0

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

在我提到personsorganisations作为两种不同的类型之前。我知道拥有andparty的超类型是一种更好的方法。现在,解决了这个问题,添加and both apply for和 for ,从而将它们连接到 supertype 。peopleorganisationadressesadditional_addressesorganisationspersonsparties

此外,我需要记录不同的人群,employees比如projectcontactssuppliercontacts。这些都是不同类型的persons, 在party. 这是加入表格persons以实现此目标的正确方法吗?suppliersand 也一样debtors,链接到organisation表格,因为supplierand debtorsare always organisations

我相信这是一种很好的设计方式,但我可能会错过主键和外键的一些内容,尤其是在查看SupplierContacts. 有一个外键partyid应该引用a person,也有一个外键supplierid,但这也引用了自己表中supplierid的某个。partyid能够从该表中查询信息不是一项非常艰巨的工作吗?这种设计是否合适?

我主要担心的是,许多表需要引用一个人或一个组织,而不是到处都有两个外键,因为我存储了一个person OR an的记录,所以始终留下一个 NULL organisation,现在我只有一个外键:partyid.

在此处输入图像描述

4

2 回答 2

1

我对您在这里提出的问题并不完全清楚。

我不知道有任何原生支持子类型化的数据库引擎——它们用于概念建模,在物理设计中,它们是用数据库引擎支持的任何东西来实现的。

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

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

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

为了帮助您评估设计,有必要解决一些显而易见的问题,例如“供应商 x 的主要联系人的电话号码是多少?”、“项目 y 有多少人工作?” 作为 SQL 查询并查看您的架构如何支持这一点。

于 2014-05-06T13:28:34.117 回答
1

答案依赖于设计主键的艺术

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

解决方案:为派对表选择一个自然键。
建议在缔约方表中有一个鉴别器列,称为party_type(枚举,值将是 person=1 和 organization=2)。
各方表的主键可以是{party_name + party_type}.
在聚合表中,像SupplierContacts在 } 上有一个检查约束{party_type = 1将解决这个问题。

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

于 2014-05-07T07:40:28.090 回答