这是一个简单的表,其中记录可以引用同一表中的父记录:
CREATE TABLE foo (
id SERIAL PRIMARY KEY,
parent_id INT NULL,
num INT NOT NULL,
txt TEXT NULL,
FOREIGN KEY (parent_id) REFERENCES foo(id)
);
加上其他字段值之一(num
)在父记录和子记录之间必须相同的附加要求,我认为复合外键应该可以解决问题。我将最后一行更改为
FOREIGN KEY (parent_id, num) REFERENCES foo(id, num)
并得到ERROR: there is no unique constraint matching given keys for referenced table "foo"。
我可以很容易地添加这个约束,但我不明白为什么它是必要的,当引用的列之一 ( id
) 已经保证是唯一的时?在我看来,新的约束将是多余的。
这是 DBMS 的一个限制——据我所知,在所有这些中。不仅在添加列时,而且在重新排列列时。如果我们对 有一个
UNIQUE
约束(a1, a2)
,我们就不能添加一个FOREIGN KEY
thatREFERENCES (a2, a1)
除非有一个唯一的约束,(a2, a1)
它本质上是多余的。将其添加为功能并不难:
或概括:
似乎它没有被要求或它没有被认为是足够高的优先级来实施。
您始终可以在相应的频道中提出请求,以实现该功能。如果 DBMS 是开源的,比如 Postgres,甚至可以自己实现它。
一般的外键(不仅仅是复合的)必须指向另一个表中某种类型的唯一键。如果他们不这样做,就不会有关系数据的完整性。
这是在抱怨,因为当您在 (id) .. 上有一个唯一键时,您在 (id, num) 上没有唯一键.. 因此,就数据库而言,这对 (id, num) 是不保证是唯一的。作为人类,我们可以发现它是独一无二的,但我敢肯定,他们必须添加很多额外的代码才能使 Postgres 足够聪明,才能看到“哦,嘿 .. id 应该是唯一的,所以 id,num 也应该是唯一的" ..
如果他们在您只需在两列上创建另一个唯一索引以解决问题时添加该代码,我会感到非常惊讶。
为了清楚起见,他们必须添加的代码不仅仅是这种简单的情况......它必须处理所有情况,即使是外键位于 4 列以上的情况,等等。我敢肯定逻辑会很复杂。