0

I'm creating a database to store incoming and outgoing text messages for a program that will be responding to text messages. The app has multiple potential responses depending on the message it receives.

Providers would be services like Twilio, Nexmo, etc and the provider_numbers are the numbers assigned to each provider account, of which there can be multiples.

I used Sea Quail to whip up what I think would be a solid relational design for this that's scalable into the future, but I'm a little unsure how to track individual conversations for easy lookups down the road.

Here's what I have so far (Ignoring the simplistic types):

Database design proposal

Seaquail creation code for those that prefer to see it in text:

-- Create Table: groups
--------------------------------------------------------------------------------
CREATE TABLE groups
(
    `id` INT NOT NULL 
    ,PRIMARY KEY (id)
    ,`name` VARCHAR(250) NOT NULL 
)
ENGINE=INNODB



-- Create Table: group_permissions
--------------------------------------------------------------------------------
CREATE TABLE group_permissions
(
    `id` INT NOT NULL 
    ,PRIMARY KEY (id)
    ,`group_id` INT NOT NULL AUTO_INCREMENT
    ,`permission_id` INT NOT NULL AUTO_INCREMENT
)
ENGINE=INNODB



-- Create Table: permissions
--------------------------------------------------------------------------------
CREATE TABLE permissions
(
    `id` INT NOT NULL 
    ,PRIMARY KEY (id)
    ,`name` VARCHAR(250) NOT NULL 
)
ENGINE=INNODB



-- Create Table: urls
--------------------------------------------------------------------------------
CREATE TABLE urls
(
    `id` INT NOT NULL 
    ,PRIMARY KEY (id)
    ,`url` VARCHAR(250) NOT NULL 
    ,`date_added` DATETIME NOT NULL 
)
ENGINE=INNODB



-- Create Table: users
--------------------------------------------------------------------------------
CREATE TABLE users
(
    `id` INT NOT NULL 
    ,PRIMARY KEY (id)
    ,`user_name` VARCHAR(250) NOT NULL 
    ,PRIMARY KEY (user_name)
    ,`password` VARCHAR(250) NOT NULL 
    ,PRIMARY KEY (password)
    ,`email` VARCHAR(250) NOT NULL 
    ,PRIMARY KEY (email)
    ,`date_added` DATETIME NOT NULL 
    ,`last_access` DATETIME NOT NULL 
)
ENGINE=INNODB



-- Create Table: user_permissions
--------------------------------------------------------------------------------
CREATE TABLE user_permissions
(
    `id` INT NOT NULL 
    ,PRIMARY KEY (id)
    ,`user_id` INT NOT NULL AUTO_INCREMENT
    ,`permission_id` INT NOT NULL AUTO_INCREMENT
)
ENGINE=INNODB



-- Create Table: messages
--------------------------------------------------------------------------------
CREATE TABLE messages
(
    `id` INT NOT NULL 
    ,PRIMARY KEY (id)
    ,`from_id` INT NOT NULL AUTO_INCREMENT
    ,`to_id` INT NOT NULL AUTO_INCREMENT
    ,`body` VARCHAR(250) NOT NULL 
    ,`msg_id` VARCHAR(250) NOT NULL 
    ,`status` VARCHAR(250) NOT NULL 
    ,`date` DATETIME NOT NULL 
    ,`conversation_id` INT  NULL AUTO_INCREMENT
)
ENGINE=INNODB



-- Create Table: provider_numbers
--------------------------------------------------------------------------------
CREATE TABLE provider_numbers
(
    `id` INT NOT NULL 
    ,PRIMARY KEY (id)
    ,`provider_id` INT NOT NULL AUTO_INCREMENT
    ,`number` INT NOT NULL 
)
ENGINE=INNODB



-- Create Table: user_groups
--------------------------------------------------------------------------------
CREATE TABLE user_groups
(
    `id` INT NOT NULL 
    ,PRIMARY KEY (id)
    ,`user_id` INT NOT NULL AUTO_INCREMENT
    ,`group_id` INT NOT NULL AUTO_INCREMENT
)
ENGINE=INNODB



-- Create Table: conversations
--------------------------------------------------------------------------------
CREATE TABLE conversations
(
    `id` INT NOT NULL 
    ,PRIMARY KEY (id)
    ,`provider_id` INT NOT NULL AUTO_INCREMENT
    ,`sms_id` INT NOT NULL AUTO_INCREMENT
)
ENGINE=INNODB



