How do I implement circular constraints in PostgreSQL?

强颜欢笑 提交于 2020-01-06 19:46:09

问题


I want to enforce that a row in one table must have a matching row in another table, and vice versa. I'm currently doing it like this to work around the fact that you can't REFERENCE a table that hasn't been created yet. Is there a more natural way that I'm not aware of?

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:


What you are doing is ideal where you have circular constraints. There is nothing that can be improved on in your solution.

There are however two points that are worth mentioning briefly just for the next reader. The first is that with this solution in your code isn't obvious why you are choosing the order you are. If you are doing this you probably want to be careful about which constraint is deferred. Usually this is obvious, but you probably want to choose your insert order based on other foreign keys referencing the appropriate tables.

The other is that of the idea of whether it is desirable to engineer around circular dependencies. On one hand it may seem like a good idea when doing so seems like an obvious simplification.

It is however worth pointing out that in a case like this you may want to look at multiple table inheritance instead. In this way you might do:

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);

This puts all your columns in one table, but gives you logical interfaces to that table as if it is two tables joined on a common field.



来源:https://stackoverflow.com/questions/13700284/how-do-i-implement-circular-constraints-in-postgresql

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!