#1071 - 指定的密钥太长;最大密钥长度为 767 字节

Posted

技术标签:

【中文标题】#1071 - 指定的密钥太长;最大密钥长度为 767 字节【英文标题】:#1071 - Specified key was too long; max key length is 767 bytes 【发布时间】:2015-06-22 23:28:20 【问题描述】:

我用这个SQL查询创建表:

CREATE TABLE IF NOT EXISTS `local_sysDB`.`hashtags` (
  `id` INT NOT NULL AUTO_INCREMENT,
  `hashtag` VARCHAR(255) NOT NULL COMMENT 'hashtag must be unique. Must be saved without #',
  `accountId` INT NULL,
  `startTracking` DATETIME NOT NULL COMMENT 'When tracking of the hashtag start',
  `endTracking` DATETIME NOT NULL COMMENT 'When tracking of the hashtag ends',
  `channelInstagram` TINYINT(1) NOT NULL DEFAULT 1,
  `channelTwitter` TINYINT(1) NOT NULL DEFAULT 1,
  `channelYoutube` TINYINT(1) NOT NULL DEFAULT 1,
  `postLimit` INT NOT NULL,
  `suspendOnLimit` TINYINT(1) NOT NULL DEFAULT 1,
  `created` TIMESTAMP NOT NULL DEFAULT NOW(),
  `updated` TIMESTAMP NULL ON UPDATE CURRENT_TIMESTAMP,
  `approveBeforeView` TINYINT(1) NOT NULL DEFAULT 0 COMMENT 'If account should approve posts before being displayed public',
  `suspended` TINYINT(1) NOT NULL DEFAULT 0,
  `InstagramSubscriptionId` INT(10) UNSIGNED NULL,
  `deleted` TINYINT(1) NULL DEFAULT 0 COMMENT 'if hashtag is marked for deletion',
  `collectedPosts` BIGINT(50) UNSIGNED NULL DEFAULT 0,
  PRIMARY KEY (`id`),
  UNIQUE INDEX `hashtags_hashtag` (`hashtag` ASC)  KEY_BLOCK_SIZE=255,
  INDEX `hashtags_accounts_accountId` (`accountId` ASC),
  INDEX `hashtag_trackingDate` (`startTracking` ASC, `endTracking` ASC),
  INDEX `hashtag_collectedPosts` (`collectedPosts` ASC),
  INDEX `hashtag_updated` (`updated` ASC),
  FULLTEXT INDEX `hashtag_search` (`hashtag` ASC),
  CONSTRAINT `hashtags_accounts_accountId`
    FOREIGN KEY (`accountId`)
    REFERENCES `local_sysDB`.`accounts` (`id`)
    ON DELETE CASCADE
    ON UPDATE CASCADE)
ENGINE = InnoDB
ROW_FORMAT = COMPRESSED
KEY_BLOCK_SIZE = 16;

当我尝试运行它时,我收到以下错误:

SQL 查询:

