我正在尝试为收件箱应用构建一个表,该应用将其邮件存储在inbox
表中。
表的结构如下:
inbox_id|sender_id|receiver_id|subject|message
列sender_id
和receiver_id
是 FOREIGN KEYS ,可以引用多个表格。
目前,数据库中有3种类型的用户,他们都可以相互发送消息。类型为UserType1
的用户可以向UserType2
发送消息,反之亦然,或UserType1
可以向UserType1
发送消息。所以接收者和发送者可以参考这3个表中的一个。
我对此问题的解决方案是构建一个inbox_user
表,其中包含每个用户类型的列,并让sender_id
和inbox_user
引用它。
我主要担心的是解决方案的灵活性有限以及浪费资源的使用。我会在任何时候每行总共有2个空列。如果我引入更多用户类型,情况会变得更糟。
这会被视为不良做法吗?什么是更灵活和智能的设计?
答案 0 :(得分:2)
根据您的描述,听起来应该将最佳做法应用于您的用户表而不是此收件箱表。当然,我不知道你的约束,但是如果你有两种或三种类型的用户,每种类型的用户都在自己的表中,这是一个糟糕的设计(同样,不知道你的约束)。首选项是将所有用户存储在一个表中,并使用列来指示其类型。然后,对收件箱表的引用变得简单,发送方和接收方FK都指向同一个用户表。
否则,您将最终使用多列来引用您所说的每个表(UserTypeASenderID,UserTypeBSenderID,UserTypeCSenderID等)。我的偏好是使用空FK列并获得参照完整性,而不是实现其他解决方案并失去约束。
答案 1 :(得分:1)
3种不同类型的用户是经典的类型/子类型情况。 (或者,如果您愿意,可以使用类/子类)。有几种方法可以设计类/子类的情况。对我来说好看的两个是“类表继承”和“单表继承”,正如Martin fowler所解释的那样。你可以在网上找到一个概要。您还可以在此处访问这些名称的标签,阅读所提供的信息,并查看标记的问题。
单表继承对于某些时候不适用的字段会遇到很多NULL,正如您在Q中指出的那样。根据您的情况,这对您来说可能是也可能不是问题。
类表继承涉及在子类(子类型)中创建新条目时的一点编程。它还涉及更多的加入,但加入并不是非常昂贵。类表继承经常与称为共享主键的技术相结合。在这种技术中,子类表最终得到的主键是超类表中主键的副本。它也是超类表的外键。这使得连接子类数据和超类数据变得简单,容易和快速。
共享主键可以解决您在Q中所述的窘境,即如何使用一个外键引用多个表。某些其他表中对超类表的外键引用也将是对至少一个子类表的引用。这看起来很神奇。试一试,看看你是否喜欢它。