mysql索引过长Specialed key was too long的解决方法

目录
  • 解决办法一
  • 解决办法二

在创建要给表的时候遇到一个有意思的问题,提示specified key was too long; max key length is 767 bytes,从描述上来看,是key太长,超过了指定的 767字节限制

下面是产生问题的表结构

create table `test_table` (
  `id` int(11) unsigned not null auto_increment,
  `name` varchar(1000) not null default '',
  `link` varchar(1000) not null default '',
  primary key (`id`),
  key `name` (`name`)
) engine=innodb auto_increment=1 default charset=utf8mb4;

我们可以看到,对于name,我们设置长度为1000可变字符,因为采用utf8mb4编码, 所以它的大小就变成了 1000 * 4 > 767
所以再不修改其他配置的前提下,varchar的长度大小应该是 767 / 4 = 191

有兴趣的同学可以测试下,分别指定name大小为191, 192时,是不是前面的可以创建表成功,后面的创建表失败,并提示错误specified key was too long; max key length is 767 bytes

解决办法一

  • 使用innodb引擎
  • 启用innodb_large_prefix选项,修改约束扩展至3072字节
  • 重新创建数据库

my.cnf配置

set global innodb_large_prefix=on;
set global innodb_file_per_table=on;
set global innodb_file_format=barracuda;
set global innodb_file_format_max=barracuda;

上面这个3072字节的得出原因如下

我们知道innodb一个page的默认大小是16k。由于是btree组织,要求叶子节点上一个page至少要包含两条记录(否则就退化链表了)。
所以一个记录最多不能超过8k。又由于innodb的聚簇索引结构,一个二级索引要包含主键索引,因此每个单个索引不能超过4k (极端情况,pk和某个二级索引都达到这个限制)。
由于需要预留和辅助空间,扣掉后不能超过3500,取个“整数”就是(1024*3)。

解决办法二

在创建表的时候,加上 row_format=dynamic

create table `test_table` (
  `id` int(11) unsigned not null auto_increment,
  `name` varchar(255) not null default '',
  `link` varchar(255) not null default '',
  primary key (`id`),
  key `name` (`name`)
) engine=innodb default charset=utf8mb4 row_format=dynamic;

这个参数的作用如下

mysql 索引只支持767个字节,utf8mb4 每个字符占用4个字节,所以索引最大长度只能为191个字符,即varchar(191),若想要使用更大的字段,mysql需要设置成支持数据压缩,并且修改表属性 row_format ={dynamic|compressed}

到此这篇关于mysql索引过长specialed key was too long的解决方法的文章就介绍到这了,更多相关mysql索引过长内容请搜索www.887551.com以前的文章或继续浏览下面的相关文章希望大家以后多多支持www.887551.com!

(0)
上一篇 2022年3月21日
下一篇 2022年3月21日

相关推荐