mysql唯一索引 负面_Mysql唯一索引线上故障记录

本文记录了一次因手动修改MySQL表中唯一索引字段导致的自增键冲突问题。当尝试插入数据时,由于已存在的sort值,系统报错1062。解决方法是删除并重新创建sort的唯一索引。这次经历提醒我们,尽量避免手动修改唯一索引字段,并在修改后正确重建索引。
摘要由CSDN通过智能技术生成

问题现象:

Mysql插入一条数据时,未指定自增键的值却报错:自增键重复,无法插入!

执行SQL

INSERT INTO `test`.`test_sort`(`id`, `name`, `age`, `birthday`) VALUES

(10027, '测试', 23, '2020-01-07 12:23:11')

报错:

INSERT INTO `test`.`test_sort`(`id`, `name`, `age`, `birthday`) VALUES

(10027, '测试', 23, '2020-01-07 12:23:11')

> 1062 - Duplicate entry '38' for key 'sort'

> 时间: 0.001s

表的创建语句:

CREATE TABLE `test_sort` (

`id` int(11) NOT NULL COMMENT '主键',

`name` varchar(24) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '姓名',

`age` tinyint(3) UNSIGNED NULL DEFAULT NULL COMMENT '年龄',

`birthday` datetime(0) NULL DEFAULT NULL COMMENT '生日',

`sort` int(11) NOT NULL AUTO_INCREMENT COMMENT '序号',

PRIMARY KEY (`id`) USING BTREE,

UNIQUE INDEX `sort`(`sort`) USING BTREE

) ENGINE = InnoDB AUTO_INCREMENT = 39 CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic;

这里可以发现,sort字段在表中是自增键,通过唯一索引 sort 来实现,而我在插入新行的时候没有指定 sort 字段的值,那么它理论上会采用当前自增 B-Tree 上最大数字 + 1,这里却提示他冲突了。

问题还原

表里面原来的数据如下:

INSERT INTO `test_sort` VALUES (10001, '张三', 23, '2020-01-07 12:23:11', 1);

INSERT INTO `test_sort` VALUES (10002, '王五', 23, '2020-01-07 12:23:11', 9);

INSERT INTO `test_sort` VALUES (10003, '赵六', 23, '2020-01-07 12:23:11', 10);

INSERT INTO `test_sort` VALUES (10004, '钱七', 23, '2020-01-07 12:23:11', 11);

INSERT INTO `test_sort` VALUES (10005, '刘八', 23, '2020-01-07 12:23:11', 12);

INSERT INTO `test_sort` VALUES (10006, '冯九', 23, '2020-01-07 12:23:11', 13);

INSERT INTO `test_sort` VALUES (10007, '李四', 23, '2020-01-07 12:23:11', 44);

INSERT INTO `test_sort` VALUES (10008, '李四1', 23, '2020-01-07 12:23:11', 36);

INSERT INTO `test_sort` VALUES (10009, '王五1', 23, '2020-01-07 12:23:11', 38);

INSERT INTO `test_sort` VALUES (10010, '赵六1', 23, '2020-01-07 12:23:11', 40);

INSERT INTO `test_sort` VALUES (10011, '钱七1', 23, '2020-01-07 12:23:11', 41);

INSERT INTO `test_sort` VALUES (10012, '刘八1', 23, '2020-01-07 12:23:11', 46);

INSERT INTO `test_sort` VALUES (10013, '冯九1', 23, '2020-01-07 12:23:11', 47);

INSERT INTO `test_sort` VALUES (10014, '李四1', 23, '2020-01-07 12:23:11', 48);

INSERT INTO `test_sort` VALUES (10015, '王五1', 23, '2020-01-07 12:23:11', 21);

INSERT INTO `test_sort` VALUES (10016, '赵六1', 23, '2020-01-07 12:23:11', 22);

INSERT INTO `test_sort` VALUES (10017, '钱七1', 23, '2020-01-07 12:23:11', 23);

INSERT INTO `test_sort` VALUES (10018, '刘八1', 23, '2020-01-07 12:23:11', 24);

INSERT INTO `test_sort` VALUES (10019, '冯九1', 23, '2020-01-07 12:23:11', 25);

INSERT INTO `test_sort` VALUES (10021, '测试', 23, '2020-01-07 12:23:11', 28);

INSERT INTO `test_sort` VALUES (10022, '测试', 23, '2020-01-07 12:23:11', 30);

INSERT INTO `test_sort` VALUES (10023, '测试', 23, '2020-01-07 12:23:11', 32);

INSERT INTO `test_sort` VALUES (10024, '测试', 23, '2020-01-07 12:23:11', 33);

INSERT INTO `test_sort` VALUES (10025, '测试', 23, '2020-01-07 12:23:11', 34);

INSERT INTO `test_sort` VALUES (10026, '测试', 23, '2020-01-07 12:23:11', 37);

这里在数据插入时,我通过 Navicat 手动修改了表中 sort 字段的值,改成一个比原来最大值。此时再重新添加数据,当自增键的值增长到该值时,就会报该错误。

解决方法

删除原来用于自增的唯一索引 sort,然后重新创建该索引。记得删除后点保存,之后添加索引,保存

bc6a6029a846dc8a6575c6b68dd2bbfe.png

删除时出现该提示是因为自增长必须依赖索引存在,索引应该先去掉该键的自增长功能。在重新添加索引后打开该功能

受《高性能Mysql》的启发

fed33bb1e58dbe24a4d80ec7c8923ac3.png

4c81ffe267b46cdd9c87aa23a33c5f20.png

这本书里面有句:通过一个不做任何操作的 ALTER 操作来重建表。而我们的删除-重新添加操作和他有异曲同工之妙。

启发

这次问题给我带来的启发如下,也请同行们参考

不到万不得已不要手动去修改数据库的唯一索引字段

如果修改了,修改之后通过删除 + 重新添加索引的方式避免线上服务出错

书中自有黄金屋,如果不是之前读过自增键、索引相关的知识,遇到此事便不能及时解决,可能会造成无法挽回的损失,书到用时方恨少...

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值