8

假设我们有这些表:

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

是否可以创建一个唯一约束,以使最多一个引用Child中的所有行都具有某个值?换一种说法,我可以创建一个唯一约束,以便上述表的连接没有重复吗?我不认为——我能找到的每个数据库的语法似乎都与每个约束绑定到一个表——但这可能是我缺乏想象力。(当然,反规范化以包含在其中是一种解决方案。)ChildParentaIdaIdaIdChild

4

2 回答 2

4

您可以尝试以下方法。您必须在 Parent 上创建一个冗余的 UNIQUE 约束(id, aId)(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);

可能更好的解决方案是从 Child 表中完全删除 parentId,添加bId并仅基于以下内容引用 Parent 表(aId, bId)

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

你有什么理由不能这样做吗?

于 2011-06-08T19:23:23.907 回答
1

执行此操作的正确方法是Child完全取消表并将createdOn列放入Parent表中,而没有NOT NULL约束。您所说的只是一个Parent条目可以有零个或一个(但不是更多)createdOn值。你不需要一个单独的表。这样做并不容易或不明显这一事实部分地证明了我的观点。;-) SQL 通常是这样工作的。

于 2011-06-09T08:25:43.607 回答