MySQL的InnoDB存储引擎的表存在一系列的限制条件,其中比较常见的一种是表的字段索引长度限制,该限制与参数innodb_large_prefix相关。

问题现象

执行如下两个建表SQL操作,都返回了报错信息,导致建表失败:

  • 报错信息:ERROR 1071 (42000): Specified key was too long; max key length is 767 bytes
  • 报错信息:ERROR 1071 (42000): Specified key was too long; max key length is 3072 bytes

原因分析

导致上面报错的原因是由于InnoDB表的索引长度限制,在MySQL5.6版本后引入了参数innodb_large_prefix可以解决这个问题。该参数控制是否允许单列的索引长度超过767字节,有ON和OFF两个取值:

  • ON :Innodb表的行记录格式是Dynamic或Compressed的前提下,单列索引长度上限扩展到3072个字节
  • OFF:Innodb表的单例索引长度最多为767个字节,索引长度超出后,主键索引会创建失败,辅助索引会被截断成为前缀索引

解决方案

  • 使用前缀索引,减少字段索引长度
  • 设置MySQL的全局参数innodb_large_prefix=ON,将InnoDB表的索引长度上限扩大到3072个字节

案例复现

测试环境
MySQL内核版本:5.7 ROW_FORMAT = Dynamic | Compressed innodb_page_size= 16K innodb_file_mat = Barracuda
测试过程
建表语句innodb_large_prefix=OFFinnodb_large_prefix=ONCREATE TABLE tb_01(
id int(11) NOT NULL AUTO_INCREMENT,
column1 varchar(256) NOT NULL DEFAULT '',
PRIMARY KEY (id,column1)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ;建表失败
报错:Specified key was too long; max key length is 767 bytes建表成功CREATE TABLE tb_02(
id int(11) NOT NULL AUTO_INCREMENT,
column1 varchar(256) NOT NULL DEFAULT '',
PRIMARY KEY (id),
KEY idx01(column1)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ;建表成功
索引字段被截断为前缀索引:
KEY idx01 (column1(255))建表成功CREATE TABLE tb_03(
id int(11) NOT NULL AUTO_INCREMENT,
column1 varchar(256) NOT NULL DEFAULT '',
column2 varchar(256) NOT NULL DEFAULT '',
column3 varchar(256) NOT NULL DEFAULT '',
column4 varchar(256) NOT NULL DEFAULT '',
column5 varchar(256) NOT NULL DEFAULT '',
PRIMARY KEY (id,column1,column2,column3,column4,column5)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ;建表失败
报错信息:Specified key was too long; max key length is 767 bytes建表失败
报错信息:Specified key was too long; max key length is 3072 bytesCREATE TABLE tb_04(
id int(11) NOT NULL AUTO_INCREMENT,
column1 varchar(256) NOT NULL DEFAULT '',
column2 varchar(256) NOT NULL DEFAULT '',
column3 varchar(256) NOT NULL DEFAULT '',
column4 varchar(256) NOT NULL DEFAULT '',
column5 varchar(256) NOT NULL DEFAULT '',
PRIMARY KEY (id),
KEY idx01(column1,column2,column3,column4,column5)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ;建表失败
报错信息:Specified key was too long; max key length is 3072 bytes建表失败
报错信息:Specified key was too long; max key length is 3072 bytesCREATE TABLE tb_05(
id int(11) NOT NULL AUTO_INCREMENT,
column1 varchar(256) NOT NULL DEFAULT '',
column2 varchar(256) NOT NULL DEFAULT '',
column3 varchar(256) NOT NULL DEFAULT '',
column4 varchar(256) NOT NULL DEFAULT '',
PRIMARY KEY (id,column1,column2,column3,column4)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ;建表失败
报错信息:Specified key was too long; max key length is 767 bytes建表失败
报错信息:Specified key was too long; max key length is 3072 bytesCREATE TABLE tb_06(
id int(11) NOT NULL AUTO_INCREMENT,
column1 varchar(256) NOT NULL DEFAULT '',
column2 varchar(256) NOT NULL DEFAULT '',
column3 varchar(256) NOT NULL DEFAULT '',
column4 varchar(256) NOT NULL DEFAULT '',
PRIMARY KEY (id),
KEY idx01(column1,column2,column3,column4)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ;建表成功
索引字段被截断为前缀索引:
KEY idx01(,column1(255),column2(255),column3(255),column4(255))建表成功CREATE TABLE tb_07(
id int(11) NOT NULL AUTO_INCREMENT,
column1 varchar(255) NOT NULL DEFAULT '',
column2 varchar(255) NOT NULL DEFAULT '',
column3 varchar(255) NOT NULL DEFAULT '',
column4 varchar(255) NOT NULL DEFAULT '',
PRIMARY KEY (id,column1,column2,column3,column4)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ;建表成功建表成功CREATE TABLE tb_08(
id int(11) NOT NULL AUTO_INCREMENT,
column1 varchar(255) NOT NULL DEFAULT '',
column2 varchar(255) NOT NULL DEFAULT '',
column3 varchar(255) NOT NULL DEFAULT '',
column4 varchar(255) NOT NULL DEFAULT '',
PRIMARY KEY (id),
KEY idx01(id,column1,column2,column3,column4)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ;建表成功建表成功
说明

字段varchar(N)中的N是指字符的长度,不是字节数,需要结合字符集换算得出字节数。例如:utf8字符集一个字符占3个字节,若单列索引限制767,则最大可以支持N=255.

总结建议

总结

  1. innodb表的单列索引长度最大字节数是767字节,辅助索引超出会被截断,主键索引超出不会截断直接报错导致建表失败
  2. innodb表的联合索引中每个字段的最大字节数是767字节,并且要求联合索引的总长度不超过3072字节
  3. 主键索引不允许被截断,辅助索引可以被截断
  4. 设置参数innodb_large_prefix=ON只能把单列索引长度扩大到3072字节,联合索引总长度的上限不变,仍然是3072个字节

建议

  • 在数据库迁移和数据库版本升级的过程中,需要对齐源库和目标库的innodb_large_prefix参数取值,否则可能导致建表失败
  • 在设计数据库表结构的过程中,对于一个可能包含很长字符串的列上创建索引时尽量使用前缀索引

mysql innodb_large_prefix相关推荐

  1. 浅谈uf8mb4字符集

    要在 Mysql 中保存 4 字节长度的 UTF-8 字符,需要使用 utf8mb4 字符集(mb4就是most bytes 4的意思,专门用来兼容四字节的unicode),但只有 5.5.3 版本以 ...

  2. mysql 报错 Specified key was too long; max key length is 767 bytes,开启系统变量:innodb_large_prefix

    mysql 报错 Specified key was too long; max key length is 767 bytes 当mysql数据库的字符集使用了utf8mb4,就很容易在执行建表sq ...

  3. mysql prefix_mysql改变innodb_large_prefix

    我刚刚在VM上设置debian 8.3并在此 Tutorial之后安装了xampp.一切正常,直到我尝试创建一个新表: create table testtable ( id int(10) not ...

  4. MySQL从5.7.32升级到8.0.22

    目录 一.备份与导出数据 二.升级到MySQL-8.0.22同时解决字符集问题 2.1.卸载MySQL-5.7.32 2.2.安装MySQL-8.0.22 2.3.修改配置文件 my.cnf 三.导入 ...

  5. MySQL 5.5 服务器变量详解(二)

    innodb_adaptive_flushing={ON|OFF} 设定是否允许MySQL服务器根据工作负载动态调整刷写InnoDB buffer pool中的脏页的速率.动态调整刷写速率的目的在于避 ...

  6. MySQL 源码 需要 什么基础_MySQL 基础之 源码 部署

    源码部署 1. 需要先卸载一些软件 centos7 中需要先卸载 mariadb-libs 软件包 # rpm -e --nodeps mariadb-libs 2. 安装依赖包 yum -y ins ...

  7. mysql 联合索引长度_MySQL 中索引的长度的限制

    单列索引的长度的限制 (5.6里面默认不能超过767bytes,5.7不超过3072bytes): 起因是256×3-1=767.这个3是字符最大占用空间(utf8).但是在5.5以后,开始支持4个字 ...

  8. mysql windows 管道连接,科技常识:Windows Server 2016 MySQL数据库安装配置详细安装教程...

    今天小编跟大家讲解下有关Windows Server 2016 MySQL数据库安装配置详细安装教程 ,相信小伙伴们对这个话题应该也很关注吧,小编也收集到了有关Windows Server 2016 ...

  9. RDS for MySQL 5.7 备份恢复为本地实例

    RDS for MySQL 5.7 备份恢复为本地实例 1. 本地环境 2. 恢复步骤 3. 后记 近期同学咨询反馈 RDS for MySQL 5.7 备份恢复本地实例的问题比较多,提供一个恢复样例 ...

最新文章

  1. stand up meeting 1/14/2016
  2. 微软企业库4.1学习笔记(六)创建对象
  3. 【鸿蒙 HarmonyOS】UI 组件 ( 多选按钮 | Checkbox 组件 )
  4. 基于weblogic 的EJB 学习笔记-JSP教程,资料/其它
  5. MIT Scheme 使用 Edwin
  6. 工信部:“5G+工业互联网”在建项目全国已超2000余个
  7. 2.python中的矩阵、多维数组----numpy
  8. 付费?广告?捐款?如何让开源软件活下去?
  9. react18并发渲染
  10. 剪映专业版mac版本要求 剪映mac版最新版更新
  11. Delphi之TStrings和TStringLists类[转]
  12. 计算机网络(自顶向下方法)-网络层
  13. 【HTML】HTML浏览器打印自定义页眉页脚
  14. Eplan绘图软件:西门子S7-1500部件
  15. 蒙氏三段卡---马三段卡
  16. GitHub · 如何创建文件夹
  17. 当android调试遇到ADB server didn't ACK以及顽固的sjk_daemon进程 .
  18. telnet连接失败的常见错误
  19. 面试关于jvm、dvm和art虚拟机区别
  20. C语言路漫漫,其修远兮

热门文章

  1. CFG保护机制校验逻辑分析
  2. 桌面录屏软件,分享3个十分便捷的录屏软件
  3. 批量一次性查找并替换多个 Word 文档中的相同的关键字
  4. 程序员工资倒挂,IT行业薪资潜规则如何规避?
  5. 金钱数字转换为大写中文
  6. android app耗电分析方法
  7. 打印等腰三角形图案[1]
  8. 一起Talk Android吧(第五百零七回:图片滤镜ImageFilterView)
  9. 腾讯CEO马化腾:从“抄袭”开始创业之路
  10. 【C语言】强符号和弱符号