简体   繁体   English

对多个表的唯一约束

[英]Unique constraint over multiple tables

Let's say we have these tables:假设我们有这些表:

CREATE TABLE A (
    id SERIAL NOT NULL PRIMARY KEY
);
CREATE TABLE B (
    id SERIAL NOT NULL PRIMARY KEY
);
CREATE TABLE Parent (
    id SERIAL NOT NULL PRIMARY KEY,
    aId INTEGER NOT NULL REFERENCES A (id),
    bId INTEGER NOT NULL REFERENCES B (id),
    UNIQUE(aId, bId)
);
CREATE TABLE Child (
    parentId INTEGER NOT NULL REFERENCES Parent (id),
    createdOn TIMESTAMP NOT NULL
);

Is it possible to create a unique constraint on Child such that for all rows in Child at most one references a Parent having some value of aId ?是否可以在Child上创建一个唯一约束,以便对于Child中的所有行至多引用一个具有某些aId值的Parent Stated another way can I created a unique constraint so that the join of the above tables will have no duplicate aId ?换句话说,我可以创建一个唯一约束,以便上述表的连接不会有重复aId吗? I'm thinking not--the grammars of every database I could find seem tied to one table per constraint--but that might be a lack of imagination on my part.我不认为——我能找到的每个数据库的语法似乎都与每个约束绑定到一个表——但这可能是我缺乏想象力。 (De-normalizing to include aId on Child is one solution, of course.) (当然,去规范化以在Child上包含aId是一种解决方案。)

You could try the following.您可以尝试以下方法。 You have to create a redundant UNIQUE constraint on (id, aId) in Parent (SQL is pretty dumb isn't it?.).您必须在 Parent 中的(id, aId)上创建一个冗余的 UNIQUE 约束(SQL 非常愚蠢,不是吗?)。

CREATE TABLE Child
(parentId INTEGER NOT NULL,
 aId INTEGER NOT NULL UNIQUE,
FOREIGN KEY (parentId,aId) REFERENCES Parent (id,aId),
createdOn TIMESTAMP NOT NULL);

Possibly a much better solution would be to drop parentId from the Child table altogether, add bId instead and just reference the Parent table based on (aId, bId) :可能更好的解决方案是从 Child 表中完全删除 parentId,添加bId并仅基于(aId, bId)引用 Parent 表:

CREATE TABLE Child
(aId INTEGER NOT NULL UNIQUE,
 bId INTEGER NOT NULL,
FOREIGN KEY (aId,bId) REFERENCES Parent (aId,bId),
createdOn TIMESTAMP NOT NULL);

Is there any reason why you can't do that?你有什么理由不能这样做吗?

The proper way to do this would be to do away with the Child table altogether and put the createdOn column in the Parent table, without the NOT NULL constraint.执行此操作的正确方法是完全取消Child表并将createdOn列放在Parent表中,而不使用NOT NULL约束。 All you are saying is that one Parent entry can have zero or one (but not more) createdOn values.您所说的只是一个Parent条目可以有零个或一个(但不是更多) createdOn值。 You don't need a separate table for that.你不需要一个单独的表。 The fact that it is not easy or obvious to do otherwise partially proves my point.这样做并不容易或不明显这一事实部分地证明了我的观点。 ;-) SQL usually works out that way. ;-) SQL 通常会这样。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM