在SQL中实现一对零或一个关系


11

让我们说,我正在为存在一对零或一个(1-0..1)关系的场景设计数据库。例如:

  • 有一组用户有些 用户也可能是客户

因此,我创建了两个对应的表,userscustomers,但是……

…在给定的SQL平台上表示和实现这种情况的最佳方法是什么?我考虑了两种可能的解决方案:

  1. users表中,添加customer可能是FOREIGN KEY引用customersNULL标记的列。

  2. customers表格中,包括指向表格的user列(设置了UNIQUE约束)users

我已经在一些论坛中提出过类似的问题,但是答案基本上是“无论您需要什么”,“无论您认为方便什么”。我不喜欢这种答案。我想要一个严肃的DB理论,一个有充分根据的答案。我在哪里可以阅读有关1-0..1关系的信息?

Answers:


10

我想要一个认真的数据库理论

现代关系理论拒绝空值,这似乎会立即使您的选择1失效。但是,可以通过用默认值替换默认空值来消除这个稻草人,例如,专门为显式建模“不是客户”而创建的“虚拟”客户。对应。

我认为您的选项2从理论上讲是最合理的,因为与修改后的选项1不同,该关系可以是第六范式(6NF),是投影联接范式和可达到的最高范式。

我还听说过一种设计经验法则,该法则规定一个关系应该对一个实体或实体之间的关系进行建模,但绝不能对两者进行建模,这在我看来是明智的。同样,这将有利于选项2。但是,我在很多年前就听说过这一经验法则,不要记得在哪里,也不能提供任何严肃的理论基础(上述6NF除外)。


2

您已获得部分正确答案。真正的答案来自您的数据模型以及如何对其进行规范化。关键是如何建立关系:

  • customers表由该表考虑的多个字段组成,这些字段users属于客户概念,并且除非用户也是客户(用户的子类型),否则为null。在这种情况下,customers表将从表继承主键users。(可能有可能重叠或不重叠的多个子类型。)

  • customers表包含与客户概念有关的许多字段,但不一定与用户概念有关。客户是一个强大的表,并不依赖于用户概念。(删除users表不会显着影响客户表的设计。)在这种情况下,客户表具有其自己的主键。

您所拥有的是一个可选的一对多关系的特例,其中上限为1。请双方考虑:一个用户可能有多个客户,还是一个客户可能有多个用户?如果是这样,您将需要重塑数据。

user-id外键添加到customers表中可能被认为是更好的选择,因为可以正确地映射一对多(上限1)关系并避免可为空的字段。为了强制执行上限,外键索引必须唯一。如果主键是,这将自动发生user-id

将a customer-id作为可选外键添加到users表中,将强制关系中的上限为1,但会逆转依赖关系。


1

您是否考虑过一种更复杂但更灵活的方法。父表是“人”(或“实体”,具体取决于您想要的复杂程度)。然后,客户表和用户表均具有与人员表的FK。人员表包含个人详细信息,而客户表和用户表仅包含与用户或客户关联的属性。通常,地址(电子邮件和蜗牛邮件),电话号码等也都在带有映射表的单独表中表示,以允许多对多情况。这是一个相对常见的模型,可以在许多参考站点上找到。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.