mysqlで外部キーにRESTRICTを使用する方法


11

のデータベース構造

  CREATE TABLE Country (
  name varchar(40) NOT NULL,
  PRIMARY KEY  (name)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8;

CREATE TABLE City (
  name varchar(40) NOT NULL,
  PRIMARY KEY  (name)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8;

CREATE TABLE Map (
  country varchar(40) NOT NULL,
  city varchar(100) NOT NULL,
  PRIMARY KEY  (country,city),
  FOREIGN KEY (country) REFERENCES Country (name) ON DELETE CASCADE,
  FOREIGN KEY (city) REFERENCES City (name) ON DELETE RESTRICT
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Cityこれら3つの同等のコマンドを使用して、子の対応する値をそのままにして、親を削除することを期待しています

  FOREIGN KEY (city) REFERENCES City (name) ON DELETE NO ACTION
  FOREIGN KEY (city) REFERENCES City (name) ON DELETE RESTRICT
  FOREIGN KEY (city) REFERENCES City (name)

ただし、NO ACTIONOR を使用しRESTRICTたり、省略したりする場合ON DELETE。MySQLでは、次のエラーで親列から削除できません。

ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails 
('test'.'Map', CONSTRAINT 'Map_ibfk_2' FOREIGN KEY ('city') REFERENCES 'City'('name')
 ON DELETE RESTRICT

どこが間違っているのですか?NO ACTION親を削除して子を孤立させておくのはSQLの責任ではないですか?

回答:


13

DELETE RESTRICTのMySQLドキュメントによると

•RESTRICT:親テーブルの削除または更新操作を拒否します。RESTRICT(またはNO ACTION)を指定することは、ON DELETEまたはON UPDATE句を省略することと同じです。

ノーアクションも

•アクションなし:標準SQLのキーワード。MySQLでは、RESTRICTと同等です。参照されるテーブルに関連する外部キー値がある場合、InnoDBは親テーブルの削除または更新操作を拒否します。一部のデータベースシステムには遅延チェックがあり、NO ACTIONは遅延チェックです。MySQLでは、外部キー制約がすぐにチェックされるため、NO ACTIONはRESTRICTと同じです。

DELETE RESTRICTは、子ではなく親を削除から保護します。


5

親を削除して子を残したい場合は、おそらくON DELETE SET NULLオプションが必要です:

SET NULL:親テーブルから行を削除または更新し、子テーブルの1つまたは複数の外部キー列をNULLに設定します。ON DELETE SET NULL句とON UPDATE SET NULL句の両方がサポートされています。

SET NULLアクションを指定する場合は、子テーブルの列をNOT NULLとして宣言していないことを確認してください。

最後の文には「not」がたくさんあるので、parent_id NULLにできることを確認してください。

この関連する質問も参照してください:外部キーの削除/更新制約でSET NULLの目的は何ですか?

外部キーを定義することにより、親に対応する値を持たない子テーブルのエントリを受け入れないようにデータベースに指示しました。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.