はじめに
外部キー制約とは、2つのテーブルを 親テーブル と 子テーブル にして生合成を保つために用いられる。
例
webアプリに次のテーブルがあるとする。(イメージはツイッターなどのアプリ)
- 親テーブル:usersテーブル
- 子テーブル:postsテーブル
ここで注意するのは、誰が投稿したかがわかるuser_id
というカラムがpostsテーブル
にあること
ルール
migrationsフォルダに親よりも先に子を作るとうまくいかなくなるらしいので注意が必要
まずは//1のようにuser_id
を作成します。
子テーブル
public function up()
{
Schema::create('posts', function (Blueprint $table) {
$table->id();
$table->string('name')->unique();
$table->unsignedBigInteger('user_id'); //1 外部キー ※型には注意!
$table->foreign('user_id')->references('id')->on('users');//2 外部キー制約をつける
$table->timestamps();
});
}
この時注意しなければならないのは、user_id
のデータ型
は何でもいいわけではない!
usersテーブルのidカラムと同じでなければならない!
デフォルトのusersテーブルではidカラムのデータ型はunsignedBigInteger型
なので、作成するuser_idのデータ型もunsignedBigInteger型
でなければなりません。
親テーブル
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->id(); // ここが unsignedBigInteger型
$table->string('name')->unique();
$table->timestamps();
});
}
次に//2で外部キー制約をかける
次に、//2のように外部キー制約を実装する。
子テーブル
$table->foreign('user_id')->references('id')->on('users');//2 外部キー制約をつける
1. ->foreign('xxx')
で外部キー制約したいカラムを指定する
2. ->references('yyy')
で参照したいカラム名を指定する
3. ->on('zzz')
でその参照したいカラムがあるテーブル名を指定する
これで、userテーブルにあるidカラム
をpostsテーブルのuser_id
に参照させ、外部キー制約することができる!
実はもう一つ方法がある(省略型)
foreignId
メソッドを使うことで前に書いた方法よりも短く書くことができる。
子テーブル
public function up()
{
Schema::create('posts', function (Blueprint $table) {
$table->id();
$table->string('name')->unique();
$table->unsignedBigInteger('user_id'); //1 外部キー ※型には注意!
- $table->foreign('user_id')->references('id')->on('users');//2 外部キー制約をつける
+ $tabel->foreignId('user_id')->constrained();//2 ここで foreignIdメソッドを使う
$table->timestamps();
});
}
$tabel->foreignId('user_id')->constrained();
1. 外部キー制約したいカラム名をforeignId
メソッドの引数に与える。
2. constrained
メソッドはforeignId
メソッドに与えられた引数からどのテーブルのどのカラム
を参照したいのかを判断してくれる。
よってuesr_id
をforeignidメソッドに与えると,constrainedメソッドがuser_id = usersテーブルのidカラム
を参照したいと判断してくれる。