关于建立索引的 767 bytes 长度限制
生产环境执行
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
本作品采用《CC 协议》,转载必须注明作者和本文链接
本帖由系统于 6年前 自动加精
推荐文章: