0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

外部キー制約とテーブル設計の基礎

Last updated at Posted at 2025-03-23

はじめに

Laravelを使ってアプリ開発を進める中で、避けて通れないのがテーブル設計と リレーション(関連) の考え方。
その中でも「外部キー制約(foreign key)」は、データの整合性を保つためにとても重要です。

この記事では、外部キー制約の基本や、Laravelでの実装方法を自分用の備忘録としてまとめます。


①外部キー制約とは?

外部キーとは、あるテーブルのカラムが、別のテーブルの主キーとつながっている関係性のこと。

例:

  • posts テーブルの user_id は、users テーブルの id を参照する

このような関係を定義することで、間違ったデータが登録されるのを防げるようになります。


②Laravelでの外部キー制約の書き方

基本構文(Laravel 7以降推奨)

$table->foreignId('user_id')->constrained();

これで以下のような制約が自動で付加されます。

  • user_id は unsignedBigInteger 型になる
  • 参照先は users.id
  • 外部キー制約が自動的に張られる

③もっと詳しく指定したい場合

$table->foreignId('category_id')
      ->constrained('categories')
      ->onDelete('cascade');

④よく使うオプション

IMG_7725.jpeg

⑤具体例:postsテーブルでの外部キー設定

Schema::create('posts', function (Blueprint $table) {
    $table->id();
    $table->string('title');
    $table->text('body');
    $table->foreignId('user_id')->constrained()->onDelete('cascade');
    $table->timestamps();
});

このようにすることで

  • user_id に存在しない users.id は登録できなくなる
  • 親ユーザーが削除されると、その人の投稿も削除される

補足:本当に onDelete('cascade') でいいのか?

実務で多くのデータを扱うようになると、「親データを消したら自動で子も削除される」という cascade の動きが、想定外のデータ消失を引き起こすリスクになることがあります。

例えば、「退会したユーザーの投稿は残しておきたい」といったケースでは、SET NULLRESTRICT を使う方が適しています。

よく使うオプション比較

オプション 動作 主な用途
cascade 親を削除すると子も削除 テストデータ、一時的な関係
set null 子の外部キーを null にする 履歴データを残したい場合
restrict 子が残っていたら削除できない データ保全が最優先の場面

書き方の例:

$table->foreignId('user_id')
      ->nullable()
      ->constrained()
      ->onDelete('set null');

※ set null を使うときは nullable() を忘れずに!

$table->foreignId('user_id')
      ->constrained()
      ->onDelete('restrict');

経験からの教訓:

  • cascade を安易に使うと、意図しない大量削除の原因になる
  • 削除連鎖は便利だけど、明示的に「削除する責任」をコードで持つ設計の方が安全
  • set null や restrict を使う習慣を身に付けておくと、設計力が一段上がる

⑥よくあるエラー:外部キー制約違反

例)「Integrity constraint violation」エラー

このエラーは、以下のような状況で発生します

  • posts.user_id = 3 に対して、users.id = 3 が存在しない
  • 親を削除しようとしても、まだ子テーブルにデータが残っている

対策:

  • onDelete('cascade') などの設定を見直す
  • データの削除順序を調整する(子→親)

⑦外部キー制約を使うメリット

IMG_7726.jpeg

⑧まとめ

  • 外部キー制約は、 データベース設計における「交通ルール」 のようなもの
  • Laravelでは foreignId()->constrained() を使えば簡単に設定できる
  • 実務でも、データの整合性を保つために積極的に活用したい
0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?