简体   繁体   English

数据库设计:每个用户多个表

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM