1. 铺垫
在实际生产过程中有很多种原因会导致MySQL中包含着重复的元素,比如下面这三种:
- 导数据过程中
- openfeign, rabbitMQ的重试机制
- 分布式下并发插入的问题
这些重复数据往往id不同其他键值相同或者相近。在这个场景下需要去除重复数据应该怎么做?
2. 使用原生MySQL
对于任意一个数据库,想要删除重复数据,是不是应该先查询出来重复的数据(获取id),然后再根据id来删除重复数据😁
为了模拟场景,给出一个学生表:
CREATE TABLE t_student (
id INT AUTO_INCREMENT PRIMARY KEY COMMENT '主键ID',
stu_id INT NOT NULL UNIQUE COMMENT '学生ID,唯一标识',
name VARCHAR(15) NOT NULL COMMENT '学生姓名',
age INT COMMENT '学生年龄',
phone VARCHAR(15) COMMENT '学生电话',
grade INT COMMENT '学生年级',
parent_info INT COMMENT '家长信息外键',
create_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间'
) COMMENT='学生信息表';
#插入数据,重复如下
-- 张三 - 4
-- 李四 - 2
-- 王五 - 2
-- 赵六 - 1
INSERT INTO t_student (stu_id, name, age, phone, grade, parent_info) VALUES
(1001, '张三', 15, '13800138001', 9, 1),
(1002, '李四', 14, '13900139001', 8, 6),
(1003, '张三', 15, '13800138002', 9, 2),
(1004, '张三', 15, '13800138003', 9, 3),
(1005, '王五', 16, '13700137001', 10, 7),
(1006, '赵六', 13, '13600136001', 7, 8),
(1007, '王五', 16, '13400134001', 6, 10);
(1008, '李四', 15, '13800138004', 8, 6),
(1009, '张三', 15, '13800138005', 9, 5);
2.1 根据唯一键值查询重复数据
# 假设name不允许重复,实际生产中替换需求
SELECT `name`, COUNT(name) FROM t_student GROUP BY `name` HAVING COUNT(name) > 1;
2.2 封装结果获取到完整数据
# 假设name不允许重复,实际生产中替换需求
SELECT * FROM t_student WHERE name IN (
SELECT `name` FROM t_student GROUP BY `name` HAVING COUNT(name) > 1
);
2.3 重复全删
# 假设name不允许重复,实际生产中替换需求
DELETE FROM t_student WHERE name IN (
SELECT t.name FROM (
SELECT `name` FROM t_student GROUP BY `name` HAVING COUNT(name) > 1
) t;
);
2.4 根据唯一id删除(保留最早的id)
# 假设name不允许重复,实际生产中替换需求
DELETE FROM t_student WHERE id NOT IN (
SELECT t.id FROM (
SELECT MIN(id) AS id FROM t_student GROUP BY `name`
) t;
);
174万+

被折叠的 条评论
为什么被折叠?



