【Laravel】migration:外部キー制約とは

時計 2023.09.28 / 時計

【Laravel】migration:外部キー制約とは

記事ではLaravelにおける、マイグレーション(migration)でテーブルのフィールドに外部キー制約を追加する方法について解説していきます。

Webアプリケーションで複数の関連するテーブルを使用する場合、外部キー制約を利用する必要があります。

マイグレーションで必須の知識である外部キー制約について、本記事を通して理解を深めてください。

Laravel用語の確認

マイグレーションとはデータベースのスキーマ(構造)を管理するための機能です。マイグレーションファイルにデータベーススキーマをコードで記述し、それをデータベースに反映することができます

外部キー制約とは

外部キー制約とはテーブルのフィールド(カラム)を他のテーブルの主キーにリンクし、データの整合性を保つための制約です。外部キーを設定することで親テーブル、子テーブルといったテーブル間の関係が作られます。

つまり外部キー制約は2つのテーブルを関係づけることでデータに矛盾が発生しない(整合性を保つ)ようにするということです。

参照先(紐づけされる側)が親テーブル、マイグレーションファイルに外部キーの定義を記述するのが子テーブルとなります。

注意点

子テーブルを作成する前に親テーブル(紐づけされる側)が作成されている必要があります

また親テーブルのレコードが削除された場合に、関連がある子テーブルのレコードを一緒に削除する設定もできます。

外部キーの作成例

マイグレーションファイルに外部キーの定義を追加して、テーブルに外部キーを作成する例を以下に記します。

外部キー制約の記述方法は2つあります。

  1. Laravel7以前までの方法
  2. foreignId メソッドの利用(Laravel7以降から使えるようになった)

まずLaravel7以前までは以下の記述方法で外部キーを作成していました。ここではpostsテーブルにusersテーブルのidフィールドを参照する外部キーuser_idフィールドを定義します。

public function up(): void
{
    Schema::table('posts', function (Blueprint $table) {
        $table->id();
        $table->string('title');
        $table->text('content');
        $table->unsignedBigInteger('user_id');

        $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');

        $table->timestamps();
    });
}

これによりpostsテーブルはusersテーブルのidフィールドを参照するuser_idフィールドが作成され、外部キー制約によりuser_idフィールドにはusersテーブルのidフィールドに存在する値しか登録できないようになります。

またonDelete()では紐づいているレコードが削除された場合に外部キー制約されているレコードのふるまいをどうするか指定しています。ここではcascadeを指定しており、Userが削除されたら関連するPostも削除されるようになります。

上記の記述方法で問題はありませんが、Laravel7以降から使えるようになったforeignIdメソッドを使用することでより簡単に外部キーを定義することができます。

public function up(): void
{
    Schema::table('posts', function (Blueprint $table) {
        $table->id();
        $table->string('title');
        $table->text('content');
        $table->foreignId('user_id')->constrained()->cascadeOnDelete();

        $table->timestamps();
    });
}

foreignIdメソッドは引数で指定した名前のunsigned BIGINTフィールドを作成し、constrainedメソッドにより外部キー制約を作成します。

注意点

foreignIdメソッドを使用する場合、参照先のフィールドのタイプがunsigned BIGINTである必要があります

参照先のテーブルがLaravelの規則と異なる名前であった場合、constrainedメソッドの引数にテーブル名を指定します。

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

Lravel7以降であればforeignIdメソッドとconstrainedメソッドを使った方法で、外部キー制約を作成することがおすすめです。