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

我知道有很多这方面的问题,但我认为我的math是正确的。

  • 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 

有什么我可以做的呢?

编辑:

事实certificate,限制是250.看起来字符数为4个字节的唯一索引,但我不知道为什么。

编辑2:

感谢Vladislav Vaintroub,charset确实是utf8mb4。 解决了这个谜。 我没有看到这个变化的任何文件。

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

如果您重新input您的评论作为答案,我会很乐意接受。

解决scheme:指定utf8,而不是utf8mb4(MySQLpipe理员不允许这样做,所以手动创build表)

如果您使用的是utf8mb4,并且在长度超过191个字符的varchar列上有唯一索引,则需要打开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文档的原因和未来的信息 :

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

Innodb_large_prefix在MySQL 5.7.7中已被弃用,并将在未来版本中被删除。 innodb_large_prefix是在MySQL 5.5中引入的,用于禁用较大的索引键前缀,以便与不支持较大索引键前缀的较早版本的InnoDB兼容。

总而言之,这个限制只是为了兼容性,在未来的版本中会有所增加。

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

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

MySQL保留为4字节的UTF8字段的最大数量,所以这就是为什么你超过1000字节的限制。 我的build议是创buildvarchar小于255或创build它没有UTF8。

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

我能想到的唯一的另一个解决scheme是将列分成2个小列,并在这两个字段上创build一个唯一的索引,但我相信你会得到与上面相同的错误。

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