CREATE TABLE IF NOT EXISTS `local_sysDB`.`hashtags` (
  `id` INT NOT NULL AUTO_INCREMENT,
  `hashtag` VARCHAR(255) NOT NULL COMMENT 'hashtag must be unique. Must be saved without #',
  `accountId` INT NULL,
  `startTracking` DATETIME NOT NULL COMMENT 'When tracking of the hashtag start',
  `endTracking` DATETIME NOT NULL COMMENT 'When tracking of the hashtag ends',
  `channelInstagram` TINYINT(1) NOT NULL DEFAULT 1,
  `channelTwitter` TINYINT(1) NOT NULL DEFAULT 1,
  `channelYoutube` TINYINT(1) NOT NULL DEFAULT 1,
  `postLimit` INT NOT NULL,
  `suspendOnLimit` TINYINT(1) NOT NULL DEFAULT 1,
  `created` TIMESTAMP NOT NULL DEFAULT NOW(),
  `updated` TIMESTAMP NULL ON UPDATE CURRENT_TIMESTAMP,
  `approveBeforeView` TINYINT(1) NOT NULL DEFAULT 0 COMMENT 'If account should approve posts before being displayed public',
  `suspended` TINYINT(1) NOT NULL DEFAULT 0,
  `InstagramSubscriptionId` INT(10) UNSIGNED NULL,
  `deleted` TINYINT(1) NULL DEFAULT 0 COMMENT 'if hashtag is [...]

mysql 融合:文档

我已经发现它与this有关:

767 字节是 InnoDB 表的规定前缀限制 - 它的 MyISAM 表的长度为 1,000 字节。

根据这个issue的回复,可以拿到申请key 通过指定列的子集而不是整个数量。 即:

ALTER TABLE mytable 添加唯一 (column1(15), column2(200));调整 因为您需要获得申请的钥匙,但我想知道这是否值得 它会检查您有关此实体的数据模型,以查看是否存在 允许您实施预期业务的改进 没有达到 MySQL 限制的规则。

我尝试为索引添加长度,但 MySQL Workbench 不断将它们重置为 0。 我想知道这个问题是否有其他原因,或者解决这个问题的其他方法。

【问题讨论】:

(1) 使用mysql 命令行界面,(2) 针对 Workbench 编写错误报告 -- bugs.mysql.com。 你使用的是 utf8mb4 吗?如果不是,那么哪个 INDEX 给出了错误? @RickJames 是的,我正在使用utf8mb4 【参考方案1】:

我刚刚学到了一种解决方法...获取 5.5.14 或 5.6.3(或更高版本),执行此处指示的 SET,并使用 DYNAMIC 或 COMPRESSED:

SET GLOBAL innodb_file_per_table = ON,
           innodb_file_format = Barracuda,
           innodb_large_prefix = ON;
CREATE TABLE so29676724 (
  `id` INT NOT NULL AUTO_INCREMENT,
  `hashtag` VARCHAR(255) NOT NULL COMMENT 'hashtag must be unique. Must be saved without #',
   PRIMARY KEY (`id`),
  UNIQUE INDEX `hashtags_hashtag` (`hashtag` ASC)
)
ENGINE = InnoDB
DEFAULT CHARACTER SET  utf8mb4
ROW_FORMAT = COMPRESSED;

SHOW CREATE TABLE so29676724\G

mysql> CREATE TABLE so29676724 (
    ->   `id` INT NOT NULL AUTO_INCREMENT,
    ->   `hashtag` VARCHAR(255) NOT NULL COMMENT 'hashtag must be unique. Must be saved without #',
    ->    PRIMARY KEY (`id`),
    ->   UNIQUE INDEX `hashtags_hashtag` (`hashtag` ASC)
    -> )
    -> ENGINE = InnoDB
    -> DEFAULT CHARACTER SET  utf8mb4
    -> ROW_FORMAT = COMPRESSED;
Query OK, 0 rows affected (0.09 sec)

【讨论】:

@RostD - 更新版本可能不够,也可能不够。 5.7 更改默认值;这可能不会过滤到任何现有表中。【参考方案2】:

“哈希”通常是十六进制,而不是 UTF-8。哈希通常比 255 短得多。

如果其中任何一个适用,那么...

`hashtag`
       VARCHAR(160)           -- this
       CHARACTER SET ascii    -- and/or this

这将是一个适用于任何版本的解决方案,无需指定任何 innodb 设置。

(注意:191 是 VARCHARutf8mb4 的截止值,但很少有标准哈希需要这么多。)

【讨论】:

以上是关于#1071 - 指定的密钥太长;最大密钥长度为 767 字节的主要内容,如果未能解决你的问题,请参考以下文章

#1071 - 指定的密钥太长;最大密钥长度为 767 字节

语法错误或访问冲突:1071 指定的密钥太长;最大密钥长度为 767 字节 [重复]

错误:#1071 - 指定的密钥太长;最大密钥长度为 1000 字节 - mysql 5.0.91

1071 - 指定的密钥太长;最大密钥长度为 1000 字节 [重复]

php 语法错误或访问冲突:1071指定密钥太长;最大密钥长度为767字节

SQL 错误 #1071 - 指定的键太长;最大密钥长度为 767 字节