7
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Laravel5.3のmigrateでパーティションを作成したらハマった罠

Last updated at Posted at 2017-05-05

対応策:

  • 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()なデータ型から主キーを外すオプションは欲しい。

7
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?