执行以下命令时:

ALTER TABLE `mytable` ADD UNIQUE (
`column1` ,
`column2`
);

我得到了这个错误信息:

#1071 - Specified key was too long; max key length is 767 bytes

columnn1和column2的信息:

column1 varchar(20) utf8_general_ci
column2  varchar(500) utf8_general_ci

我认为varchar(20)只需要21个字节,而varchar(500)只需要501个字节。所以总字节数是522,小于767。为什么我得到了错误消息?

#1071 - Specified key was too long; max key length is 767 bytes

当前回答

5解决方法:

在5.7.7中提高了限制(MariaDB 10.2.2?)。并且可以通过5.6(10.1)中的一些工作来增加它。

如果你因为试图使用字符集utf8mb4而达到极限。然后做以下其中一种(每一种都有缺点)来避免错误:

⚈  Upgrade to 5.7.7 for 3072 byte limit -- your cloud may not provide this;
⚈  Change 255 to 191 on the VARCHAR -- you lose any values longer than 191 characters (unlikely?);
⚈  ALTER .. CONVERT TO utf8 -- you lose Emoji and some of Chinese;
⚈  Use a "prefix" index -- you lose some of the performance benefits.
⚈  Or... Stay with older version but perform 4 steps to raise the limit to 3072 bytes:

SET GLOBAL innodb_file_format=Barracuda;
SET GLOBAL innodb_file_per_table=1;
SET GLOBAL innodb_large_prefix=1;
logout & login (to get the global values);
ALTER TABLE tbl ROW_FORMAT=DYNAMIC;  -- (or COMPRESSED)

——http://mysql.rjweb.org/doc.php/limits 767 _limit_in_innodb_indexes

其他回答

您可以添加长列的md5列

我们在尝试使用utf8mb4向VARCHAR(255)字段添加UNIQUE索引时遇到了这个问题。虽然在这里已经很好地概述了这个问题,但我想为我们如何发现并解决它添加一些实际的建议。

当使用utf8mb4时,字符计数为4个字节,而在utf8下,字符计数为3个字节。InnoDB数据库有一个限制,索引只能包含767字节。因此,当使用utf8时,您可以存储255个字符(767/3 = 255),但使用utf8mb4时,您只能存储191个字符(767/4 = 191)。

你完全可以使用utf8mb4为VARCHAR(255)字段添加常规索引,但发生的事情是索引大小自动被截断为191个字符-就像这里的unique_key:

这很好,因为常规索引只是用来帮助MySQL更快地搜索数据。整个字段不需要被索引。

那么,为什么MySQL为常规索引自动截断索引,但抛出一个显式错误时,试图这样做的唯一索引?好吧,为了让MySQL能够判断插入或更新的值是否已经存在,它需要索引整个值,而不仅仅是它的一部分。

最后,如果您想在一个字段上拥有唯一的索引,那么该字段的整个内容必须适合该索引。对于utf8mb4,这意味着将VARCHAR字段长度减少到191个字符或更少。如果这个表或字段不需要utf8mb4,那么可以将其删除回utf8,并能够保留255长度的字段。

您使用的是什么字符编码?有些字符集(如UTF-16等等)每个字符使用一个以上的字节。

好吧,在我的情况下,我必须将数据库文件从mySQL 5.7恢复到mySQL 5.6,我遇到了这个问题。

根本原因是版本不兼容,并且索引的某些列长于191(默认值为255)。

所以解决方案很简单:让所有“索引列的长度”都小于191(例如180)

如果您最近修改了innodb_log_file_size,请尝试恢复之前的值。