2013-06-03 4 views
1

Я пытаюсь создать базу данных, в которой хранятся сообщения для нескольких пользователей. Каждый пользователь сможет отправлять/получать 5 разных типов сообщений (строго обозначение, фактические типы данных будут одинаковыми). Моя первоначальная мысль заключалась в создании нескольких таблиц для каждого пользователя, представляющих 5 разных типов сообщений. Я быстро понял, что это не такая хорошая идея. Моя следующая мысль заключалась в том, чтобы создать 1 таблицу для типа сообщения с столбцом пользователей, но я не уверен, что это лучший метод либо с точки зрения производительности. Что произойдет, если пользователь 1 отправит 100 сообщений типа 1, а пользователь 3 отправит 10? Остальные поля будут равны нулю, и я действительно не уверен, что это имеет значение или нет. Мысли? Предложения и/или предлагаемые чтения? Заранее спасибо!Дизайн базы данных: несколько таблиц на пользователя

+0

http://pragprog.com/book/bksqla/sql-antipatterns – dm03514

ответ

1

Нет, что (идея дана в теме этого вопроса) будет чрезвычайно неэффективно. Вам нужно будет вводить новую таблицу каждый раз, когда будет создан новый пользователь, и одновременное обращение к ним будет кошмаром.

Это очень легко сделать с помощью таблица для хранения информации о сообщении. Каждая строка в этой таблице будет соответствовать одно - и единственному сообщению.

Кроме того, эта таблица, вероятно, должна иметь три «ссылочных» столбца: два для привязки определенного сообщения к его отправителю и получателю и один для хранения его типа, которому может быть назначен только ограниченный набор значений.

Например:

MSG_ID | SENDER_ID | RECEIVER_ID | MSG_TYPE | MSG_TEXT 
------------------------------------------------------ 
    1 |  1  |  2  | 1  | ....... 
    2 |  2  |  1  | 1  | ####### 
    3 |  1  |  3  | 2  | $$$$$$$ 
    4 |  3  |  1  | 2  | %%%%%%% 

... 

Это будет довольно легко получить как все сообщения, отправленные по кем-то (с WHERE sender_id = %someone_id% пункта), послал в кого-то (WHERE receiver_id = %someone_id%) некоторого конкретного типа (WHERE msg_type = %some_type%). Но что лучше всего, можно легко объединить эти предложения, чтобы настроить более сложные фильтры.


То, что вы первоначально думали, кажется, выглядит следующим образом:

IS_MSG_TYPE1 | IS_MSG_TYPE2 | IS_MSG_TYPE3 | IS_MSG_TYPE4 
--------------------------------------------------------- 
    1  |  0  |  0  |  0 
    0  |  1  |  0  |  0 
    0  |  0  |  1  |  0 

Это может быть NULL s вместо 0, ядро ​​остается прежним. И это сломано. Да, вы все равно можете получить все сообщения одного типа с предложением WHERE is_msg_type_1 = 1. Но даже такая простая задача, как получение типа конкретного сообщения, становится, ну, не так просто: вам нужно будет проверить каждые из этих 5 столбцов, пока не найдете значение truthy.

Аналогичные трудности ожидают, что тот, кто пытается подсчитать количество сообщений каждого типа (что почти тривиальным со структурой приведенной выше:.. COUNT(msg_id)... GROUP BY msg_type

Так что, пожалуйста, не делайте этого) Если не вам имеют очень сильную причину, чтобы не пытаться структурировать ваши таблицы, чтобы при прохождении времени они будут расти в высоту - не в ширину.

+1

Отлично. Теперь я лучше понимаю не только то, что, но почему. Спасибо! – user2442072

0

Остальные поля будет нулевые значения

За исключением, если вы разрабатываете базы данных по вертикали, не будет никаких остальных полей.

user int 
msgid int 
msg text 
0
create table `tv_ge_main`.`Users`( 
    `USER_ID` bigint NOT NULL AUTO_INCREMENT , 
    `USER_NAME` varchar(128), 
    PRIMARY KEY (`ID`) 
) 

create table `tv_ge_main`.`Message_Types`( 
    `MESSAGE_TYPE_ID` bigint NOT NULL AUTO_INCREMENT , 
    `MESSAGE_TYPE` varchar(128), 
    PRIMARY KEY (`ID`) 
) 

create table `tv_ge_main`.`Messages`( 
    `MESSAGE_ID` bigint NOT NULL AUTO_INCREMENT , 
    `USER_ID` bigint , 
    `MESSAGE_TYPE_ID` bigint , 
    `MESSAGE_TEXT` varchar(255) , 
    PRIMARY KEY (`ID`) 
) 
Смежные вопросы