久々にハマって、何が悪いのかわからんレベルだったのでメモ書き。
例えば cds
テーブルを作って、ユーザに沢山のCDを入れてもらう時、cds.user_id
を入れるのですが、そこに外部キーを設定するという話。
Laravel: 5.3
MySQL: 5.6.34
結果
cds
テーブルを作るにはこんな感じのがいい。
/**
* Class AddCDTable
*
* CDを保存するテーブル
*/
class AddCDTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
\Schema::create( 'cds', function (Blueprint $table){
$table->increments( 'id' );
$table->unsignedInteger( 'user_id' )->comment = '所有ユーザデータID';
$table->string( 'name' )->comment = 'CD名';
$table->text('url')->comment = 'AmazonとかのURL';
$table->timestamps();
$table->index( 'user_id' );
$table->foreign('user_id')
->references('id')->on('users')
->onDelete('cascade')
->onUpdate('cascade');
} );
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
\Schema::dropIfExists( 'cds' );
}
}
何も考えずにボクがやってしまった事
/**
* Class AddCDTable
*
* CDを保存するテーブル
*/
class AddCDTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
\Schema::create( 'cds', function (Blueprint $table){
$table->increments( 'id' );
$table->integer( 'user_id' )->comment = '所有ユーザデータID';
$table->string( 'name' )->comment = 'CD名';
$table->text('url')->comment = 'AmazonとかのURL';
$table->timestamps();
$table->foreign('user_id')
->references('id')->on('users')
->onDelete('cascade')
->onUpdate('cascade');
} );
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
\Schema::dropIfExists( 'cds' );
}
}
要は二つあって、
-
cds.user_id
に Index が張られていないからコケる。 -
cds.user_id
の型が、increments
で作成されるunsigned int(10)
と、integer
で生成されるint(11)
が別なのでコケる。
両方共、コケた時のエラーが Cannot add foreign key constraint
だけなので話がなおややこしい。
細かいエラーを見るには show warnings
を実行して結果の Create table 'test/#sql-360e_7dc' with foreign key constraint failed. There is no index in the referenced table where the referenced columns appear as the first columns.
あたりから目星をつけるしか無いっぽい。