现象
创建数据库表的时候,报错:ERROR 1071 (42000): Specified key was too long; max key length is 767 bytes
信息很明确,就是由于 innoDB 表的索引长度限制,那么为什么会有这个限制,怎么消除这个限制,当然分析了下。
原因
其实,在 MySQL5.6 版本后引入了参数 innodb_large_prefix 可以解决这个问题。该参数控制是否允许单列的索引长度超过 767 字节,有 ON 和 OFF 两个取值:
- ON :Innodb 表的行记录格式(row format)是 Dynamic 或 Compressed 的前提下,单列索引长度上限扩展到 3072 个字节,联合索引长度上线仍为 3072 个字节
- OFF:Innodb 表的单例索引长度最多为 767 个字节,索引长度超出后,主键索引会创建失败,唯一索引也会创建失败,辅助索引会被截断成为前缀索引
解决方案
使用前缀索引,减少字段索引长度;
设置 MySQL 的全局参数 innodb_large_prefix=ON,将 InnoDB 表的索引上限扩大到 3072 个字节。
说明
字段 varchar(N)中的 N 是指字符的长度,不是字节数,需要结合字符集换算得出字节数。例如:utf8 字符集一个字符占 3 个字节,若单列索引限制 767,则最大可以支持 N=255.而 utf8mb4 字符集一个字符占 4 个字节,若单列索引限制 767,则最大可以支持 N=191。
建议
- 在数据库迁移和数据库版本升级的过程中,需要对齐源库和目标库的 innodb_large_prefix 参数取值,否则可能导致建表失败
- 在设计数据库表结构的过程中,对于一个可能包含很长字符串的列上创建索引时尽量使用前缀索引