-- Create Table: providers
--------------------------------------------------------------------------------
CREATE TABLE providers
(
    `id` INT NOT NULL AUTO_INCREMENT
    ,PRIMARY KEY (id)
    ,`name` VARCHAR(250) NOT NULL 
    ,`api_url` VARCHAR(250) NOT NULL 
)
ENGINE=INNODB



-- Create Table: sms_numbers
--------------------------------------------------------------------------------
CREATE TABLE sms_numbers
(
    `id` INT NOT NULL 
    ,PRIMARY KEY (id)
    ,`number` INT NOT NULL AUTO_INCREMENT
    ,`provider_id` INT  NULL AUTO_INCREMENT
)
ENGINE=INNODB



-- Create Foreign Key: provider_numbers.provider_id -> providers.id
ALTER TABLE provider_numbers ADD FOREIGN KEY (provider_id) REFERENCES providers(id);


-- Create Foreign Key: user_groups.user_id -> users.id
ALTER TABLE user_groups ADD FOREIGN KEY (user_id) REFERENCES users(id);


-- Create Foreign Key: user_groups.group_id -> groups.id
ALTER TABLE user_groups ADD FOREIGN KEY (group_id) REFERENCES groups(id);


-- Create Foreign Key: conversations.id -> messages.conversation_id
ALTER TABLE conversations ADD FOREIGN KEY (id) REFERENCES messages(conversation_id);


-- Create Foreign Key: group_permissions.permission_id -> permissions.id
ALTER TABLE group_permissions ADD FOREIGN KEY (permission_id) REFERENCES permissions(id);


-- Create Foreign Key: group_permissions.group_id -> groups.id
ALTER TABLE group_permissions ADD FOREIGN KEY (group_id) REFERENCES groups(id);


-- Create Foreign Key: user_permissions.user_id -> users.id
ALTER TABLE user_permissions ADD FOREIGN KEY (user_id) REFERENCES users(id);


-- Create Foreign Key: user_permissions.permission_id -> permissions.id
ALTER TABLE user_permissions ADD FOREIGN KEY (permission_id) REFERENCES permissions(id);


-- Create Foreign Key: conversations.provider_id -> provider_numbers.number
ALTER TABLE conversations ADD FOREIGN KEY (provider_id) REFERENCES provider_numbers(number);


-- Create Foreign Key: conversations.sms_id -> provider_numbers.number
ALTER TABLE conversations ADD FOREIGN KEY (sms_id) REFERENCES provider_numbers(number);


-- Create Foreign Key: messages.from_id -> provider_numbers.provider_id
ALTER TABLE messages ADD FOREIGN KEY (from_id) REFERENCES provider_numbers(provider_id);


-- Create Foreign Key: messages.to_id -> sms_numbers.id
ALTER TABLE messages ADD FOREIGN KEY (to_id) REFERENCES sms_numbers(id);


-- Create Foreign Key: sms_numbers.provider_id -> provider_numbers.provider_id
ALTER TABLE sms_numbers ADD FOREIGN KEY (provider_id) REFERENCES provider_numbers(provider_id);


-- Create Foreign Key: sms_numbers.id -> messages.to_id
ALTER TABLE sms_numbers ADD FOREIGN KEY (id) REFERENCES messages(to_id);

How would you design this database? Is relational the right way to go about it?

7
  • Do you need provider_numbers and sms_numbers? They appear to hold the same fields Jun 11, 2014 at 15:48
  • No, I only figured it would save long term space by reducing the amount of numbers stored in the messages table. Too much?
    – Ryan
    Jun 11, 2014 at 15:49
  • I'd just have a numbers table. And link both the from_id and to_id to it as Foreign Key relationships Jun 11, 2014 at 15:53
  • Provider_numbers is going to exist regardless, Just so the app knows which provider it's receiving a text from and how to receive the data - but it doesn't need to be tied to this if it clutters things up.
    – Ryan
    Jun 11, 2014 at 15:56
  • 2
    Some food for thought; You might want to split the messages into MOs and MTs and store them in different tables because of how they are dealt with (you won't get a DR for an incoming message, for example). I'd also make any statuses integers and have a separate table holding the status strings. This saves space when you're dealing with billions of rows.
    – Philᵀᴹ
    Jun 11, 2014 at 15:58

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Browse other questions tagged or ask your own question.