我正在尝试构建一个为多个用户存储消息的数据库。每个用户将能够发送/接收 5 种不同的消息“类型”(严格来说是一个标签,实际数据类型将是相同的)。我最初的想法是为每个用户创建多个表,代表 5 种不同的消息类型。我很快就知道这不是一个好主意。我的下一个想法是为每个消息类型创建一个带有用户列的表,但从性能角度来看,我不确定这是否是最好的方法。如果用户 1 发送 100 条消息类型 1,而用户 3 只发送 10 条,会发生什么?其余字段将是空值,我真的不确定这是否会有所不同。想法?建议和/或建议阅读?先感谢您!
3 回答
不,那(在这个问题的主题中给出的想法)将非常低效。每次创建新用户时都需要引入一个新表,而一次查询所有用户将是一场噩梦。
使用单个表来存储有关消息的信息要容易得多。此表中的每一行将对应一个 - 也是唯一的 - 消息。
此外,这个表可能应该有三个“参考”列:两个用于将特定消息链接到它的发送者和接收者,一个用于存储它的类型,只能分配一组有限的值。
例如:
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
可以是NULL
s 而不是0
,核心还是一样的。它坏了。WHERE is_msg_type_1 = 1
是的,您仍然可以使用 with子句获取单一类型的所有消息。但是,即使是像获取特定类型的消息这样简单的任务也变得不那么容易:您必须检查这 5 列中的每一列,直到找到truthy
有价值的列。
尝试计算每种类型的消息数量的人会遇到类似的困难(这对于上面给出的结构来说几乎是微不足道的:COUNT(msg_id)... GROUP BY msg_type
.
所以请不要这样做。) 除非您有非常充分的理由不这样做,否则请尝试构建您的表格,以便随着时间的推移它们会增加高度 - 而不是宽度。
其余字段将为空值
除非您是垂直设计数据库,否则不会有剩余字段。
user int
msgid int
msg text
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`)
)