【Laravel】migration:外部キー制約とは
2023.09.28 /
本記事ではLaravelにおける、マイグレーション(migration)でテーブルのフィールドに外部キー制約を追加する方法について解説していきます。
Webアプリケーションで複数の関連するテーブルを使用する場合、外部キー制約を利用する必要があります。
マイグレーションで必須の知識である外部キー制約について、本記事を通して理解を深めてください。
マイグレーションとはデータベースのスキーマ(構造)を管理するための機能です。マイグレーションファイルにデータベーススキーマをコードで記述し、それをデータベースに反映することができます
【Laravel】マイグレーションとは(migration):テーブル作成について
外部キー制約とは
外部キー制約とはテーブルのフィールド(カラム)を他のテーブルの主キーにリンクし、データの整合性を保つための制約です。外部キーを設定することで親テーブル、子テーブルといったテーブル間の関係が作られます。
つまり外部キー制約は2つのテーブルを関係づけることでデータに矛盾が発生しない(整合性を保つ)ようにするということです。
参照先(紐づけされる側)が親テーブル、マイグレーションファイルに外部キーの定義を記述するのが子テーブルとなります。
子テーブルを作成する前に親テーブル(紐づけされる側)が作成されている必要があります
また親テーブルのレコードが削除された場合に、関連がある子テーブルのレコードを一緒に削除する設定もできます。
外部キーの作成例
マイグレーションファイルに外部キーの定義を追加して、テーブルに外部キーを作成する例を以下に記します。
外部キー制約の記述方法は2つあります。
- Laravel7以前までの方法
- 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メソッドを使った方法で、外部キー制約を作成することがおすすめです。