指定的密钥太长;最大密钥长度为 767 字节

Posted

技术标签:

【中文标题】指定的密钥太长;最大密钥长度为 767 字节【英文标题】:Specified key was too long; max key length is 767 bytes 【发布时间】:2016-04-15 11:24:51 【问题描述】:

我了解 InnoDB 索引的最大长度为 767 字节。

CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `email` varchar(254) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
  .....
  `token` varchar(128) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
  `rank` int(11) NOT NULL,
  PRIMARY KEY (`id`),
  KEY `user_token_index` (`token`),
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

我想在我的电子邮件上创建一个索引。

alter table agent add UNIQUE index idx_on_email (email);

但收到错误消息:

但是 token 列的长度只有 128 字节,email 是 254 字节,没有超过 767 字节。希望任何人都可以帮助我!提前致谢!

【问题讨论】:

#1071 - Specified key was too long; max key length is 767 bytes的可能重复 254 是 字符。如果您使用的是CHARACTER SET utf8mb4,则需要乘以 4 才能得到 bytes 【参考方案1】:

varchar(254) 当你使用utf8mb4时,表示254个字符,每个字符有4个字节,email字段至少需要1016 bytes (254 * 4)。 你可以看看这篇文章: http://wildlyinaccurate.com/mysql-specified-key-was-too-long-max-key-length-is-767-bytes/ 所以你可以让你的电子邮件列:varchar(100)

【讨论】:

191 是utf8mb4 的上限,估计是他用的那个。 注意自 MySQL 5.7.7 以来有一个 innodb_large_prefix option(默认为 true),它允许最多 3072 个字节的键(utf8mb4 为 768 个字符)。换句话说,较新的 MySQL 版本没有这种限制。【参考方案2】:

另一种选择是重新评估存储在该表中的数据的性质和约束,以及它们与 JOIN 中其他数据的关系,然后证明是否需要 utf8mb4 的字符集和排序规则。

示例:如果存储和/或与其他数据进行比较的数据永远不会有超过 2 个字节的特殊字符,您可以分别用 utf8 和 utf8_general_ci 替换 charset 和 collat​​ion(或替代)。对于 ascii,您可能会更短。

无论如何,这项评估/证明工作是一种很好的做法,并且可能会免费带来应计的绩效。

【讨论】:

以上是关于指定的密钥太长;最大密钥长度为 767 字节的主要内容,如果未能解决你的问题,请参考以下文章

#1071 - 指定的密钥太长;最大密钥长度为 767 字节

语法错误或访问冲突:1071 指定的密钥太长;最大密钥长度为 767 字节 [重复]

指定的密钥太长;实体框架 6 中的最大密钥长度为 767 字节 Mysql 错误

SQL 错误 #1071 - 指定的键太长;最大密钥长度为 767 字节

php 语法错误或访问冲突:1071指定密钥太长;最大密钥长度为767字节

laravel migration 指定的key太长;最大密钥长度为 767 字节 [重复]