RESTRICTは、参照された行の削除を防ぎます。NO ACTIONは、制約がチェックされたときに参照行がまだ存在する場合、エラーが発生することを意味します。これは、何も指定しない場合のデフォルトの動作です。(これら2つの選択肢の本質的な違いは、NO ACTIONを使用すると、トランザクションの後半までチェックを延期できるのに対し、RESTRICTでは許可されないことです。)
確認してみましょう。親子テーブルを作成します。
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;
最初の削除の整合性が壊れた後、2番目の削除の後にそれは復元されます。ただし、最初の削除では実行は失敗します。
更新についても同じです。
BEGIN;
update parent set id = 2 where id = 1; -- same as above
update child set parent_id = 2 where parent_id = 1;
COMMIT;
削除の場合はステートメントを交換して機能させることができますが、更新の場合は実行できません(両方の行を削除して新しいバージョンを挿入することで実現できます)。
多くのデータベースは、postgresがそうでないふりをしている間、RESTRICTとNOACTIONの間に違いはありません。それは(まだ)本当ですか?