MySQL - 错误 1071、 "specified key was too long..."阻止更改字符集/归类

标签 mysql indexing encoding

我正在尝试将我的一个数据库表从 utf8_general_ci 切换到 utf8mb4。

ALTER TABLE d4b80le1jha CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_bin

这会引发以下错误:

1071 - Specified key was too long; max key length is 1000 bytes

我已经阅读了很多关于此错误消息的答案,但似乎无法解决我的问题。他们中的大多数人都在谈论定义新索引,而不是如何处理现有索引。

我还尝试运行以下命令,如 recommended here , 这没有区别:

SET @@global.innodb_large_prefix = 1;

一个复杂的因素可能是我使用 varchar 散列作为主键。这是我无法控制的遗留功能。我没有为我的索引设置明确的大小 - 我想知道这是否是我应该查看的内容。

表:

Field           Type            Null    Key     Default
-------------------------------------------------------
id              varchar(11)     NO      PRI     NULL    
link            varchar(255)    NO              NULL    
title           varchar(255)    NO              NULL    
description     varchar(255)    YES             NULL    
pubdate         datetime        NO              NULL    
img_url         varchar(255)    YES             NULL    
team_id         varchar(11)     NO      MUL     NULL    
source_id       varchar(11)     NO              NULL    
hits            int(11)         YES             NULL

索引:

Keyname         Type    Unique  Packed  Column      Cardinality Collation   Null
--------------------------------------------------------------------------------
PRIMARY         BTREE   Yes         No  id          13407       A           No
Unique combo    BTREE   Yes         No  team_id                 A           No
                                        source_id               A           No
                                        link        13407       A           No

最佳答案

这可能是你的 Unique combo索引引起麻烦,我的意思是你在 (team_id, source_id, link) 上的索引.该索引的字符总长度为 277,因此它的最大字节总长度是 1108 的四倍。

对此你能做什么?

  • 减少 link 的字符长度列到 228,因此索引的最大字符长度为 250。只要您的值仍然适合,这可能是最简单的。

  • 重新创建索引并提及 link(228)而不仅仅是 link仅索引 link 的前导字符.我不知道这是不是个好主意;索引的目的是定义一个唯一约束。如果您不索引 link 的整个值你并没有完全那样做。

  • 而不是将表中的所有字符列都转换为 utfmb4字符编码,只需转换titledescription列。这可能对你有用。为什么?你的_id哈希可能使用有限的字符集,根本不需要 unicode。你的link列值可能是 URLS,也可以使用有限的 (latin1) 字符集。所以,只是 titledescription可能需要用希伯来语或中文书写或包含表情符号或其他内容。这可能是您的最佳解决方案。

(注意字符编码实际上是逐列指定的。转换整个表格的能力是为了方便而提供的。)

所以你可以这样做

ALTER TABLE d4b80le1jha 
     MODIFY title VARCHAR(255) 
                  CHARACTER SET utf8mb4
                  COLLATE utf8mb4_bin;
ALTER TABLE d4b80le1jha 
     MODIFY description VARCHAR(255) 
                        CHARACTER SET utf8mb4
                        COLLATE utf8mb4_bin;

最后,因为这两列是人类可读的文本,您可能想要使用 utf8mb4_general_ci用于整理这些列而不是 utf8mb4_bin .搜索和订购可能会更好地满足用户的期望。

关于MySQL - 错误 1071、 "specified key was too long..."阻止更改字符集/归类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49095673/

相关文章:

php - 在相关的两个表之间搜索 SQL 问题

C# MYSQL Insert 查询无法更新或添加子行

mysql - 触发以跟踪 MySQL 数据库中的更改

来自索引数组的python numpy数组

ajax - 解决使用ajax发送阿拉伯字符的问题

mysql - 如何在 MySQL Workbench 中编写 pl/sql 或等价物?

MySQL 不使用索引排序

hadoop - 如何使用Solr将文件发送到HDFS

java - java如何有效存储4字节char数组

json - 如何配置 F# JSON 类型提供程序以对 POST 请求使用 UTF-8?