解决MySQL Specified key was too long; max key length is 767 bytes

最近在给QA测试环境数据表的一个的 varchar(255) 类型字段添加索引时遇到了错误Specified key was too long; max key length is 767 bytes,奇怪的是同样的创建索引命令是可以在开发环境执行成功的。
我们知道InnoDB引擎索引字段长度不能超过767,所以在排查问题时,我的第一反应是数据表的字符集配置有问题。

  • utf8mb4 字符集是 1个字符=4个字节, varchar255字节长度 = 255 * 4=1020字节
  • utf8 字符集是 1个字符=3个字节, varchar255字节长度 = 255 * 3= 765字节
  • gbk字符集是 1个字符=2个字节, varchar255字节长度 = 255 * 2= 510字节

检查了数据表,果然字符集配置是utf8mb4,255个字符需要1020个字节,报错是符合预期的。但是实际使用中,该列是用来存储固定64字符长的token的,就算是utf8mb4 字符集,64 * 4 = 256字节也是远远小于767的,按理不应该报错。

并且开发环境同样的数据表配置并没有出现问题,会不会是脏数据(超过64字符)引起的呢?
于是使用下面命令按列的长度排序,找出前5条数据,发现查出的列长度都是64,确定不是脏数据引起的问题。

SELECT 列名 FROM 表名 ORDER BY length(列名) DESC limit 5;

再次查看数据表,show create table 表名;,对比两个环境的数据表有什么差异,一个属性引起了我的注意。
原来QA环境该表的row_format属性不知为何被改为了compact。
image.png
row_format为compact时,不论实际数值长度为多少,创建索引时都按照数据列声明长度创建,如上文所提,255字符也就是需要1020字节,难怪会报错。
找到问题后修复就很简单了,将row_format改为Dynamic,即按照值的实际长度而非声明长度创建索引。

alter table 表名 row_format=Dynamic;

参考:
https://cloud.tencent.com/developer/article/1005696
https://stackoverflow.com/questions/1814532/1071-specified-key-was-too-long-max-key-length-is-767-bytes

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值