MySQL的报错信息有时可能和大家预期的不一样,本文将根据实际案例演示最常见的唯一索引报错与预期情况有差异,不了解的同学可能以为有bug。
1. 数据准备
1.1 创建一个含唯一索引的表
代码语言:javascript复制-- 创建一张test表
CREATE TABLE test (
id INT PRIMARY KEY AUTO_INCREMENT,
c1 VARCHAR (31),
c2 VARCHAR (32),
c3 VARCHAR (8),
c4 INT,
UNIQUE KEY uq_c1_c2_c3 (c1, c2, c3)
);
1.2 插入一批数据
代码语言:javascript复制insert into `test` (`id`, `c1`, `c2`, `c3`, `c4`) values('1','90806443B5534D33B652929F5205E4F','5b612c194383488fad19e2889cf077f5','202204','1000000');
insert into `test` (`id`, `c1`, `c2`, `c3`, `c4`) values('2','988806443B5534D33B652929F5205E4','077f55b612c194383488fad19e2889cf','202205','2000000');
insert into `test` (`id`, `c1`, `c2`, `c3`, `c4`) values('3','988806443B5534D33B652929F5205E','5b612c194383488fad19e2889cf077f5','202204','1000000');
1.3 插入一条唯一索引冲突的数据
代码语言:javascript复制INSERT INTO `test` (`id`, `c1`, `c2`, `c3`, `c4`) VALUES('4','90806443B5534D33B652929F5205E4F','5b612c194383488fad19e2889cf077f5','202204',200000);
报错信息如下:
代码语言:javascript复制错误代码:1062
Duplicate entry '90806443B5534D33B652929F5205E4F-5b612c194383488fad19e2889cf077f5'
for key 'uq_c1_c2_c3'
报错信息中只有c1(90806443B5534D33B652929F5205E4F)和c2(5b612c194383488fad19e2889cf077f5)的值,无c3(202204)的值,有时如果批量插入过多的行时,无法快速定位哪一行冲突,不便于快速排查问题。
2. 原因探索
从报错信息中可以发现,c1、c2、'-'连接符总长度为64个字符,可以从源码着手。
在源码 errmsg-utf8 文件中,可以发现有如下信息:
代码语言:javascript复制eng "Duplicate entry '%-.64s' for key '%-.192s'"
也就是,报错信息中内容的有64个字符,key的名字为192个字符,至此揭开了谜底。