LoginSignup
1
1

More than 5 years have passed since last update.

OctoberCMSで "Index column size too large. The maximum column size is 767 bytes." が発生したときの対処方法

Last updated at Posted at 2018-09-22

概要

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.phpmysql.charsetmysql.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';
        ...
    }
}

以上!

1
1
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
1
1