数据库设计包括人员和组织

时间:2014-05-06 12:50:27

标签: database-design relational-database subtyping

我最近在关系数据库设计中发现了子类型/超类型方法,因此这个问题:这是一个与子类型/超类型设计方法混合的正确设计吗?

在我将personsorganisations称为两种不同类型之前。我知道让party成为peopleorganisation的超类型是一种更好的方法。现在,解决了这个问题,添加adressesadditional_addresses两者都申请organisations以及persons,从而将它们连接到超类型parties

此外,我需要记录不同的人群,例如employeesprojectcontactssuppliercontacts。这些是persons内所有不同类型的partypersons。这是以suppliers加入表格以实现此目标的正确方法吗?与debtors表关联的organisationsupplier也是如此,因为debtorsorganisations始终是SupplierContacts

我相信这是一种很好的设计方式,但我可能会错过主键和外键,特别是在查看partyid时。有person的外键应该引用supplierid,还有supplierid的外键,但此partyid也引用某个person在自己的表中。如果能够从这个表中查询信息并且这个设计是否合适,这难道不是一件非常艰苦的工作吗?

我主要担心的是,许多表需要引用一个人ÓR一个组织,而不是在任何地方都有两个外键,因为我存储了一个记录要么organisation partyid,现在我只有一个外键:{{1}}。

enter image description here

2 个答案:

答案 0 :(得分:1)

我不清楚你在这里问的问题。

我不知道任何本地支持子类型的数据库引擎 - 它们用于概念建模,而在物理设计中它们是用数据库引擎支持的任何方式实现的。

将其建模为物理数据模型可能更有用 - 因为您对主键和外键的决定几乎肯定会根据您物理表示子类型的方式而改变。

有几种方法可以将“子类型”的逻辑概念转换为物理数据模型 - 最常见的是:

    每个子类型的
  • 表。这意味着您的外键可能需要链接到多个表(例如“人”或“组织”),但您的查询/联接很简单。
  • 具有共同属性的超类型表,用于子类型数据的单独表(例如“派对”,“人员”和“组织”) - 在这种情况下,您的外键转到“派对”,但要获取子类型数据,您有包括连接到子类型表。这使您的SQL变得复杂。
  • 具有大量可空列的公共表(例如,“人员和组织的所有列”的“派对”)。这使外键变得简单 - 但同样,您的数据访问逻辑变得混乱。

为了帮助您评估设计,值得解决一些明显的问题,例如“供应商x主要联系人的电话号码是什么?”,“有多少人参与项目y?”作为SQL查询并查看您的架构如何支持它。

答案 1 :(得分:1)

答案取决于art of designing primary keys

您已使用surrogate identifier作为parties表的主键(开发人员常见的陷阱之一),同时在parties表中无法检测到行实际上是没有加入个人或组织表的个人或组织。
因此,当你在其他表中使用parties的PK作为FK时,如果该方是所需的那个,则无法检测到,您正在失去业务逻辑,这是使用代理键的副作用。

解决方案:为派对表选择一个自然键 建议在派对表中使用名为party_type的标识符列(枚举,值为person = 1,organization = 2)。
聚会表的主键可以是{party_name + party_type} 在诸如SupplierContacts之类的聚合表中,{party_type = 1}上的检查约束将解决问题。

请注意,该解决方案旨在解决数据库设计级别的问题,作为替代方案,您可以在应用程序级别进行额外的工作来归档数据完整性(建议开发人员使用的建议较少!)