执行以下命令时:

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

当前回答

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

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

其他回答

关于为什么你会得到错误消息的答案已经被很多用户回答了。我的答案是如何修复和使用它。

从这个链接中查阅。

打开MySQL客户端(或MariaDB客户端)。它是一个命令行工具。 它会问你的密码,输入正确的密码。 使用以下命令选择您的数据库:

数据库修改

设置全局innodb_large_prefix=on;

查询OK, 0行受影响(0.00秒)

set global innodb_file_format=Barracuda;

查询OK, 0行受影响(0.02秒)

去phpMyAdmin或类似的数据库,以便于管理。>选择数据库>查看表结构>进入“操作”页签。>将ROW_FORMAT更改为DYNAMIC并保存更改。 进入表的结构选项卡>单击唯一按钮。 完成了。现在应该没有错误了。

这个修复的问题是,如果你导出数据库到另一个服务器(例如从本地主机到真实主机),你不能在该服务器上使用MySQL命令行。你不能让它在那里工作。

MySQL对字符串中每个字符的字节数假设最坏的情况。对于MySQL 'utf8'编码,每个字符是3个字节,因为该编码不允许字符超过U+FFFF。对于MySQL 'utf8mb4'编码,它是每个字符4字节,因为这是MySQL所谓的实际UTF-8。

因此,假设您使用'utf8',那么您的第一列将占用索引的60字节,第二列将占用索引的1500字节。

我对这个相同问题的修复是添加一个选项作为第三个参数:charset

queryInterface.createTable(
  tableName,
  { /*... columns*/ },
  { charset: 'utf8' } 
)

否则sequelize将创建utf8mb4表。

您可以添加长列的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长度的字段。