假设我们有这些表格:
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
上创建一个唯一约束,以便Child
中的所有行最多一个引用Parent
,其值为aId
?换句话说,我可以创建一个唯一约束,以便上表的连接没有重复aId
?我在想 - 我能找到的每个数据库的语法似乎都与每个约束的一个表相关联 - 但这可能是我缺乏想象力的。 (当然,在aId
上取消标准化以包含Child
是一种解决方案。)
答案 0 :(得分:4)
您可以尝试以下方法。你必须在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);
可能更好的解决方案是完全从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);
你有什么理由不能这样做吗?
答案 1 :(得分:1)
执行此操作的正确方法是完全取消Child
表并将createdOn
列放在Parent
表中,而不使用NOT NULL
约束。你要说的只是一个Parent
条目可以有零个或一个(但不是更多)createdOn
个值。您不需要单独的表。这样做的事实并不容易或不明显,这部分证明了我的观点。 ;-) SQL通常以这种方式运行。