のデータベース構造
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;
これらの3つの同等のコマンドにより、子の対応する値をそのままにして、City
から親を削除することを期待しています
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 ACTION
OR 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
どこが間違っているのですか?親を削除して子を孤立させるのは、SQLのNO ACTION
の責任ではありませんか?
DELETE RESTRICTに関するMySQLドキュメント によると
•RESTRICT:親テーブルの削除または更新操作を拒否します。 RESTRICT(またはNO ACTION)を指定することは、ON DELETEまたはON UPDATE句を省略することと同じです。
ノーアクションも
•アクションなし:標準SQLのキーワード。 MySQLでは、RESTRICTと同等です。参照されるテーブルに関連する外部キー値がある場合、InnoDBは親テーブルの削除または更新操作を拒否します。一部のデータベースシステムには遅延チェックがあり、NO ACTIONは遅延チェックです。 MySQLでは、外部キー制約がすぐにチェックされるため、NO ACTIONはRESTRICTと同じです。
DELETE RESTRICTは、子ではなく親を削除から保護します。
親を削除して子を残したい場合は、おそらく ON DELETE SET NULL
オプション:
SET NULL:親テーブルから行を削除または更新し、子テーブルの1つまたは複数の外部キー列をNULLに設定します。 ON DELETE SET NULL句とON UPDATE SET NULL句の両方がサポートされています。
SET NULLアクションを指定する場合は、子テーブルの列をNOT NULLとして宣言していないことを確認してください。
最後の文には「not」がたくさんあるので、parent_idcanがNULLであることを確認してください。
この関連するqestionも参照してください: 外部キーの削除/更新制約でSET NULLの目的は何ですか?
外部キーを定義することで、親に対応する値を持たない子テーブルのエントリを受け入れないようにデータベースに指示しました。