[英]Database design: Multiple tables per user
I'm attempting to build a database that stores messages for multiple users. 我正在尝试建立一个数据库,用于存储多个用户的消息。 Each user will be able to send/receive 5 different message "types" (strictly a label, actual data types will be the same).
每个用户将能够发送/接收5种不同的消息“类型”(严格来说是标签,实际数据类型将是相同的)。 My initial thought was to create multiple tables for each user, representing the 5 different message types.
我最初的想法是为每个用户创建多个表,分别代表5种不同的消息类型。 I quickly learned this is not such a good idea.
我很快就知道这不是一个好主意。 My next thought was to create 1 table per message type with a users column, but I'm not sure that's the best method either from a performance perspective.
我的下一个想法是为每种消息类型的用户列创建1个表,但是从性能的角度来看,我不确定这是最好的方法。 What happens if user 1 sends 100 message type 1's, while user 3 only sends 10?
如果用户1发送100个消息类型1,而用户3仅发送10个消息,会发生什么? The remaining fields would be null values, and I'm really not sure if that makes a difference or not.
其余字段将为空值,我真的不确定这是否有所不同。 Thoughts?
思考? Suggestions and/or suggested reading?
建议和/或建议阅读? Thank you in advance!
先感谢您!
No, that (the idea given in the subject of this question) will be tremendously inefficient. 不,那(在本主题中给出的想法)将效率极低。 You'll need to introduce a new table each time a new user is created, and querying all them at once would be a nightmare.
每次创建新用户时,您都需要引入一个新表,而一次查询所有这些表将是一场噩梦。
It's far easier to be done with a single table for storing information about message. 使用单个表存储有关消息的信息要容易得多。 Each row in this table will correspond to one - and only - message.
该表中的每一行都将对应一个(唯一)消息。
Besides, this table should probably have three 'referential' columns: two for linking a specific message to its sender and receiver, and one for storing its type, that can be assigned only a limited set of values. 此外,此表可能应具有三个“引用”列:两个用于将特定消息链接到其发送者和接收者的列,以及一个用于存储其类型的列,这些列只能分配有限的一组值。
For example: 例如:
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 | %%%%%%%
...
It'll be quite easy to get both all the messages sent by someone (with WHERE sender_id = %someone_id%
clause), sent to someone ( WHERE receiver_id = %someone_id%
), of some specific type ( WHERE msg_type = %some_type%
). 获得某人发送的所有消息(带有
WHERE sender_id = %someone_id%
子句),以及发送给某人(其中WHERE receiver_id = %someone_id%
)的某种特定类型( WHERE msg_type = %some_type%
),这将是非常容易的。 But what's best of it, one can easily combine these clauses to set up more sophisticated filters. 但是最好的是,可以轻松组合这些子句以设置更复杂的过滤器。
What you initially thought of, it seems, looks like this: 您最初想到的似乎是这样的:
IS_MSG_TYPE1 | IS_MSG_TYPE2 | IS_MSG_TYPE3 | IS_MSG_TYPE4
---------------------------------------------------------
1 | 0 | 0 | 0
0 | 1 | 0 | 0
0 | 0 | 1 | 0
It can be NULL
s instead of 0
, the core is still the same. 它可以是
NULL
而不是0
,核心仍然是相同的。 And it's broken. 而且坏了。 Yes, you can still get all the messages of a single type with
WHERE is_msg_type_1 = 1
clause. 是的,您仍然可以使用
WHERE is_msg_type_1 = 1
子句来获取单一类型的所有消息。 But even such an easy task as getting a type of specific message becomes, well, not so easy: you'll have to check each of these 5 columns until you find the one that has truthy
value. 但是,即使获得诸如特定类型的消息之类的简单任务也变得不那么容易:您必须检查这5列中的每列,直到找到具有
truthy
价值的列。
The similar difficulties expect the one who tries to count the number of messages of each types (which is almost trivial with the structure given above: COUNT(msg_id)... GROUP BY msg_type
. 遇到类似困难的人可能希望尝试计算每种类型的消息数(对于上面给出的结构这几乎是微不足道的:
COUNT(msg_id)... GROUP BY msg_type
。
So please, don't do this. 所以请不要这样做。 ) Unless you have a very strong reason not to, try to structure your tables so that with the time passing by they will grow in height - not in width.
)除非您有非常强烈的理由不这样做,否则请尝试对表进行结构设计,以便随着时间的流逝它们的高度将增加,而不是宽度增加。
The remaining fields would be null values
其余字段将为空值
Except if you're designing your database vertically, there will be no remaining fields. 除非您是垂直设计数据库,否则将没有剩余字段。
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`)
)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.