是否有可能实现真正的一对一关系?

10 浏览
0 Comments

是否有可能实现真正的一对一关系?

考虑以下模型,其中Customer应该有一个且只有一个Address,而Address应该属于一个且只属于一个Customer

enter image description here

为了实现这个模型,正如数据库领域中的几乎所有人所说,Shared PK是解决方案:

enter image description here

但是我认为这是一个伪造的一对一关系。因为从数据库关系的角度来看,没有任何东西可以阻止删除Address表中的任何行。所以实际上,它是1..[0..1]而不是1..1

我是正确的吗?是否有其他方法可以实现真正的1..1关系?

更新:

为什么级联删除不是解决方案:

如果我们将级联删除视为解决方案,我们应该将其放在其中一个表上。假设从Address表中删除一行,这会导致将在Customer表中对应的行删除。这是可以的,但只解决了一半的问题。如果从Customer中删除一行,相应的Address行也应该被删除。这是问题的另一半,显然会导致循环。

0
0 Comments

是的,你展示的“共享PK”习语适用于1对0或1。

拥有真正的1对1对应关系的直接方法是在一个表中使用Customer和Address作为CKs(候选键)。 (通过UNIQUE NOT NULL和/或PRIMARY KEY。)您可以将单独的表作为视图提供。不幸的是,典型的数据库管理系统对视图的操作有一些限制,特别是对于更新操作。

拥有单独的CUSTOMER和ADDRESS表以及第三个表/关联/关系,该表具有Customer和Address列作为CKs,并且在CUSTOMER和ADDRESS之间以及Address和ADDRESS之间具有FKs(或等效约束)时,可以实现真正的1对1对应关系。不幸的是,大多数数据库管理系统不允许在FKs中声明循环,而且您无法在没有触发器/复杂性的情况下实施约束。 (最终,如果要在典型的SQL数据库中具有适当的完整性,您需要使用触发器和复杂语法。)

基于实体的设计方法不幸地人为地将实体,关联和属性区分开来。这是一个例子,如果您认为最简单的设计只是具有PKs的一个表,那么您不希望总是必须为每个实体拥有不同的表。或者,如果您认为最简单的设计是具有具有PKs和FKs(或1对1的其他约束)的三个表(甚至两个表),那么不幸的是,典型的数据库管理系统只是不以声明性/人体工程学的方式支持该特定的设计情况。

(直接的关系设计是将值(有时用作id)与应用程序中的事物1对1,然后根据需要拥有任何相关的应用程序关系/关联/关系和相应/表示表/关系来描述您的应用程序情况。)

你发现了一个很好的发现:似乎在传统RDBMs中无法实现这一点。

0
0 Comments

在实际的数据库关系中,往往存在客户有多个地址或多个组织位于同一地址的情况。因此,实现一个真正的一对一关系是不可能的。这是一个例子而已。这是一个评论,不是对问题的回答。

0
0 Comments

实现真正的一对一关系是否可能?

在这个讨论中,某些情况下了使用`DELETE CASCADE`来实现一对一关系的删除操作。同时,还指出了插入操作的问题,即必须先插入`Customer`,然后再插入`Address`。因此,如果真的想要实现一对一关系,最好的方法是创建一个单一的表,将`Customer`和`Address`的字段合并在一起。

他还强调了实体与行的区别,实体由值表示,而行则表示关系。他认为将实体与行混淆在一起是误导性的,特别是当它们不能有效地进行一对一映射时。

在ER方法中,实体实例或关系/关联实例由行表示,实体类/集或关系/关联类/集由表表示。他还提到了实体和关系这些术语在实例和/或类/集之间的混用。他认为,由于每个表达值的超键都与一个应用实例是一对一的关系,所以可以将超键(包括所有完整的行)和/或值(一列超键的值)视为实例。他承认这显示了ER的混乱。

最后,他感谢他重新思考这个问题,并接受了使用`table`而不是`entity`这个建议,以避免与ER术语混淆。

通过使用单一的表来合并`Customer`和`Address`的字段,可以实现真正的一对一关系。此外,还需要注意实体与行的区别,并避免混淆术语的使用。

0