我使用 google could sql(mysql)作为我的生产数据库。为了在 docker 中复制此数据库进行测试,我使用了 mysql:8 映像。
我注意到我的一个迁移脚本在云数据库上成功了,但在测试期间失败了。以下脚本导致错误:
CREATE TABLE testTable
(
name varchar(1000)
);
CREATE INDEX idx_device_designs_name ON testTable (name);
错误:Specified key was too long; max key length is 3072 bytes [Failed SQL: (1071)...
我了解错误的原因,但由于我们的标准生产数据库没有产生该错误,所以我正在寻找禁用此检查的设置。
编辑1:
SELECT VERSION();
-> 8.0.31-谷歌
SHOW CREATE TABLE tableName
生产
CREATE TABLE `testTable` (
`name` varchar(1000) COLLATE utf8mb3_unicode_ci NOT NULL,
KEY `idx_device_designs_name` (`name`),
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci
docker 容器
CREATE TABLE `testTable` (
`name` varchar(1000) CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
生产已经在过去应用了索引(在mysql更新之前,所以是5.7)。
SHOW TABLE STATUS LIKE 'testTable'
(生产中)
testTable,InnoDB,10,Dynamic,2,8192,16384,0,32768,0,3,2024-11-14 08:52:26,,,utf8mb3_unicode_ci,,"",""
在MySQL中,没有控制索引键前缀长度限制的设置。InnoDB限制
有一些解决方法,与表的行格式、字符集、索引等有关......
如果你运行以下创建语句语法并验证表的创建,你会看到 name 列没有定义字符集,并且采用表的字符集和排序规则
utf8mb4
(每个字符最多占用 4 个字节,1000 × 4 = 4000 字节,超过了 3072 字节的限制)并给出错误在生产环境中,
InnoDB
允许索引键大小为 3072 字节utf8mb3
,这意味着索引 1000 个字符的列(1000 × 3 = 3000 字节)在限制范围内如果您使用与生产服务器相同的语法,则不会出现任何错误
查看示例
在MySQL 5.7中,对于使用 REDUNDANT 或 COMPACT 行格式的 InnoDB 表,索引键前缀长度限制为 767 字节。例如,假设字符集为 utf8mb3,每个字符的最大长度为 3 个字节,则 TEXT 或 VARCHAR 列上的列前缀索引长度超过 255 个字符时,可能会达到此限制。
此项检查由
SET [SESSION|GLOBAL] innodb_strict_mode=ON;
当设置为
ON
某些 InnoDB 引擎时,警告将变成错误并阻止某些操作。受该选项影响的功能的详细描述可在此处找到:https ://dev.mysql.com/doc/refman/8.4/en/innodb-parameters.html#sysvar_innodb_strict_mode如果设置为
OFF
InnoDB,仍将仅使用前 3072 个字节进行索引,但错误将变成无害的警告。