SQLite长臂检查约束?

时间:2019-06-03 10:29:18

标签: sql sqlite check-constraints

我在SQLite中有两个表,对一对多关系进行建模:

CREATE TABLE parent (
    id INTEGER PRIMARY KEY,
    payload TEXT
);

CREATE TABLE child (
    id INTEGER PRIMARY KEY,
    flag BOOLEAN,
    parent_id INTEGER,
    FOREIGN KEY(parent_id) REFERENCES parent (id) ON DELETE CASCADE ON UPDATE CASCADE, 
);

是否有一种方法可以将CHECK CONSTRAINT放在child.flag上,从而对于任何True,在所有child中总是只有一个parent

2 个答案:

答案 0 :(得分:5)

  

“尽管这可以通过放置应用程序级逻辑来解决,但我仍然想看看纯数据库中是否有任何创意解决方案,而不涉及应用程序和触发器。”

是的,可以通过partial unique index达到要求的约束条件:

CREATE UNIQUE INDEX idx ON child (flag, parent_id) WHERE flag = 1;

db<>fiddle demo

INSERT INTO parent(id, payload) VALUES(1, 'Parent1');
INSERT INTO child(id, flag, parent_id) VALUES (1, 1, 1);
INSERT INTO child(id, flag, parent_id) VALUES (2, 0, 1);
INSERT INTO child(id, flag, parent_id) VALUES (3, 0, 1);
SELECT * FROM child;

-- trying to insert second active child will cause unique index violation
INSERT INTO child(id, flag, parent_id) VALUES (4, 1, 1)
-- UNIQUE constraint failed: child.flag, child.parent_id

答案 1 :(得分:0)

我的研究表明,无法让本地检查约束知道其同级状态。我建议将检查逻辑放在应用程序层中。