対応策:
-
DB:statement("ALTER TABLE [テーブル名] DROP PRIMARY KEY, ADD PRIMARY KEY (`id`, `created_at`)");
で主キーをDROPして複合主キーを発行 -
$table->timestamps()
を削除して$table->dateTime('created_at')
に変更
原因:
自動で発行される主キーの罠
$table->increments('id')
完全に盲点だったのだが↑のコードを実行すると自動的に主キーが発行される。
AUTO_INCREMENT値はだいたいの場合主キーに設定するのでわからなくはないが主キーにしない、というオプションが存在しない模様。
なのでこの状態で「主キーを複合主キーにすればパーティション作成できるじゃん!」とか考えていて痛い目をみた。
Syntax error or access violation: 1068 Multiple primary key defined
$table->primary(["id", "created_at"])
を呼び出してもすでに主キーがあるため↑のエラーが吐かれる
(上書きしてくれたりはしない、めんどくせえ…)
--
created_at
の型がパーティショニングに対応していない
Laravelのmigrationファイルを作成するときにphp artisan make:migration --create=[テーブル名]
をすると思うんだけど
migrate側が自動的に生成してくれる$table->timestamps()
で定義されているデータ型がパーティショニングに対応していない。
具体的にはMySQLのパーティショニングがサポートする日付、時間関連のデータ型はDatetime、もしくはDate型のみサポートしているためTimestamp型はサポート対象外となる。
Syntax error or access violation: 1067 Invalid default value for 'created_at' (SQL: ALTER TABLE [テーブル名] DROP PRIMARY KEY, ADD PRIMARY KEY (`id`, `created_at`))
Field 'created_at' is of a not allowed type for this type of partitioning
Laravel4で複合プライマリーキーを設定するではtimestampsでイケた!とあるが少なくともLaravel(5.3)+MySQL(5.7.18)ではエラーになる。
--
まとめ
ちなみにスキーマビルダーではパーティションの作成はできないのでmigrationファイル内でDB:statement("ALTER TABLE [テーブル名] PARTITION BY RANGE COLUMNS(`created_at`) ([省略])");
みたいな泥臭い実装をする必要がある。
パーティションは割りとよく使う部分の機能だと思うがサポートするのは面倒そうだしわからなくはないがincrements()/bigIncrements()
なデータ型から主キーを外すオプションは欲しい。