1

我正在尝试构建一个为多个用户存储消息的数据库。每个用户将能够发送/接收 5 种不同的消息“类型”(严格来说是一个标签,实际数据类型将是相同的)。我最初的想法是为每个用户创建多个表,代表 5 种不同的消息类型。我很快就知道这不是一个好主意。我的下一个想法是为每个消息类型创建一个带有用户列的表,但从性能角度来看,我不确定这是否是最好的方法。如果用户 1 发送 100 条消息类型 1,而用户 3 只发送 10 条,会发生什么?其余字段将是空值,我真的不确定这是否会有所不同。想法?建议和/或建议阅读?先感谢您!

4

3 回答 3

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     | %%%%%%%

...   

获取某人发送的所有消息(withWHERE 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

可以是NULLs 而不是0,核心还是一样的。它坏了。WHERE is_msg_type_1 = 1是的,您仍然可以使用 with子句获取单一类型的所有消息。但是,即使是像获取特定类型的消息这样简单的任务也变得不那么容易:您必须检查这 5 列中的每一列,直到找到truthy有价值的列。

尝试计算每种类型的消息数量的人会遇到类似的困难(这对于上面给出的结构来说几乎是微不足道的:COUNT(msg_id)... GROUP BY msg_type.

所以请不要这样做。) 除非您有非常充分的理由不这样做,否则请尝试构建您的表格,以便随着时间的推移它们会增加高度 - 而不是宽度。

于 2013-06-03T22:02:19.750 回答
0

其余字段将为空值

除非您是垂直设计数据库,否则不会有剩余字段。

user   int
msgid  int
msg    text
于 2013-06-03T22:01:27.970 回答
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`)
 )
于 2013-06-03T22:01:34.553 回答