【テーブル】
Booksテーブル
Categoriesテーブル
upメソッドでforeignIdが使われていたとする。
以下の記述はBooksテーブルを作成するものだ。
$table->foreignId('category_id')->constrained();
であるが、これはどうやらCategoriesテーブルのidを参照するらしい。
public function up(): void { Schema::create('books', function (Blueprint $table) { $table->id(); $table->string('title', 100); $table->foreignId('category_id')->constrained(); $table->timestamps(); }); }
この仕組みがよくわからなかったので調べてみた。
もくじ
foreignIdメソッドとの解説
foreignId
foreignId
メソッドは、外部キー(foreign key)を定義するために使われます。
このコードでは、category_id
というカラムを作成しています。このカラムは通常、関連する別のテーブル(ここではcategories)のIDを参照します。
デフォルトでは、作成されるカラムの型は BIGINT UNSIGNED
となります。
【外部キー(Foreign Key)とは?】
外部キーとは、データベースにおける”リレーション(関係)”を表現するために使われる特別なキーです。
あるテーブルの列が、”他のテーブルの主キー(Primary Key)”を参照している場合、その列を外部キーと呼びます。
constrained
constrained
メソッドは、foreignId
で作成したカラムに外部キー制約(foreign key constraint)を設定します。
このメソッドを使うと、以下を自動的に行います。
例: category_id
→ categories
テーブルのid
カラムを参照します。
ここから本題に入ります。
参照先として自動的に推測されること
参照先のテーブル名
$table->foreignId('category_id')->constrained();
category_idのcategory
部分をもとに、categoriesテーブルが推測されます。
デフォルトの動作(名前から推測)
- 推測される参照先テーブル名:
categories
- 参照先カラム名:
id
->constrained()
を使う場合、デフォルトの挙動として外部キーの名前(例: category_id
)のプレフィックス部分(category
)をもとに、参照先テーブル名が自動的に推測されます。このため、カラム名とテーブル名の命名規則が一致させるのが自然だし、便利に使える。
さらにこの仕組みを知っていればLaravelを使用している人ならば”予測ができる”という意味でわかりやすさに繋がる。
参照先のカラム名
外部キーが参照するカラム名はデフォルトでid
が選ばれます。
カスタマイズ
外部キーが参照するカラムは何もしなければidが選ばれるということがわかった。
では参照するテーブルやカラムを指定することはできるのか?
→できる
参照先のテーブル名やカラム名を明示的に指定したい場合
外部キーがデフォルトのテーブル・カラムを参照しない場合は、以下のように明示的に指定できます。
$table->foreignId('category_id')->constrained('custom_table_name', 'custom_column_name');
外部キーの挙動を制御(onDeleteなど)
onDelete
やonUpdate
を使って外部キーの動作を制御できます。
$table->foreignId('category_id')->constrained()->onDelete('cascade');
onDelete(‘cascade’)
categoriesテーブルの参照するレコードが削除された際、自動的にこのテーブルの関連レコードも削除します。
onDelete(‘restrict’)
参照先レコードが削除されるのを防ぎます。
まとめ
$table->foreignId('category_id')->constrained();
ならcategory_idのプレフィックス:categoryからcategoriesテーブルを参照する。- デフォルトでIDを参照する。(カスタマイズ可能)
categoriesテーブルに関連付けられた外部キー制約を持つcategory_idカラムを作成する。
自動で外部キー制約を設定することで、参照整合性(referential integrity)を保つ仕組みをデータベースに組み込むことができる。