如何使用来自其他几个表的外键对表进行建模

时间:2009-03-16 21:04:48

标签: database-design data-modeling

我正在尝试创建一个包含两个主要实体的联系人应用程序 - 人员和公司。一个人可以拥有许多电子邮件,号码和地址。公司还可以拥有许多电子邮件,号码和地址。我正在尝试为这种情况确定合适的设计。

选项#1 - 多个外键
电子邮件,号码和地址将有两列名为person_id和company_id。根据数据属于哪个实体,一个将为null,另一个将包含一个链接回父级的id。

选项#2 - 每个实体每种类型一个表
我复制每个表,因此会有一个company_addresses表和一个person_addresses表。我会有两倍的表,但这是现在最有意义的解决方案。

选项#3 - 一个链接表
我创建了一个表 - “链接”。该表将包含四列:source_id,source_entity,dest_id,dest_entity。因此,如果公司获得一个新号码,您将拥有如下行:1,number,2,company。

选项#4 - 多个链接表
我为每种类型的链接创建一个表(company_address,person_address,company_email,person_email等)

您会选择哪个选项?

2 个答案:

答案 0 :(得分:8)

你已经谈到了一些我认为你会避免的做法。我在Database Development Mistakes Made by AppDevelopers中写了更多关于此的内容(例如,独占弧)。

至于你的问题,我实际上不会选择这些选项。你遇到的是generic Party model。基本上,您有一个具有子类型的Party实体,例如Person和Organization。联系人具有Party ID作为外键。使用共同的超类/超级性比这更深刻,因为你会发现你也将它用于许多其他事情(例如整个角色概念)。

很多这些数据库设计建模问题都有成熟的解决方案,但它们往往不是程序员所教过的东西。我强烈建议您阅读本书The Data Model Resource Book, Vol. 1: A Library of Universal Data Models for All Enterprises,其中详细介绍了如何为人员和组织建模以及许多其他典型问题。

这里要记住的关键点是你以前做过的事情已经完成了。

答案 1 :(得分:0)

选项#2或我会这样做:

你可以创建一个定义Id和Entity类型的EntityTable,然后你可以将你的地址,电子邮件表链接到那个。

然后你创建Person&公司表引用回Entity。其他词是你的子类实体。

选项#1 - 我过去曾经使用过它,随着事情变得复杂和发展,它会变得很难受管理。

选项#3 - 您不能使用参考完整性,并且从保存一些击键来执行选项#2所获得的成本将不值得清理坏数据或处理额外的复杂性。