生產環境執行
php artisan migrate
Laravel 丟擲錯誤:
Index column size too large. The maximum column size is 767 bytes.
然而在本地開發的時候是正常的。
搜尋了一番。 原因定位在欄位的長度設定
。
- Laravel 建表使用的是 utf8mb4 字符集。 這個一個4位元組字符集
- 如果說最大限制是 767 bytes。 那麼一個 varchar 欄位:767/4=191.75。
- 所以我欄位設定使用預設的(255),遠遠超出了限制。
為什麼在本地開發時又正常呢?
- 本地開發使用的 MySQL5.7 而線上環境是 MySQL5.6。
- MySQL5.7 有預設引數
innodb_default_row_format=dynamic
和innodb_large_prefix=on
。這樣的引數下是允許建立長位元組索引的。 - MySQL5.6 的引數
innodb_large_prefix
預設為off
,並且沒有一個預設引數可以在新建表時選擇自己想要的 row_format,只能在create table
或alert table
時 加上ROW_FORMAT=DYNAMIC
。
目前我試過可行的三種方法
- 將建立索引的
varchar
欄位長度調低,使所有欄位位元組之和不超過 767 bytes。 - 建表時將 MySQL 的
charset
改為 utf8 ,collation
改為 utf8_general_ci。可在 config/database.php 中設定預設值。 - 將 MySQL 升級到 5.7 版本
未嘗試的方法
- 設定 MySQL 的引數:
set GLOBAL innodb_large_prefix=ON;
- 建表時新增
ROW_FORMAT=DYNAMIC
參考
MySQL 5.6 Reference Manual : DYNAMIC and COMPRESSED Row Formats
MySQL 5.7 Reference Manual : Limits on InnoDB Tables