了解一对一关系

Man*_*ngo 5 foreign-key database-design

据我了解,两个表之间的一对一关系意味着一个表中的每一行与另一个表中的一行完全匹配。

\n\n

其有用的原因有很多,例如虚拟地向表中添加列而不实际更改它。

\n\n

上面的描述表明这种关系是对称的:任一表中的行与另一个表中的行匹配。

\n\n

如果主键也是另一个主键的外键,那么这很容易完成:

\n\n
CREATE TABLE stuff (\n    id INT PRIMARY KEY REFERENCES more(id),\n    data VARCHAR(255)\n);\n\nCREATE TABLE more (\n    id INT PRIMARY KEY REFERENCES stuff(id),\n    data VARCHAR(255)\n);\n
Run Code Online (Sandbox Code Playgroud)\n\n

我在这里可以看到一个逻辑问题:当另一个表中没有\xe2\x80\x99t 行匹配时,如何向一个表添加一行?

\n\n

更轻松的版本是一对零或一的关系,我更喜欢将其称为一对可能的关系。如果一个表引用另一个表,则很容易实现这一点,但反之则不然:

\n\n
CREATE TABLE stuff (\n    id INT PRIMARY KEY, --  does not reference the more table\n    data VARCHAR(255)\n);\n
Run Code Online (Sandbox Code Playgroud)\n\n

关系仍然是主键之间的关系,但只有一个方向。这在逻辑上更容易,并且可以用于实现可选列,而无需陷入有关NULLs 的使用的争论。

\n\n

问题是:

\n\n
    \n
  • 一对一关系真的是指第一种情况,即两个表在两个方向上匹配吗?
  • \n
  • 在这种情况下,您将如何添加一行?
  • \n
\n

EzL*_*zLo 3

11(或可能为 0)关系不交叉引用,它们作为您的第二个示例实现,两个实体之一与另一个实体相关(而不是相反)。

\n\n

对于其中一种关系来说,两种方式的链接都是多余的,因为您只需要 1 来了解链接的性质。此外,在不支持可延迟外键或一条语句中多次插入的数据库中(感谢 @ypercube\xe1\xb5\x80\xe1\xb4\xb9 的注释),您将无法插入行无需先禁用外键。

\n\n

stuff如果依赖moremore依赖的存在stuff,那就存在先有鸡还是先有蛋的问题。哪一个真正代表您要存储的实体?您真的需要为他们准备两张不同的桌子吗?您的实体仅在创建两条记录时才存在吗?

\n\n

设计时,一对一的关系总是令人惊讶。也许如果您有一个特定的案例场景可以分享,我们可以深入研究更多细节。我实现了一对一关系的唯一少数例外是,我们继承了以前的数据库,其中的表有 100 多个列,并且我们出于性能和存储问题将它们分开,但不是出于纯粹的设计原因。

\n

  • *“如果不首先禁用外键,您将无法插入任何行”*。请更正这一点。是的,您可以在所有已实现延迟约束的数据库中执行此操作。同样在允许在一条语句中插入多个表的数据库中。 (2认同)