执行以下命令时:

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

当前回答

这解决了我的问题

ALTER DATABASE dbname CHARACTER SET utf8 COLLATE

其他回答

更改排序规则。您可以使用支持几乎所有功能的utf8_general_ci

将抱怨索引字段的CHARSET更改为“latin1” 例如:ALTER TABLE tbl CHANGE myfield varchar(600) CHARACTER SET latin1 DEFAULT NULL Latin1为一个字符使用一个字节,而不是四个

我解决了这个问题:

varchar(200) 

取而代之的是

varchar(191)

所有超过200的唯一或主varchar键将它们替换为191或将它们设置为文本。

我们在尝试使用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长度的字段。

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

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

否则sequelize将创建utf8mb4表。