具有可以引用不同表的外键的表

时间:2015-06-05 16:38:17

标签: sql database database-design

我正在尝试为收件箱应用构建一个表,该应用将其邮件存储在inbox表中。

表的结构如下:

inbox_id|sender_id|receiver_id|subject|message

sender_idreceiver_id FOREIGN KEYS ,可以引用多个表格。

目前,数据库中有3种类型的用户,他们都可以相互发送消息。类型为UserType1的用户可以向UserType2发送消息,反之亦然,或UserType1可以向UserType1发送消息。所以接收者和发送者可以参考这3个表中的一个。

我对此问题的解决方案是构建一个inbox_user表,其中包含每个用户类型的列,并让sender_idinbox_user引用它。

我主要担心的是解决方案的灵活性有限以及浪费资源的使用。我会在任何时候每行总共有2个空列。如果我引入更多用户类型,情况会变得更糟。

这会被视为不良做法吗?什么是更灵活和智能的设计?

2 个答案:

答案 0 :(得分:2)

根据您的描述,听起来应该将最佳做法应用于您的用户表而不是此收件箱表。当然,我不知道你的约束,但是如果你有两种或三种类型的用户,每种类型的用户都在自己的表中,这是一个糟糕的设计(同样,不知道你的约束)。首选项是将所有用户存储在一个表中,并使用列来指示其类型。然后,对收件箱表的引用变得简单,发送方和接收方FK都指向同一个用户表。

否则,您将最终使用多列来引用您所说的每个表(UserTypeASenderID,UserTypeBSenderID,UserTypeCSenderID等)。我的偏好是使用空FK列并获得参照完整性,而不是实现其他解决方案并失去约束。

答案 1 :(得分:1)

3种不同类型的用户是经典的类型/子类型情况。 (或者,如果您愿意,可以使用类/子类)。有几种方法可以设计类/子类的情况。对我来说好看的两个是“类表继承”和“单表继承”,正如Martin fowler所解释的那样。你可以在网上找到一个概要。您还可以在此处访问这些名称的标签,阅读所提供的信息,并查看标记的问题。

单表继承对于某些时候不适用的字段会遇到很多NULL,正如您在Q中指出的那样。根据您的情况,这对您来说可能是也可能不是问题。

类表继承涉及在子类(子类型)中创建新条目时的一点编程。它还涉及更多的加入,但加入并不是非常昂贵。类表继承经常与称为共享主键的技术相结合。在这种技术中,子类表最终得到的主键是超类表中主键的副本。它也是超类表的外键。这使得连接子类数据和超类数据变得简单,容易和快速。

共享主键可以解决您在Q中所述的窘境,即如何使用一个外键引用多个表。某些其他表中对超类表的外键引用也将是对至少一个子类表的引用。这看起来很神奇。试一试,看看你是否喜欢它。