10
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

HRBrainAdvent Calendar 2024

Day 7

外部キー制約の親テーブルのレコードを削除したい!

Last updated at Posted at 2024-12-07

はじめに

HRBrain Advent Calendar 2024 7日目の記事です
こんにちは。イナです。
外部キー制約の親テーブルのレコードを削除したい!となったときの削除方法についてまとめました。

そもそも外部キーとは

  1. 社員と部署情報を管理したい
    スクリーンショット 2024-12-03 18.46.39.png

  2. 社員はどこかしらの部署に所属しているか分かるようにしたい
    スクリーンショット 2024-12-03 18.45.48.png

このときの部署IDが外部キー(FOREIGN KEY)になります。
外部キーとして部署のIDを紐づけておくことで、情報を辿れるようにしています。

外部キー制約とは

  1. これから頑張るぞ!
    スクリーンショット 2024-12-03 18.49.54.png

  2. 開発部署なくなっちゃった
    スクリーンショット 2024-12-03 18.49.42.png

  3. 花子さんの部署どこだろう。IDは2か。つまり、どこ!?
    スクリーンショット 2024-12-03 18.49.39.png

上記のようなケースを防ぐために、どこのテーブルのどこのIDと紐づけているかを定義してあげるのが外部キー制約です。
外部キー制約をしておけば、デフォルトだと2の段階でエラーが出るようになります。

じゃあ、消したいときにどうすればいいの?

基本的な方法としては、以下の2つかと思います。
どちらも、親テーブルのレコードを削除する前に処理をします。

子テーブルのカラムをNULLにしてから削除する

レコードは消したくない ときに使用します。

UPDATE 社員 SET 部署ID = NULL WHERE 部署ID = 2;
DELETE FROM 部署 WHERE ID = 2;

子テーブルのレコードを削除する

レコードごと消したい ときに使用します。

DELETE FROM 社員 WHERE 部署ID = 2;
DELETE FROM 部署 WHERE ID = 2;

余談

ちなみに、外部キー制約のON DELETEのoptionで外部キーが削除されたときの動作を指定できます。
CASCADEは制約のある子テーブルのレコードをすべて削除し、SET NULLは制約のある子テーブルのレコードのカラムにNULLをセットします。
しかし、こういった設定は意図しない動作になりやすいため、 基本的にデフォルトのままで削除時に処理をするのが望ましい のかなと思っています。(デフォルトではRESTRICTやNO ACTIONに設定されており、外部キー制約が適用されるものは削除しようとしたら拒否するようになっています。)

終わりに

今回は外部キー制約の削除方法についてまとめました。
どんなコードでもですが、意図しない動作は怖いですね...
物理削除は取り返しのつかないものなので、CASCADEやSET NULLを使う!というときは慎重に検討したいです。

PR

良い記事が続々投稿予定ですので、弊社のAdventCalendarもぜひご覧ください。
https://qiita.com/advent-calendar/2024/hrbrain

株式会社HRBrainでは、一緒に働く仲間を募集しています。
興味を持っていただいた方は、ぜひ弊社の採用ページをご確認ください。
HRBrain文化を一緒に作っていきましょう!

10
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?