如何CASCADE从子表删除到父表?

sam*_*mol 8 sql postgresql database-design cascade foreign-keys

我准备了一个演示问题的小提琴.

CREATE TABLE parent (
   parent_id integer primary key
);

CREATE TABLE child (
   child_name TEXT primary key,
   parent_id integer REFERENCES parent (parent_id) ON DELETE CASCADE
);

INSERT INTO parent VALUES (1);
INSERT INTO child VALUES ('michael',1), ('vanessa', 1);
Run Code Online (Sandbox Code Playgroud)

我想要一种删除子记录时删除CASCADE到父记录的方法.
例如:

DELETE FROM child WHERE child_name='michael';
Run Code Online (Sandbox Code Playgroud)

这应该级联到父表并删除记录.

Cra*_*ger 9

外键仅在另一个方向上工作:级联从父级删除到子级,因此当删除父级(引用的)记录时,也会删除任何子级(引用)记录.

如果它是1:1关系,您可以创建双向外键关系,其中一侧是DEFERRABLE INITIALLY DEFERRED,并且两侧都是级联.

否则,ON DELETE ... FOR EACH ROW如果没有剩余的子项,您将需要子表上的触发器删除父行.它可能容易出现并发INSERTs的竞争条件; 你需要SELECT ... FOR UPDATE父记录,然后检查其他子记录.对插入的外键检查会FOR SHARE锁定引用的(父)记录,这样可以防止任何竞争条件.


Erw*_*ter 6

你似乎想要杀死整个家庭,而不顾剩下的孩子。运行这个而不是DELETE FROM child ...

DELETE FROM parent p
USING  child c
WHERE  p.parent_id = c.parent_id
AND    c.child_name = 'michael';
Run Code Online (Sandbox Code Playgroud)

然后一切都适合您当前的设计。如果你坚持原来的DELETE说法,你就需要一个规则或一个触发器。但这会相当混乱。

DELETE手册中的声明。