MySQL VARCHAR(255)UTF8对于密钥太长,但最大长度为1000字节

时间:2011-05-30 06:05:38

标签: mysql utf8mb4

我知道有很多关于此的问题,但我认为我的数学是正确的。

  • MySQL为每个UTF8字符保留3个字节。
  • MyISAM允许长度为1000字节的密钥。
  • 我的UTF8 VARCHAR(255)255 * 3 = 765字节

除非UNQUE每个条目需要额外的200多个字节,为什么这不起作用?

mysql> ALTER TABLE entry ADD UNIQUE INDEX (name(255));
ERROR 1071 (42000): Specified key was too long; max key length is 1000 bytes

我能做些什么吗?

修改

事实证明,限制是250.对于唯一索引,字符似乎计为4个字节,但我不知道为什么。

编辑2:

感谢Vladislav Vaintroub,charset确实是utf8mb4。这解决了这个谜。我没有看到有关此更改的任何文档。

我猜它通过隐式截断字段来构建非唯一索引,这对于唯一索引是不可接受的,所以它拒绝。

如果您重新输入评论作为答案,我很乐意接受。

解决方案:指定utf8,而不是utf8mb4(MySQL管理员不允许这样做,因此请手动创建表)

3 个答案:

答案 0 :(得分:39)

如果您正在使用utf8mb4,并且varchar列上的唯一索引的长度超过191个字符,那么您需要打开innodb_large_prefix以允许索引中的更大列,因为utf8mb4需要比utf8或latin1更多的存储空间。将以下内容添加到my.cnf文件中。

[mysqld]
innodb_file_format=barracuda
innodb_file_per_table=1
innodb_large_prefix=1
init_connect='SET collation_connection = utf8mb4_unicode_ci'
init_connect='SET NAMES utf8mb4'
character-set-server=utf8mb4
collation-server=utf8mb4_unicode_ci

有关MySQL 5.7 documentation的原因和未来的更多信息:

  

如果启用innodb_large_prefix(MySQL 5.7.7中的默认设置),则为   对于使用的InnoDB表,索引键前缀限制为3072字节   DYNAMIC或COMPRESSED行格式。如果禁用innodb_large_prefix,   对于任何行格式的表,索引键前缀限制为767字节。

     

innodb_large_prefix在MySQL 5.7.7中已弃用,将被删除   在将来的版本中。 innodb_large_prefix是在MySQL 5.5中引入的   禁用大型索引键前缀以与之前的兼容性   不支持大索引键前缀的InnoDB版本。

总而言之,限制仅用于兼容性,并将在未来版本中增加。

答案 1 :(得分:7)

MySQL保留UTF8字段的最大数量,即4字节,这就是为什么你超过了1000字节的限制。我的建议是创建小于255的varchar,或者在没有UTF8的情况下创建它。

这两种解决方案可能都不适合您,或者您已经尝试过了。

我能想到的唯一其他解决方案是将列拆分为2个小列并在这两个字段上创建唯一索引,但我相信您会得到与上面相同的错误。

由于你可能需要UTF8,我会认真考虑将varchar(255)列减少到250(或249)以使其工作。

答案 2 :(得分:7)

任何需要更长密钥长度的人都应该查看innodb_large_prefix

访问http://dev.mysql.com/doc/refman/5.5/en/innodb-parameters.html#sysvar_innodb_large_prefix