例如。在我的系统中,我有一个对象被其他几种类型的对象以1对1的关系使用。让我们调用使用Address的对象,以及使用它的两个对象Company和Person。每个公司和个人都有一个地址,每个地址在系统中都是唯一的,因此每个地址都由个人或公司引用。1对1与超过2个表的关系
我有两个问题。
问题1)这个关系叫什么?我在网上找到的1对1关系的所有例子都只在两个表之间,而这是三对一的关系。
问题2)什么样的表结构最好地捕获了这种关系?我发现至少有两种看起来有缺陷的潜在设计。
设计a)使用两个可为空的外键,约束条件是至少有一个不为空。就像一个复合外键。
- Company -
pkCompanyId
...
- Person -
pkPersonId
...
- Address -
pkAddressId
fkPersonId <nullable>
fkCompanyId <nullable>
...
设计b)每个公司和个人识别它使用的地址。
- Company -
pkCompanyId
fkAddressId
...
- Person -
pkPersonId
fkAddressId
...
- Address -
pkAddressId
...
设计一)似乎是一个更传统的使用外键我在正在使用的对象标识引用它的对象,但我还没有看到任何的例子是与做多这样的外键。
设计b)看起来像是正常建模1对1关系的反过程。
在我看来,在常规的1对1关系(下面)中,fkPersonId是一个不可为空的唯一外键有助于在实际表结构中强制执行1对1关系(它保证每个地址被一个没有引用其他地址的Person引用)。我的设计都没有达到这个目标。在设计中a)必须确保fkCompanyId或fkPersonId中的一个且仅有一个为空以确保一致性。在设计b)中,必须确保公司或人员中的任何fkAddressId都不在任何表中重复。这使我怀疑我在这里犯了一个错误。
- Person -
pkPersonId
...
- Address -
pkAddressId
fkPersonId
...
没有太多的精力,我可以看到其他的设计,例如使用guid作为pkCompanyId和pkPersonId以及Address中的单个外键,但我再次在我所研究的任何在线资源中看不到任何此策略的示例。
我已经明显超出了我对数据库设计的有限知识,可以使用一些指导。处理这个问题的最好方法是什么?
更新响应沃尔特米蒂的回答
我认为单个表继承不适合我的情况。尽管我在这里使用了公司和人员的例子,但在我的真实应用程序中,这些都是大型复杂表格,除了它们都拥有地址之外,没有任何共同之处。他们的数据不仅非常不同,而且代表完全不同的概念。
我的每个具有相同类型实例的实际实体都是Organization,Project和ProjectElement。组织代表许可使用系统的公司。项目表示由特定组织的用户创建的项目,ProjectElement表示一段项目数据。
他们都有一个实例的东西是一个设置对象。默认设置在组织级别提供。创建项目时,会获取组织设置的副本。项目中的组件获得项目设置的副本。
此体系结构支持多种用例,包括何时修改组织的设置时,这些更改仅影响新项目,而不影响已创建的项目。 ProjectElement继承了Project的设置,但可以选择覆盖特定的Project设置。
更进一步的复杂性包括组织,项目和ProjectElement不仅仅具有一个共享类型的实例,而是几个。有几种不同类型的设置对象,每个都有自己的表格。如果不能使用共享类型的实例的ID作为引用对象的主键,则这使得它变得尴尬。我也在使用目前不支持视图的实体框架核心ORM。
你的答案非常有用,给了我很多思考,但到目前为止,似乎我的设计2最好的实现了我的要求。设计2有什么内在不合理的地方让它不适合?
当然。我的建议是基于你最初提出的简单案例。 –