使用两个表而不是具有两个不同值的列的优点

时间:2010-04-05 14:08:11

标签: sql mysql database

我正在创建一个数据库结构。我必须存储输入和传出的消息,我想知道这是最好的方法。

2个分隔的表格或带有ENUM('in','out')列的相同表格?

有什么建议吗?

感谢。

9 个答案:

答案 0 :(得分:1)

如果您要向其他用户发送消息,我的工作就是创建一个sent_message表和一个message_to_users表。

可能是你不想在任何时候正确删除邮件,所以我只是为此添加标记。

sent_message
------------
sent_message_id
from_id int
subject varchar(128)
body text
status char(1)
sent_datetime datetime


message_to_user
-------
message_to_user_id int
sent_message_id int
to_id int
read_datetime datetime
status char(1)

sent_message的状态为s(ent)d(eleted)message_to_user的状态为a(rrived)r(ead)d(eleted)

此方法可以轻松“全部回复”功能,并在向多个用户发送邮件时节省空间。

答案 1 :(得分:1)

决定你的结构的一件事是传入和传出的消息是否需要存储与它们有关的不同数据。如果他们这样做,您可能需要单独的表。

您通常也会单独请求它们,或者您是否总是需要来自同一查询的两种类型。

在做出决定时,您需要坐下来决定您需要存储的关于每种类型的数据以及您将如何查询数据。这将最终决定你的结构。在一个典型的消息中,你可能会有许多记录,并且考虑到这一点而设计将是有益的。我甚至可以用数百万的测试记录测试两种方式,看看我的基本设计选择有什么影响。我知道人们谈论的不是过早优化,但是一旦你有数百万的实际记录,数据库的基本结构很难改变,现在值得花时间用测试记录设置它,看看哪些可行的方法可行最好使用您需要执行的查询类型(不要忘记使用索引进行测试,因为它们会产生巨大的性能差异)。这不是过早的优化,这是在设计糟糕的设计之前测试可能的负载,而在用户尖叫性能时无法重构。

答案 2 :(得分:0)

由于消息是完全相同的对象,因此您应该将box_id作为对boxes表的引用。这将有助于您不仅在收件箱/发件箱中存储邮件,还可以在垃圾邮件,草稿和您可能想到的其他“文件夹”中存储邮件。

否则,您可以拥有多对多关系并在多个框中存储相同的消息(就像gmail标签一样)。

答案 3 :(得分:0)

如果90%的列相同,请使用一个表。

伪SQL:

TABLE messages
  id INT
  subject STRING
  direction ENUM
INDEX direction

答案 4 :(得分:0)

如果它们由不同的进程访问/管理,我建议使用单独的表。如果同一进程管理两种类型的消息,则使用相同的表。

答案 5 :(得分:0)

一张表是最佳解决方案。

通常任何给定的数据实体都应存储在表中。在这种情况下,消息是您的数据实体。

作为一个侧面点,我建议不要在表格中使用枚举 - 在这种情况下,消息将属于传入或传出 - 因此消息 direction 应该存储在一个单独的表中,约束以确保它们有效。

此外方向可能是一个误区,你可能希望打电话给&输出文件夹或位置或框(如@Eimantas指出的那样)。

答案 6 :(得分:0)

如果它是同一站点/应用程序的用户之间的消息的消息传递系统,则只需使用包含senderIdrecipientId的1个表。收件箱是用户ID与recipientId匹配的邮件,用户ID与senderId匹配的发件箱。

请注意,这对于同时向多个用户发送的邮件不能很好地扩展。在这种情况下,您需要一个单独的表格,如Matt Allen所示。

答案 7 :(得分:0)

我认为这取决于您是否希望一次看到所有消息。如果您的查询将返回所有传入的 OR 所有传出,但 NEVER 所有这些一起;然后你会想要两张桌子。特别是如果最终每个都有很多行,那么两个表将是一个更快的解决方案。

答案 8 :(得分:0)

如果消息实际上是同一个实体,仅在单个属性值上有所不同,请使用单个表。如果您希望在某些例程中有可用的子集,请创建单表视图以仅获取入站或出站消息。

如果消息是不同的实体,特别是如果它们针对不同的用户ID进行验证,则需要两个表。