执行以下命令时:

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

当前回答

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

其他回答

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

根据下面给出的列,这两个变量字符串列使用utf8_general_ci排序规则(隐含utf8字符集)。

在MySQL中,utf8字符集每个字符最多使用3个字节。因此,它需要分配500*3=1500字节,这比MySQL允许的767字节要大得多。这就是为什么您会得到1071错误。

换句话说,您需要基于字符集的字节表示来计算字符数,因为并非每个字符集都是一个字节表示(正如您所假设的那样)。例如,MySQL中的utf8每个字符最多使用3个字节,767/3≈255个字符,而对于utf8mb4,最多使用4个字节表示,767/4≈191个字符。

众所周知,MySQL

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

在MySQL 5.6(以及之前的版本)中,767字节是InnoDB表的前缀限制。MyISAM表有1000字节长。在MySQL版本5.7(及以上)中,此限制已增加到3072字节。

您还必须注意,如果在utf8mb4编码的大char或varchar字段上设置索引,则必须将最大索引前缀长度767字节(或3072字节)除以4,结果为191。这是因为utf8mb4字符的最大长度是4个字节。对于utf8字符,它将是三个字节,导致最大索引前缀长度为255(或减去空结束符,254个字符)。

一个选择是在VARCHAR字段上设置下限。

另一种选择(根据对这个问题的响应)是获取列的子集,而不是整个数量,即:

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

根据需要进行调整以获得要应用的键,但我想知道是否值得检查关于这个实体的数据模型,看看是否有可能进行改进,从而允许您在不触及MySQL限制的情况下实现预期的业务规则。

对我来说,#1071 -指定键太长了;通过限制列大小200来改变主键/唯一键组合后,最大键长度是767字节”得到了解决。

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

我从varchar变成了nvarchar,对我有用。