39

postgresqlのドキュメントから:

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の間に違いはありません。それは(まだ)本当ですか?

4

1 に答える 1

35

DEFERRABLE違いは、INITIALLY DEFERREDorINITIALLY IMMEDIATEモードのように制約を定義する場合にのみ発生します。

を参照してくださいSET CONSTRAINTS

于 2013-02-17T13:42:31.983 に答える