概要
OctoberCMS(Laravel) + MySQL(InnoDB) でマイグレーションを実行したら下記エラーが発生した。
SQLSTATE[HY000]: General error: 1709 Index column size too large. The maximum column size is 767 bytes.
未確認だが、OctoberCMSかそれが依存するパッケージでデフォルトcharsetがutf8からutf8mb4になったようで、依存パッケージを更新したら発生するようになった。
utf8mb4になったことで1文字のバイト数がutf8の3バイトから4バイトになり、例えば長さ255のvarchar型はutf8だと255x3で765バイトでOKだが、utf8mb4だと1020バイトになり上限を超えてしまうために発生する。
対処方法としては、utf8を使うか、上限を上げるかが考えられるが、上限を上げる歩法をメモする。
ちなみに、utf8にするには config/database.php
の mysql.charset
や mysql.collation
をutf8にするだけだ。
また、MySQL 5.7.7以上だとデフォルトでここにメモる方法をサポートする様になっているので、正攻法と言えるだろう。
データベースレベルでの設定
MySQL 5.7.7以上だとデフォルトでデータベースレベルの設定は有効になっているので不要だ。
5.7.7より下のバージョンでは、データベースレベルで下記を my.cnf に設定する。
[mysqld]
innodb_file_format=BARRACUDA
innodb_large_prefix=1
AWS RDSならRDSコンソールの Parameter groupsを作成して設定することができる。
ついでに、私が使っているdocker-composeだと command
にオプションとして渡すだけで良い。
version: '3'
services:
my-db:
image: mysql:5.6
container_name: my-db
command: --character-set-server=utf8mb4 --collation-server=utf8mb4_general_ci --innodb_file_format=BARRACUDA --innodb_large_prefix=1
...
テーブルレベルでの設定
そして、テーブルレベルで ROW_FORMAT=DYNAMIC
を設定する。
これはマイグレーションファイルでテーブル作成時の engine
で指定するようだ。
public function up()
{
Schema::create("my_table", function(Blueprint $table)
{
$table->engine = 'InnoDB ROW_FORMAT=DYNAMIC';
...
}
}
以上!