我最近在关系数据库设计中发现了子类型/超类型方法,因此这个问题:这是一个与子类型/超类型设计方法混合的正确设计吗?
在我将persons
和organisations
称为两种不同类型之前。我知道让party
成为people
和organisation
的超类型是一种更好的方法。现在,解决了这个问题,添加adresses
和additional_addresses
两者都申请organisations
以及persons
,从而将它们连接到超类型parties
。
此外,我需要记录不同的人群,例如employees
,projectcontacts
和suppliercontacts
。这些是persons
内所有不同类型的party
。persons
。这是以suppliers
加入表格以实现此目标的正确方法吗?与debtors
表关联的organisation
和supplier
也是如此,因为debtors
和organisations
始终是SupplierContacts
。
我相信这是一种很好的设计方式,但我可能会错过主键和外键,特别是在查看partyid
时。有person
的外键应该引用supplierid
,还有supplierid
的外键,但此partyid
也引用某个person
在自己的表中。如果能够从这个表中查询信息并且这个设计是否合适,这难道不是一件非常艰苦的工作吗?
我主要担心的是,许多表需要引用一个人ÓR一个组织,而不是在任何地方都有两个外键,因为我存储了一个记录要么organisation
或和partyid
,现在我只有一个外键:{{1}}。
答案 0 :(得分:1)
我不清楚你在这里问的问题。
我不知道任何本地支持子类型的数据库引擎 - 它们用于概念建模,而在物理设计中它们是用数据库引擎支持的任何方式实现的。
将其建模为物理数据模型可能更有用 - 因为您对主键和外键的决定几乎肯定会根据您物理表示子类型的方式而改变。
有几种方法可以将“子类型”的逻辑概念转换为物理数据模型 - 最常见的是:
为了帮助您评估设计,值得解决一些明显的问题,例如“供应商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
}上的检查约束将解决问题。
请注意,该解决方案旨在解决数据库设计级别的问题,作为替代方案,您可以在应用程序级别进行额外的工作来归档数据完整性(建议开发人员使用的建议较少!)