MySQL 如何处理重复数据问题

背景

最近运维同学反馈了一条慢查询的问题。研究完表结构后,发现是缺少索引。
看完了代码逻辑,发现这张表需要添加唯一索引。本想直接添加一个唯一索引解决问题。
但是,表中的数据已经存在重复数据。直接添加索引添加不成功。
常规思维,是去除掉重复数据,然后再添加唯一索引。

问题描述

如何去除表中重复数据?

解决办法

方法一:添加唯一索引

ALTER IGNORE TABLE `tbl_like_work` ADD UNIQUE INDEX `uk_tian`(`user_id`, `work_id`)

需要注意SQL语句中使用了 IGNORE 关键字,若不添加此关键字,则添加唯一索引会失败。

若添加索引成功,则自动会去除重复数据。

IGNORE is a MySQL extension to standard SQL. It controls how ALTER TABLE works if there are duplicates on unique keys in the new table or if warnings occur when strict mode is enabled. If IGNORE is not specified, the copy is aborted and rolled back if duplicate-key errors occur. If IGNORE is specified, only one row is used of rows with duplicates on a unique key. The other conflicting rows are deleted. Incorrect values are truncated to the closest matching acceptable value.

As of MySQL 5.7.4, the IGNORE clause for ALTER TABLE is removed and its use produces an error.

方法二:使用临时表

对于 MySQL 5.7.4 是不支持 INSERT IGNORE的。可以使用临时表完成数据去重。
通过使用临时表,备份数据。然后给原表添加唯一索引,再将临时表中的数据导入到原表,得到去重表。

整个流程如下:

  1. 使用临时表备份数据。根据原表创建临时表
  2. 清掉原表数据
  3. 给原表添加唯一索引
  4. 将临时表数据插入到原表,插入时忽略重复数据(使用 IGNORE 关键字)
  5. 删除临时数据
CREATE TABLE tmp_data SELECT * FROM mytable;
TRUNCATE TABLE mytable;
ALTER TABLE mytable ADD UNIQUE INDEX myindex (A, B, C, D);
INSERT IGNORE INTO mytable SELECT * from tmp_data;
DROP TABLE tmp_data;

方法三:删除重复数据

如果需要删除重复数据,必须找到重复数据。

如何查找重复数据

SELECT *, count(*) as total
FROM `tbl_like_work` 
GROUP BY user_id,work_id
HAVING total > 1

删除重复数据

DELETE tbl_like_work
WHERE `id` not in (
    SELECT min(id)  # 保留最旧的数据
    FROM  `tbl_like_work` 
    GROUP BY user_id,work_id
)

总结

需要注意的是,方法二会更改原表的主键ID,对于有主键依赖的业务。不能使用第二种方法。
建议使用方法一、方法三,只删除重复数据,且不会对原数据做出修改。

参考资料

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • pyspark.sql模块 模块上下文 Spark SQL和DataFrames的重要类: pyspark.sql...
    mpro阅读 9,495评论 0 13
  • 手动不易,转发请注明出处 --Trance 数据库系统命令: (1).查看存储过程状态:show pro...
    Trance_b54c阅读 1,693评论 0 8
  • --- layout: post title: "如果有人问你关系型数据库的原理,叫他看这篇文章(转)" date...
    蓝坠星阅读 813评论 0 3
  • SQL SERVER提供了多种索引。如果以存储结构结构来区分,有聚集索引和非聚集索引;如果以数据的唯一性来区分,则...
    不知名的蛋挞阅读 6,044评论 0 5
  • 本文主要总结了工作中一些常用的操作及不合理的操作,在对慢查询进行优化时收集的一些有用的资料和信息,本文适合有MyS...
    Chting阅读 613评论 0 1