事象
Laravelの migrationで複合主キー(id, fuga_datetime)を設定しようとすると以下エラーが発生。
(idとfuga_dateteimeを複合主キーにすることの妥当性については無視...)
エラー
SQLSTATE[42000]: Syntax error or access violation: 1068 Multiple primary key defined (SQL: alter table `hoge` add primary key `tbl_hoge_id_fuga_datetime_primary`(`id`, `fuga_datetime`))
migration
public function up()
{
Schema::create('tbl_hoge', function (Blueprint $table) {
$table->bigIncrements('id');
// 省略
$table->dateTime('fuga_datetime');
$table->timestamps();
$table->primary(['id', 'fuga_datetime']);
});
}
原因
自動インクリメントのカラムがあると、そこが勝手に主キーになるとのこと。
idカラム( $table->bigIncrements('id');
)で主キーが設定されているのに、さらに複合主キー( $table->primary(['id', 'fuga_datetime']);
)を作成しようとしているのでエラーが出ていた。
対処法
一旦自動インクリメントを指定せずにidを作成し、複合主キーを設定した後にidに自動インクリメントを設定する。
migration
public function up()
{
Schema::create('tbl_hoge', function (Blueprint $table) {
$table->unsignedBigInteger('id');
// 省略
$table->dateTime('fuga_datetime');
$table->timestamps();
$table->primary(['id', 'fuga_datetime']);
});
Schema::table('tbl_hoge', function (Blueprint $table) {
$table->unsignedBigInteger('id', true)->change();
});
}
参考:github:Multiple primary keys with one auto increment #17204
integer('id', true, true)について
参考にしたgithub issuesに載っていたこの記述法、integerに第二、第三引数を指定したことがなかったので調べてみた
(公式ドキュメント内では使い方は見つけられず、、)
ソースを見てみると
第二引数:autoIncrementの指定
第三引数:unsignedの指定
のようでした。
src/vendor/laravel/framework/src/Illuminate/Database/Schema/Blueprint.php
/**
* Create a new integer (4-byte) column on the table.
*
* @param string $column
* @param bool $autoIncrement
* @param bool $unsigned
* @return \Illuminate\Database\Schema\ColumnDefinition
*/
public function integer($column, $autoIncrement = false, $unsigned = false)
{
return $this->addColumn('integer', $column, compact('autoIncrement', 'unsigned'));
}