错误复现
创建如下一张表:
create table `mytable` (
id bigint primary key not null auto_increment,
column1 varchar(255),
column2 varchar(255)
) engine Innodb charset utf8;
并执行如下的创建复合索引的语句:
alter table `mytable` add unique (`column1`, `column2`);
会得到如下的错误:
18:18:51 alter table `mytable` add unique (`column1`, `column2`)
Error Code: 1071. Specified key was too long; max key length is 767 bytes 0.125 sec
意思是指定的索太张了,超过最大索引大小767B的限制了。
原因
在MySQL 5.6及之前的版本,使用InnoDB作引擎的表的索引大小要小于767B,对于MyISAM的限制则是1000B。在MySQL5.7之后此限制扩展到了3027B
如果你设置的一个varchar字段使用的是utf8mb4字符集,那么索引最多可以存储 767 / 4 = 191个这样的字符。因为utf8mb4的字符每个占4B的存储空间,如果varchar使用utf8字符集,那么索引最多可以存储767 / 3 = 254个这样的字符。因为使用utf8存储的字符占3B的存储空间
解决办法
减少索引列的长度
alter table `mytable` change column column1 column1 varchar(20), change column column2 column2 varchar(20);
截取列的一部分作为索引,而不是全部
alter table `mytable` add unique (`column1`(15), `column2`(15));