在具有一对一关系的表之间确定FK

时间:2013-12-01 19:25:44

标签: database database-design foreign-keys primary-key one-to-one

我是数据库设计的新手,对这个noob问题感到抱歉。我有2个简单的表,彼此之间有1比1的关系。哪个表的PK在其他表中应该是FK?我怎么决定呢?

2 个答案:

答案 0 :(得分:2)

为了做出决定,要问的问题是关系是否为真1 :: 1

如果关系是1 :: 0..1(即B中的每一行都有一个相关的行,但A中的行可能不会(全部)在B中有一行),那么应该有一个{{表FOREIGN KEY中{1}}表示{}}}。这是最常见的情况,几乎在所有DBMS中都很容易实现。

如果关系是真B (pk)(即表A中的每一行都有一个表B中的相关行 - 反之亦然),那么应该有两个外键,一个从B到A,另一个从A到B.这也很容易申报,但实际上并没有那么简单。

问题出现是由于鸡蛋问题:我应该先在哪一个表中插入一行?如果我们首先插入A,外键(朝向B)将禁止插入。如果我们先插入B,那么外键(朝向A)将禁止插入。

为了使这项工作,2个插入语句必须在一个事务中 - 并且外键必须被定义为REFERENCES A (pk) - 即在事务结束时检查。因此,如果您在SQL-Server(或MySQL)中工作,则根本无法做到这一点。如果您在Postgres或Oracle或任何其他已实施可延迟约束的DBMS,则可以实现。

答案 1 :(得分:1)

  

哪个表的PK在其他表中应该是FK?

两者。对于 true “1对1”,您将需要循环外键(这也意味着您需要延迟外键以在插入新数据时打破“鸡与蛋”问题,而不是所有DBMS支持)。

或者只将两个表合并到一个表中(在大多数情况下建议使用)。


但是,我怀疑你不是在谈论真正的“1对1”,而是“1到0或1”,在这种情况下,“0或1”端点应该包含外键,例如:

CREATE TABLE ONE (
    ID INT PRIMARY KEY
);

CREATE TABLE ZERO_OR_ONE (
    ID INT PRIMARY KEY REFERENCES ONE (ID)
);