自由気ままに書いちゃおう

好きなことをつらつらと・・・

【MySQL】外部キー制約(ForeignKey制約)のon delete設定について

今回は外部キー制約を設定する際の、on delete設定についてです。

■前提

外部キー制約は以下の通り作成します。
※6行目の部分です。

f:id:guri2o1667:20201027104208p:plain

外部キー制約の書式は、以下の通りです。

foreign key (参照元の列名) references 参照先テーブル名(参照先列名) on delete cascade

つまり、「ordersテーブルのuser_id列は、usersテーブルのid列を参照する」ということになります。

参照される側(=usersテーブルのid列)を親、
参照する側(=ordersテーブルのuser_id列)を子
と表現します。
図にすると下記のような感じです。

f:id:guri2o1667:20201027104818p:plain

■on delete設定について

on deleteの後に続く単語(cascade , restrict , set null)により、
親テーブル/親レコードを削除しようとしたときの動作が異なります。

f:id:guri2o1667:20201027114823p:plain

1点補足ですが、
cascadeの場合、該当する行データが丸っと削除されます。
set nullの場合、該当する行データは残り、参照していたデータがNULLに置き換わります。

■on delete設定の動作検証の前の状態整理

以下の状態となっている前提とします。
【テーブル】

f:id:guri2o1667:20201027121618p:plain

【usersテーブル】

f:id:guri2o1667:20201027121645p:plain

【ordersテーブル】

f:id:guri2o1667:20201027121737p:plain

■on delete cascade 設定の動作検証

cascadeを選択した際の動作は、
「親情報を削除すると、子情報も削除される」というものでした。
そのため、今回は、usersテーブルのuser2(id=2)を削除してみます。

f:id:guri2o1667:20201027122643p:plain

f:id:guri2o1667:20201027122652p:plain

上記の通り、user2が削除されました。
続いて、ordersテーブルも確認してみます。

f:id:guri2o1667:20201027122736p:plain

f:id:guri2o1667:20201027122801p:plain

ordersテーブルのid=3のデータが丸っと削除されていることが確認できました。

■on delete restrict 設定の動作検証

restrictを選択した際の動作は、
「親情報を削除しようとした際にエラーが表示され、削除できない」というものでした。

そのため、今回は、usersテーブルのuser3(id=3)を削除してみます。

f:id:guri2o1667:20201027123353p:plain

上記を実行した際、以下の通りエラーとなりました。
※想定通りの動きです。
delete from users where id=3 Error Code: 1451. Cannot delete or update a parent row: a foreign key constraint fails (`user`.`orders`, CONSTRAINT `orders_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE RESTRICT) 0.000 sec12:33:41 delete from users where id=3 Error Code: 1451. Cannot delete or update a parent row: a foreign key constraint fails (`user`.`orders`, CONSTRAINT `orders_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE RESTRICT) 0.000 sec

■on delete set null 設定の動作検証

set null を選択した際の動作は、
「親情報を削除すると、子データがnullに置き換わる」というものでした。
作業前の状態は以下の通りです。
【usersテーブル】

f:id:guri2o1667:20201027123912p:plain

【ordersテーブル】

f:id:guri2o1667:20201027123937p:plain

では、今回も、usersテーブルのuser3(id=3)を削除してみます。

f:id:guri2o1667:20201027123353p:plain

削除後の各テーブルは以下の通りです。
【usersテーブル】

f:id:guri2o1667:20201027124031p:plain

【ordersテーブル】

f:id:guri2o1667:20201027124054p:plain

上記のordersテーブルのid4をみると、user_id列が「NULL」として設定されています。※期待通りの動作です。


以上です。



以上です。