如何在PostgreSQL中实现循环约束?

时间:2012-12-04 10:01:42

标签: postgresql database-design

我想强制一个表中的一行必须在另一个表中具有匹配的行,反之亦然。我目前正在这样做,以解决您无法参考尚未创建的表的事实。是否有一种我不了解的更自然的方式?

CREATE TABLE LE (id int PRIMARY KEY);
CREATE TABLE LE_TYP (id int PRIMARY KEY, typ text);

ALTER TABLE LE ADD CONSTRAINT
  twowayref FOREIGN KEY (id) REFERENCES LE_TYP (id) DEFERRABLE INITIALLY DEFERRED;

ALTER TABLE LE_TYP ADD CONSTRAINT
  twowayref_rev FOREIGN KEY (id) REFERENCES LE (id) DEFERRABLE INITIALLY DEFERRED;

1 个答案:

答案 0 :(得分:0)

当您有循环约束时,您正在做的事情是理想的。在您的解决方案中没有任何可以改进的地方。

然而,对于下一位读者而言,有两点值得一提。首先,在您的代码中使用此解决方案并不明显为什么您选择自己的订单。如果您这样做,您可能需要注意延迟哪个约束。通常这很明显,但您可能希望根据引用相应表的其他外键选择插入顺序。

另一个是关于是否需要围绕循环依赖关系进行设计的想法。一方面,这样做似乎是一个好主意,这似乎是一个明显的简化。

但值得指出的是,在这种情况下,您可能希望查看多个表继承。通过这种方式你可以这样做:

CREATE TABLE p1 (
     id serial not null,
     attribute1 int not null,
     attribute2 text not null,
     check (attribute1 > 1 or length(attribute2) > 10)
);

CREATE TABLE p2 (
     id int not null, -- shared primary key with p1
     attribute3 int not null,
     attribute4 text not null
);

CREATE TABLE combined (
     primary key (id)
) INHERITS (p1, p2);

这会将您的所有列放在一个表中,但会为您提供该表的逻辑接口,就好像它是在公共字段上连接的两个表一样。