从
postgresql documentation:
RESTRICT prevents deletion of a referenced row. NO ACTION means that if any referencing rows still exist when the constraint is checked,an error is raised; this is the default behavior if you do not specify anything. (The essential difference between these two choices is that NO ACTION allows the check to be deferred until later in the transaction,whereas RESTRICT does not.)
让我们检查一下
创建父表和子表:
CREATE TABLE parent ( id serial not null,CONSTRAINT parent_pkey PRIMARY KEY (id) ); CREATE TABLE child ( id serial not null,parent_id serial not null,CONSTRAINT child_pkey PRIMARY KEY (id),CONSTRAINT parent_fk FOREIGN KEY (parent_id) REFERENCES parent (id) ON DELETE NO ACTION ON UPDATE NO ACTION );
填写一些数据:
insert into parent values(1); insert into child values(5,1);
而测试确实检查真的很差:
BEGIN; delete from parent where id = 1; -- violates foreign key constraint,execution fails delete from child where parent_id = 1; COMMIT;
第一次删除完整性被打破后,但是第二次它将被恢复.但是,首次删除时执行失败.
相同的更新:
BEGIN; update parent set id = 2 where id = 1; -- same as above update child set parent_id = 2 where parent_id = 1; COMMIT;
在删除的情况下,我可以交换语句以使其正常工作,但是在更新的情况下,我无法做到这一点(通过删除行和插入新版本可以实现).
许多数据库在RESTRICT和NO ACTION之间没有任何区别,而postgres则假装不作.是(仍然)真的吗
解决方法
只有当您将限制定义为具有INITIALLY DEFERRED或INITIALY IMMEDIATE模式的DEFERRABLE时,才会产生差异.