今天优化公司项目时候创建索引时报了:
1071 - Specified key was too long; max key length is 767 bytes错误,意思就是“索引字段长度太长,超过了767bytes”。

查了一下 mysql的varchar主键只支持不超过767个字节或者768/2=384个双字节 或者767/3=255个三字节的字段 而GBK是双字节的,UTF8是三字节的。

innodb存储引擎,多列索引的长度限制如下:

  • 每个列的长度不能大于767 bytes;所有组成索引列的长度和不能大于3072 bytes

myisam存储引擎,多列索引长度限制如下:

  • 每个列的长度不能大于1000 bytes,所有组成索引列的长度和不能大于1000 bytes

定位到出错的建表语句,使用的字符集为(utf8mb4),而且长度是255(如下图所示)。
在这里插入图片描述
这个指每个字符最大的字节数为4,所以很明显 4*255 > 767
改变varchar的字符数,我改成了64就可以了。varchar(64)

问题虽然是解决了,但是难道InnoDB中单个索引字段的长度真的只能小于767?

又经过一番探索,发现在InnoDB中,可以启用启用innodb_large_prefix参数,来使得单个索引字段的长度突破767。

注意

  • 启用innodb_large_prefix参数能够取消对于索引中每列长度的限制(但是无法取消对于索引总长度的限制)
  • 启用innodb_large_prefix必须同时指定innodb_file_format=barracuda,innodb_file_per_table=true,并且建表的时候指定表的row_format为dynamic或者compressed(mysql 5.6中row_format默认值为compact)

启用innodb_large_prefix,那么限制值会增加到3072
具体的操作如下:

1 查看innodb_large_prefix,innodb_file_format参数

mysql> show variables like 'innodb_large_prefix';

+-------------------------+---------------+

| Variable_name | Value |

+--------------------------+--------------+

| innodb_large_prefix | OFF |

+--------------------------+--------------+

2 查看mysql> show variables like ‘innodb_file_format’;

+-------------------------+---------------+

| Variable_name | Value |

+-------------------------+---------------+

| innodb_file_format | Antelope |

+-------------------------+---------------+

3 建索引测试(innodb_large_prefix,innodb_file_format都为默认值的情况下)
在这里插入图片描述
并且索引列大于767 bytes时报错,组成索引列总长度大于3072 bytes时报错
④ 修改innodb_large_prefix,innodb_file_format参数

mysql> set global innodb_large_prefix=1;

mysql> set global innodb_file_format=BARRACUDA;

innodb_large_prefix=1并且innodb_file_format=BARRACUDA时,对于row_format为dynamic的表可以指定索引列长度大于767 bytes。但是索引列总长度的不能大于3072 bytes的限制仍然存在。

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