执行以下命令时:

ALTER TABLE `mytable` ADD UNIQUE (
`column1` ,
`column2`
);

我得到了这个错误信息:

#1071 - Specified key was too long; max key length is 767 bytes

columnn1和column2的信息:

column1 varchar(20) utf8_general_ci
column2  varchar(500) utf8_general_ci

我认为varchar(20)只需要21个字节,而varchar(500)只需要501个字节。所以总字节数是522,小于767。为什么我得到了错误消息?

#1071 - Specified key was too long; max key length is 767 bytes

当前回答

对我来说,#1071 -指定键太长了;通过限制列大小200来改变主键/唯一键组合后,最大键长度是767字节”得到了解决。

ALTER TABLE `mytable` ADD UNIQUE (
`column1` (200) ,
`column2` (200)
);

其他回答

5解决方法:

在5.7.7中提高了限制(MariaDB 10.2.2?)。并且可以通过5.6(10.1)中的一些工作来增加它。

如果你因为试图使用字符集utf8mb4而达到极限。然后做以下其中一种(每一种都有缺点)来避免错误:

⚈  Upgrade to 5.7.7 for 3072 byte limit -- your cloud may not provide this;
⚈  Change 255 to 191 on the VARCHAR -- you lose any values longer than 191 characters (unlikely?);
⚈  ALTER .. CONVERT TO utf8 -- you lose Emoji and some of Chinese;
⚈  Use a "prefix" index -- you lose some of the performance benefits.
⚈  Or... Stay with older version but perform 4 steps to raise the limit to 3072 bytes:

SET GLOBAL innodb_file_format=Barracuda;
SET GLOBAL innodb_file_per_table=1;
SET GLOBAL innodb_large_prefix=1;
logout & login (to get the global values);
ALTER TABLE tbl ROW_FORMAT=DYNAMIC;  -- (or COMPRESSED)

——http://mysql.rjweb.org/doc.php/limits 767 _limit_in_innodb_indexes

这个问题

MySQL中有最大键长度限制。

InnoDB -最大密钥长度为1536字节(8kb页面大小)和768字节(4kb页面大小)(来源:Dev.MySQL.com) MyISAM -最大密钥长度是1000字节(来源Dev.MySQL.com)。

这些都是以字节为单位计算的!因此,一个UTF-8字符可能需要一个以上的字节才能存储到密钥中。

因此,你只有两个直接的解决方案:

只索引文本类型的前n个字符。 创建一个全文搜索-所有内容都可以在文本中搜索,以一种类似ElasticSearch的方式

索引文本类型的前N个字符

如果您正在创建一个表,请使用以下语法来索引某些字段的前255个字符:KEY sometextkey (SomeText(255))。像这样:

CREATE TABLE `MyTable` (
    `id` int(11) NOT NULL auto_increment,
    `SomeText` TEXT NOT NULL,
    PRIMARY KEY  (`id`),
    KEY `sometextkey` (`SomeText`(255))
);

如果你已经有了这个表,那么你可以用add unique (ConfigValue(20));为一个字段添加一个唯一键。像这样:

ALTER TABLE
MyTable
ADD UNIQUE(`ConfigValue`(20));

如果字段名不是保留的MySQL关键字,则在字段名周围不需要反引号(' ' ')。

创建全文搜索

全文搜索将允许您搜索文本字段的全部值。如果你使用自然语言模式,它会进行全词匹配,如果你使用其他模式之一,它会进行部分词匹配。查看更多关于全文本的选项:Dev.MySQL.com

创建您的文本表,并添加全文索引…

ALTER TABLE
        MyTable
ADD FULLTEXT INDEX
        `SomeTextKey` (`SomeTextField` DESC);

然后像这样搜索你的桌子……

SELECT
        MyTable.id, MyTable.Title,
MATCH
        (MyTable.Text)
AGAINST
        ('foobar' IN NATURAL LANGUAGE MODE) AS score
FROM
        MyTable
HAVING
        score > 0
ORDER BY
        score DESC;

如果你要创建如下内容:

CREATE TABLE IF NOT EXISTS your_table (
  id int(7) UNSIGNED NOT NULL AUTO_INCREMENT,
  name varchar(256) COLLATE utf8mb4_bin NOT NULL,
  PRIMARY KEY (id),
  UNIQUE KEY name (name)
) ENGINE=INNODB DEFAULT CHARSET=utf8mb4 AUTO_INCREMENT=1 ROW_FORMAT=FIXED;

应该是这样的

CREATE TABLE IF NOT EXISTS your_table (
      id int(7) UNSIGNED NOT NULL AUTO_INCREMENT,
      name varchar(256) COLLATE utf8mb4_bin NOT NULL,
      PRIMARY KEY (id)
    ) ENGINE=INNODB DEFAULT CHARSET=utf8mb4 AUTO_INCREMENT=1 ROW_FORMAT=FIXED;

但是您需要从代码中检查该列的唯一性,或者添加一个新列作为varchar列的MD5或SHA1

在导入文件中用utf8替换utf8mb4。

但请注意,utf8字符集已弃用,它不支持所有的Unicode字符,例如表情符号,所以如果这样做,您将失去对Unicode的完全支持。

我在这个话题上做了一些搜索,最后得到了一些自定义更改

MySQL工作台6.3.7版本有图形界面

启动Workbench并选择连接。 转到管理或实例并选择选项文件。 如果Workbench要求您允许读取配置文件,然后按OK两次。 在中心位置的管理员选项文件窗口出现。 进入InnoDB选项卡,如果在General部分没有检查innodb_large_prefix。 设置innodb_default_row_format选项值为DYNAMIC。

对于6.3.7以下的版本,直接选项不可用,因此需要使用命令提示符

Start CMD as administrator. Go To director where mysql server is install Most of cases its at "C:\Program Files\MySQL\MySQL Server 5.7\bin" so command is "cd \" "cd Program Files\MySQL\MySQL Server 5.7\bin". Now Run command mysql -u userName -p databasescheema Now it asked for password of respective user. Provide password and enter into mysql prompt. We have to set some global settings enter the below commands one by one set global innodb_large_prefix=on; set global innodb_file_format=barracuda; set global innodb_file_per_table=true; Now at the last we have to alter the ROW_FORMAT of required table by default its COMPACT we have to set it to DYNAMIC. use following command alter table table_name ROW_FORMAT=DYNAMIC; Done