【问题标题】:What is causing MySQL error 1071 (key too long) in this case?在这种情况下,是什么导致 MySQL 错误 1071(密钥太长)?
【发布时间】:2018-11-15 19:18:18
【问题描述】:

我有一个用utf8mb4 编码的下表:

CREATE TABLE IF NOT EXISTS `account` (
  `id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
  `customer_id` INT UNSIGNED NOT NULL,
  `name` VARCHAR(45) NOT NULL,
  `username` VARCHAR(254) NOT NULL,
  `password` CHAR(60) NOT NULL,
  PRIMARY KEY (`id`),
  INDEX `fk_table1_customer_idx` (`customer_id` ASC),
  UNIQUE INDEX `unique_account` (`customer_id` ASC, `username` ASC),
  CONSTRAINT `fk_table1_customer`
    FOREIGN KEY (`customer_id`)
    REFERENCES `customer` (`id`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)
ENGINE = InnoDB
ROW_FORMAT = DYNAMIC;

我需要向它添加一个布尔列,所以这就是我要做的:

ALTER TABLE `account` 
    ADD COLUMN `is_customer_admin`
        INT(4) NOT NULL DEFAULT 0
        AFTER `customer_id`;

我还尝试专门添加 BOOLEAN 列而不是 INT(4)

但是,我得到了错误:

ERROR 1071 (42000):指定的密钥太长;最大密钥长度为 767 字节

这是我第一次遇到这样的错误。我确实发现了有关该特定错误的一些问题,但是,我自己无法将其应用于我的情况。

来自this question 我知道username 可能太长了,但是我不明白他们最初是如何创建该表的。我的查询没有触及该字段。

【问题讨论】:

标签: mysql mariadb


【解决方案1】:

在较旧的 MySQL / MariaDB 版本中,允许的最大键(索引)长度仅为 767 字节。来自Docs

默认情况下,索引键前缀长度限制为 767 字节。例如,您可能会在 TEXT 或 VARCHAR 列上的列前缀索引超过 255 个字符时达到此限制,假设使用 utf8mb3 字符集并且每个字符最多 3 个字节。启用 innodb_large_prefix 配置选项后,对于使用 DYNAMIC 或 COMPRESSED 行格式的 InnoDB 表,索引键前缀长度限制将提高到 3072 字节。

现在,您的问题进一步增加,因为您使用的是utf8mb4 字符集。这意味着每个字符 4 个字节(不是 3 个字节)。

`username` VARCHAR(254)

这意味着254 * 4 = 1016 字节,这肯定超出了限制。您需要减少为username 列指定的最大字符数。

此外,以下约束没有多大意义,因为customer_id 已经是主键。

UNIQUE INDEX `unique_account` (`customer_id` ASC, `username` ASC)

你也可以摆脱它。

【讨论】:

  • 谢谢。我不认为已经存在的列会阻止进一步的更改...
猜你喜欢
  • 2021-08-15
  • 1970-01-01
  • 2012-05-25
  • 2020-11-10
  • 2017-03-13
  • 1970-01-01
  • 2011-02-26
  • 2018-12-22
  • 2016-10-04
相关资源
最近更新 更多