Mysql::Error: 指定的键太长;最大键长度为1000字节。

28
script/generate acts_as_taggable_on_migration
rake db:migrate

原因

Mysql::Error: Specified key was too long; max key length is 1000 bytes: CREATE  INDEX `index_taggings_on_taggable_id_and_taggable_type_and_context` ON `taggings` (`taggable_id`, `taggable_type`, `context`)

我该怎么办?

这是我的数据库编码:

mysql> SHOW VARIABLES LIKE 'character\_set\_%';
+--------------------------+--------+
| Variable_name            | Value  |
+--------------------------+--------+
| character_set_client     | latin1 | 
| character_set_connection | latin1 | 
| character_set_database   | utf8   | 
| character_set_filesystem | binary | 
| character_set_results    | latin1 | 
| character_set_server     | latin1 | 
| character_set_system     | utf8   | 
+--------------------------+--------+
7 rows in set (0.00 sec)

请先提供更多信息。正在迁移什么? - Pekka
http://github.com/mbleigh/acts-as-taggable-on - amaseuk
http://github.com/mbleigh/acts-as-taggable-on/blob/master/generators/acts_as_taggable_on_migration/templates/migration.rb - amaseuk
1
这里有一个类似的问题 http://community.engineyard.com/discussions/problems/420-database-index-problems ,它已经得到解决,但不知道具体是怎么解决的。 - amaseuk
767问题的修复:http://mysql.rjweb.org/doc.php/limits#767_limit_in_innodb_indexes - Rick James
如果涉及到Java Hibernate,请参考答案https://stackoverflow.com/a/76016256/9370144 - Nadun Kulatunge
4个回答

56

这仅仅是一个MySQL问题 -

MySQL有不同的引擎 - MyISAM、InnoDB、Memory等。

MySQL对于在列上定义索引时可以使用的空间有不同的限制 - 对于MyISAM是1,000字节; 对于InnoDB是767字节。并且这些列的数据类型也很重要 - 对于VARCHAR类型,它的值是3倍的,因此在VARCHAR(100)上的索引将占用300个字节(因为100个字符* 3 = 300)。

当您达到上限时,为了容纳某些索引,您可以根据列数据类型的部分定义索引:

CREATE INDEX example_idx ON YOUR_TABLE(your_column(50))

假设 your_column 的类型为 VARCHAR(100),那么上面的例子中的索引只针对前50个字符。搜索超过第50个字符的数据将无法使用该索引。


2
你知道一种MySQL引擎类型不会导致上述错误吗? - amaseuk
6
通过将默认引擎从MyISAM更改为InnoDB来解决。谢谢。 - amaseuk
3
通过将默认引擎从MyISAM更改为InnoDB进行解决。虽然InnoDB的限制确实较短,但这是可行的。 - Stijn de Witt
听起来不可能,但是对我来说将MyISAM改为InnoDB也起了作用。WAMP,Win10。 - Howdy_McGee

4

如果这个错误发生在像迁移这样的某些过程中,可以通过更改MySql(*.ini)的配置文件来解决。

default-storage-engine=InnoDB

3

看起来这好像是一个在这里报告的错误:http://bugs.mysql.com/bug.php?id=4541

如果你已经尝试了所有这篇文章中的答案,但仍然遇到错误,你可能想尝试在SQL查询窗口中运行此命令。

set GLOBAL storage_engine='InnoDb';

2
未知的系统变量 'storage_engine'。自 MySQL 5.7 起不再起作用。 - astroanu
storage_engine 系统变量在 MySQL 8.0 中已被移除,这就是为什么你会收到“Unknown system variable”错误的原因。 要设置 MySQL 8.0 及更高版本中新创建表格的默认存储引擎,可以使用 default_storage_engine 系统变量而非 storage_engine,并使用以下命令实现此目的。SET GLOBAL default_storage_engine = 'InnoDB'; - Asad Khan
如果涉及到Java Hibernate,请参考答案https://stackoverflow.com/a/76016256/9370144 - Nadun Kulatunge

0

我认为你的一个字段是varchar类型,长度超过了1000个字符。例如:context?

考虑索引的含义。当所有索引字段都在where子句中时,它可以快速访问一行。如果索引太长(在mysql的情况下超过1000字节),使用索引就没有意义,因为它可能比使用全表扫描访问整个表更慢。

我建议缩短索引,例如缩短到taggable_id和taggable_type,如果这两个字段都较短。

祝好 - Gerhard


你好,这是一个常见的Rails插件/宝石,我在互联网上没有看到过这个错误信息 - 不确定是迁移文件还是我的数据库需要修改...? - amaseuk
你正在使用哪个 MySql 版本?是当前版本还是 Mysql 4.x? - BitKFu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接