Specified key was too long; max key length is 1000 bytes
问题描述
MySQL建表的时候,执行建表语句(如下),报错Specified key was too long; max key length is 1000 bytes,只知道字段超长了,字段类型使用的utf8mb4,经过一番搜索思考才得以解决。
建表语句
CREATE TABLE `sys_quartz_job` (
`id` VARCHAR(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`create_by` VARCHAR(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '创建人',
`create_time` DATETIME(0) NULL DEFAULT NULL COMMENT '创建时间',
`del_flag` INT(1) NULL DEFAULT NULL COMMENT '删除状态',
`update_by` VARCHAR(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '修改人',
`update_time` DATETIME(0) NULL DEFAULT NULL COMMENT '修改时间',
`job_class_name` VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '任务类名',
`cron_expression` VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT 'cron表达式',
`parameter` VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '参数',
`description` VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '描述',
`status` INT(1) NULL DEFAULT NULL COMMENT '状态 0正常 -1停止',
PRIMARY KEY (`id`) USING BTREE,
UNIQUE INDEX `uniq_job_class_name`(`job_class_name`) USING BTREE
) ENGINE = MYISAM CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = DYNAMIC;
报错截图
问题分析及解决
问题分析
经搜索得知MySQL单列索引最大长度为1000字节,不同的版本,不同的引擎最大长度有所不同,这点要注意;
问题解决
上表中job_class_name字段的长度为255,而采用utf8mb4编码的字节数为255 * 4 大于1000,因此报错;我将字段长度改为160则可以正常执行;
拓展分析
建立索引时,数据库计算key的长度是累加所有Index用到的字段的char长度后再按下面比例乘起来不能超过限定的key长度1000:
latin1 = 1 byte = 1 character
uft8mb4 = 4 byte = 1 character
uft8 = 3 byte = 1 character
gbk = 2 byte = 1 character
举例能看得更明白些,以GBK为例:
CREATE UNIQUE INDEX unique_record
ON reports (report_name
, report_client
, report_city
);
其中report_name varchar(200), report_client varchar(200), report_city varchar(200)
(200 + 200 +200) * 2 = 1200 > 1000,所有就会报1071错误,只要将report_city改为varchar(100)那么索引就能成功建立。
如果表是UTF8字符集,那索引还是建立不了。
正文到此结束