schedule2020-01-22

Laravel6.xでMySQL5.5を使うための設定

開発サーバに相乗りするためにMySQL5.5の環境にLaravel6.2を配置しました。 その際、SQLのエラーが出たのでそれを回避する設定について書きます。

デフォルトの設定を維持しつつ、他のプロジェクトへ影響も鑑みてmy.confは変更しないよう対応します。

環境

  • CentOS 7
  • PHP 7.3
  • Laravel 6.2
  • MySQL5.5

変更点

先に変更点を挙げます。 文字コードとstrictモードについてサーバ毎に変更できるようにしました。

config/database.php

'mysql' => [
    // 文字コードを指定
    'charset' => env('DB_CHARSET', 'utf8mb4'),
    'collation' => env('DB_COLLATION', 'utf8mb4_unicode_ci'),

    // strictモードを指定
    'strict' => env('DB_STRICT', true),
],

.env

DB_CHARSET=utf8
DB_COLLATION=utf8_unicode_ci
DB_STRICT=false

MySQL 5.8以降の環境では .envに修正が不要です。

文字コードの対応

[previous exception] [object] (PDOException(code: 42000): SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was too long; max key length is 767 bytes at /srv/samples.jp/app/vendor/laravel/framework/src/Illuminate/Database/Connection.php:463)"}

このエラーが出たので調べると次の記事に辿り着いた。

原因について詳しくかかれているので引用させて頂きます。

  1. Laravel5.4から標準charasetがutf8mb4に変わった 標準charasetがutf8mb4となったことで1文字あたりの最大byte数が4bytesに増えた。
  2. MySQL5.7.7未満ではユニーク制約を付けたカラムは最大767bytes マイグレーションファイルにvarcharカラムの大きさを指定しなかった場合、varchar(255) のカラムが作成される。
$table->string('email')->unique();

一方、MySQL5.7.7以前のバージョンでは、PRIMARY_KEYおよびUNIQUE_KEYを付けたカラムには最大767bytesまでしか入らない。

4bytes,255文字では767bytesを超えてしまう。これがエラーの原因。

また、utf8utf8mb4の違いは以下のよう。

MySQL の UTF-8 には歴史的事情により utf8 と utf8mb4 の二つあります。

UTF-8 は1バイト〜4バイトで1文字が構成される文字コードですが、MySQL の utf8 は4バイト文字を扱うことができません。ハマりたくなければ utf8mb4 を使いましょう。 MySQL で utf8 と utf8mb4 の混在で起きること - @tmtms のメモ

特に絵文字は4バイトであるためutf8だと使えない。

strictモード