如何在mysql中解决"指定密钥太长,最大密钥长度为255字节"?

tus*_*til 7 mysql database innodb my.cnf mysql-5.7

每当我从一个mysql客户端(emma)触发此查询时:

CREATE TABLE `tbl_mappings` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `private_id` int(11) unsigned NOT NULL,
  `name` tinytext NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `name` (`private_id`,`name`(255)),
  KEY `FK_tbl__private_integrations_mappings_tbl__private_integrations` (`private_id`),
  CONSTRAINT `FK_tbl__private_integrations_mappings_tbl__private_integrations` FOREIGN KEY (`private_id`) REFERENCES `tbl__private_integrations` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Run Code Online (Sandbox Code Playgroud)

我得到错误:指定键太长最大键长度是255个字节

我使用的是mysql server 5.7,ubuntu 16.04

我已经尝试在[mysqld]下的my.cnf中添加配置:

innodb_file_format=barracuda
innodb_file_per_table=1
innodb_large_prefix=1
init_connect='SET collation_connection = utf8mb4_unicode_ci'
init_connect='SET NAMES utf8mb4'
character-set-server=utf8mb4
collation-server=utf8mb4_unicode_ci
default-storage-engine=InnoDB
Run Code Online (Sandbox Code Playgroud)

然后重新启动mysql服务.still它不会工作.

任何帮助表示赞赏.谢谢.

spe*_*593 7

编辑

问题似乎与TINYTEXT数据类型有关.(我可以使用InnoDB或MyISAM复制MySQL版本5.7.17-0ubuntu0.16.04.1-log中观察到的行为.)

简短的回答(作为解决方法,如何解决1071警告)是使用数据类型VARCHAR(255)代替TINYTEXT.


我运行了几个具有各种字符集(utf8,utf8mb4,latin1)并使用InnoDB和MyISAM存储引擎的测试用例.1071警告似乎与TINYTEXT列上的索引中指定的前缀长度有关...似乎是对前缀长度的MySQL限制(与InnoDB没有特别关系,因为我可以使用MyISAM复制行为.)I没有使用TINYTEXT以外的任何其他TEXT类型进行测试.


以前的答案

InnoDB表的索引键长度限制为767字节.

name(255)在键定义指定的前255个字符name.使用MySQL utf8字符集,字符可以占用一到三个字节.并且255次三次是765.为int添加四个字节private_id,那是769,超过了最大值.

这就是你得到错误的原因.

解决这个问题的几种方法.

最简单的方法是减少索引中包含的名称字符数,例如

UNIQUE KEY `name` (`private_id`,`name`(254))
Run Code Online (Sandbox Code Playgroud)

如果这不满足您的用例,那么您可能需要考虑使用已弃用的innodb_large_prefix设置.您需要使用DYNAMICCOMPRESSED行格式.请参阅此处的讨论:

https://dev.mysql.com/doc/refman/5.7/en/innodb-restrictions.html

https://dev.mysql.com/doc/refman/5.7/en/innodb-row-format-specification.html

  • 谢谢。将tinytext更改为varchar(255)可以正常工作。 (2认同)