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

 更新时间:2021年11月08日 11:08:39   作者:一灰灰  
在创建要给表的时候遇到一个有意思的问题,提示Specified key was too long; max key length is 767 bytes,本文就来介绍一下解决方法,如果你也遇到此类问题,可以参考一下

在创建要给表的时候遇到一个有意思的问题,提示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索引过长内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • MYSQL分页limit速度太慢的优化方法

    MYSQL分页limit速度太慢的优化方法

    这篇文章主要介绍了MYSQL分页limit速度太慢的优化方法,需要的朋友可以参考下
    2016-05-05
  • MySQL数据库优化的六种方式总结

    MySQL数据库优化的六种方式总结

    关于数据库优化,网上有不少资料和方法,但是不少质量参差不齐,所以下面这篇文章主要给大家介绍了关于MySQL数据库优化的六种方式,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-01-01
  • mysql数据库连接池配置教程

    mysql数据库连接池配置教程

    在与数据库进行连接的时候,会牵扯到数据库连接池的配置,本文将详细介绍mysql数据库连接池配置,需要了解跟多的朋友可以参考下
    2012-11-11
  • mysql修改数据库默认路径无法启动问题的解决

    mysql修改数据库默认路径无法启动问题的解决

    这篇文章主要给大家介绍了关于mysql修改数据库默认路径无法启动问题的解决方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2018-11-11
  • MySQL笔记之运算符使用详解

    MySQL笔记之运算符使用详解

    运算符包括四类,分别是:算数运算符、比较运算符、逻辑运算符和位运算符
    2013-05-05
  • 解读SQL语句中要不要加单引号的问题

    解读SQL语句中要不要加单引号的问题

    这篇文章主要介绍了关于SQL语句中要不要加单引号的问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-02-02
  • MySQL中触发器和游标的介绍与使用

    MySQL中触发器和游标的介绍与使用

    这篇文章主要给大家介绍了关于MySQL中触发器和游标的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-03-03
  • 清理MySQL Binlog二进制日志的三种方式

    清理MySQL Binlog二进制日志的三种方式

    Binlog日志非常重要,但是占用的磁盘空间也很大,我们也需要定期的去清理二进制日志,在MySQL数据库中,提供了自动清理Binlog日志的参数,本文给大家介绍了清理MySQL Binlog二进制日志的三种方式,文中通过代码讲解非常详细,需要的朋友可以参考下
    2024-01-01
  • 检查MySQL中的列是否为空或Null的常用方法

    检查MySQL中的列是否为空或Null的常用方法

    在MySQL数据库中,我们经常需要检查某个列是否为空或Null,空值表示该列没有被赋值,而Null表示该列的值是未知的或不存在的,在本文中,我们将讨论如何在MySQL中检查列是否为空或Null,并探讨不同的方法和案例,需要的朋友可以参考下
    2023-11-11
  • MySQL笔记之字符串函数的应用

    MySQL笔记之字符串函数的应用

    字符串操作在程序设计中是非常重要的组成部分,而MySQL数据库中的字符串操作却相当简单
    2013-05-05

最新评论