在MySQL中,当你尝试执行插入(INSERT
)或更新(UPDATE
)操作时,如果目标表中存在唯一索引(包括主键索引、唯一约束索引等),并且你要插入或更新的数据在该索引列上的值与表中已有的值重复,这时就会触发“Duplicate entry”错误。
具体来说,以下几种情况会导致“Duplicate entry”错误:
- 主键索引重复:尝试插入的记录的主键值与表中已有的主键值相同。
- 唯一索引重复:如果表中有一个或多个列被定义为具有唯一约束的唯一索引,而你尝试插入的数据在这些列上的值与现有记录冲突,也会触发错误。
- 复合唯一索引重复:当一个索引包含多个列,称为复合索引,并且定义为唯一时,只有当这些列的值组合完全相同时才视为重复。如果插入的数据在这些列的值组合上与现有记录匹配,也会报错。
- 插入或更新操作触发的唯一性检查失败:在执行
INSERT
或UPDATE
时,即使你没有直接修改唯一索引列,但如果操作间接导致了唯一性约束被违背(比如,更新其他列触发了唯一索引列的级联更新),同样会遇到“Duplicate entry”。
建表:
CREATE TABLE `ent_test` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '自增主建',
`pripid` char(32) NOT NULL COMMENT '主体身份代码',
`ent_name` varchar(200) NOT NULL DEFAULT '' COMMENT '企业名称',
`ent_code` char(18) NOT NULL DEFAULT '' COMMENT '统一社会信用代码',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '时间戳',
PRIMARY KEY (`id`),
UNIQUE KEY `idx_pripid` (`pripid`),
UNIQUE KEY `idx_ent_code_ent_name` (`ent_code`,`ent_name`),
KEY `idx_ent_code` (`ent_code`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 COMMENT='主体表'
INSERT INTO ent_test (id, pripid, ent_name, ent_code, create_time, update_at) VALUES (1, '111', '企业1', 'A', '2024-06-08 07:06:04', '2024-06-08 07:19:29');
INSERT INTO ent_test (id, pripid, ent_name, ent_code, create_time, update_at) VALUES (2, '222', '企业2', 'B', '2024-06-08 07:06:04', '2024-06-08 07:19:29');
INSERT INTO ent_test (id, pripid, ent_name, ent_code, create_time, update_at) VALUES (3, '333', '企业3', 'C', '2024-06-08 07:10:21', '2024-06-08 07:19:29');
测试数据:
主键索引
# [23000][1062] Duplicate entry '1' for key 'PRIMARY'
insert into ent_test(id,pripid,ent_name,ent_code) values (1,'4','企业4','D')
唯一键索引
# [23000][1062] Duplicate entry '111' for key 'idx_pripid'
insert into ent_test(id,pripid,ent_name,ent_code) values (4,'111','企业4','D')
复合索引
# [23000][1062] Duplicate entry 'A-企业1' for key 'idx_ent_code_ent_name'
insert into ent_test(id,pripid,ent_name,ent_code) values (4,'444','企业1','A')
加入ignore,只有最后一条数据没有触发索引报错
insert ignore into ent_test(id,pripid,ent_name,ent_code) values (1,'4','企业4','D');
insert ignore into ent_test(id,pripid,ent_name,ent_code) values (4,'444','企业1','A');
insert ignore into ent_test(id,pripid,ent_name,ent_code) values (4,'444','企业2','A');