在这种情况下是什么导致MySQL错误1071(密钥太长)?

时间:2018-11-15 19:18:18

标签: mysql mariadb

我有一个用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)

但是,我得到了错误:

  

错误1071(42000):指定的密钥太长;无法更改。最大密钥长度为767   字节

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

this question中我了解到username可能太长,但是我不明白他们是如何首先创建该表的。我的查询没有涉及该字段。

1 个答案:

答案 0 :(得分:0)

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

  

默认情况下,索引键前缀长度限制为767个字节。例如,假设utf8mb3字符集且每个字符最多3个字节,则在TEXT或VARCHAR列上使用超过255个字符的列前缀索引可能会达到此限制。启用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)

您也可以摆脱它。