MariaDB 10.1.38 - 指定的键太长;最大密钥长度为 767 字节

Ema*_*nes 10 mysql mariadb index

我有一个包含 3 列的表:

id(int 11)  | user_id(int 4) | title(varchar 512) 
____________|________________|___________________
     1      |        3       | Thing X
     2      |        3       | Something Else
     3      |        5       | Thing X
Run Code Online (Sandbox Code Playgroud)

我需要在user_id和之间进行独特的组合title。为此,我正在使用这个简单的查询:

ALTER TABLE posts ADD UNIQUE `unique_post`(`user_id`, `title`)
Run Code Online (Sandbox Code Playgroud)

title列的字符集是utf8mb4_unicode_ci. 数据库是使用字符集创建的utf8mb4

CREATE DATABASE learning_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
Run Code Online (Sandbox Code Playgroud)

表类型是InnoDB.

我试图设置一些全局变量:

SET GLOBAL innodb_file_format=Barracuda;
SET GLOBAL innodb_file_per_table=on;
SET GLOBAL innodb_large_prefix=on;
Run Code Online (Sandbox Code Playgroud)

但我遇到了同样的错误1071

Specified key was too long; max key length is 767 bytes
Run Code Online (Sandbox Code Playgroud)

还有什么我可以做的吗?

PS:如果我只设置索引的第一个191字符,title我不会得到那个错误:

ALTER TABLE posts ADD UNIQUE `unique_post`(`user_id`, `title`(191))
Run Code Online (Sandbox Code Playgroud)

...但我有与同一用户相关的头衔,可能仅在最后一个字母上有所不同(考虑到我的字符集,也就是最后 4 个字节)

PSS:我在本地主机上(使用 xampp)。

Ema*_*nes 17

好的,经过一个周末的研究,答案非常简单,我将把它留在这里给面临同样问题的其他人。

这个答案在 MariaDB 10.1.38、db charset utf8mb4、table typeInnoDB和 table charset 上进行了测试utf8mb4_unicode_ci

在 [mysqld] 之后打开my.ini并添加以下行(如果它们已经存在,只需编辑之后的所有内容=):

innodb_file_format = Barracuda
innodb_file_per_table = on
innodb_default_row_format = dynamic
innodb_large_prefix = 1
innodb_file_format_max = Barracuda
Run Code Online (Sandbox Code Playgroud)

您还可以通过 cmd/终端设置它们:

在 Windows 上 - 如果您的 XAMPP 位于c:\xampp\

打开一个 cmd 并导航到mysql's bin - 在这种情况下:

cd c:\xampp\mysql\bin
Run Code Online (Sandbox Code Playgroud)

认证:

mysql -h localhost -u root
Run Code Online (Sandbox Code Playgroud)

通过身份验证后,运行此查询(一次一个):

SET GLOBAL innodb_file_format = Barracuda;
SET GLOBAL innodb_file_per_table = on;
SET GLOBAL innodb_default_row_format = dynamic;
SET GLOBAL innodb_large_prefix = 1;
SET GLOBAL innodb_file_format_max = Barracuda;
Run Code Online (Sandbox Code Playgroud)

但我建议坚持编辑 my.ini(或 .cnf),因为如果您要查询,您的选项可能会在每次重新启动 Apache 时重写。

您可以阅读有关InnoDB存储格式的更多信息:here

此外,这篇文章非常有趣,可以帮助您在varchars创建之前优化您的breed unique keyshere

  • 您应该将自己的答案标记为正确 - 这样它会在搜索中更加突出,并且更有可能帮助其他人解决相同的问题!+1 顺便说一句! (2认同)
  • 我必须删除 `innodb_default_row_format =dynamic` 行,否则 MariaDB 将无法在 CentOs 上启动。但即使没有这个选项,我也摆脱了错误。 (2认同)