解决Mysql中删除重复记录的问题

1、相同记录的由来

以Mysql为例,根据表的设计原则,表中不可能存在两条完全相同的记录。


第一范式(1NF):字段值具有原子性,不能再分(所有关系型数据库系统都满足第一范式);

例如:姓名字段,其中姓和名是一个整体,如果区分姓和名那么必须设立两个独立字段;


第二范式(2NF):一个表必须有主键,即每行数据都能被唯一的区分;  

(备注:必须先满足第一范式;)


第三范式(3NF):一个表中不能包涵其他相关表中非关键字段的信息,即数据表不能有沉余字段;( 备注:必须先满足第二范式;)

1

2

3

4

5

6

7

但是,在我们实际的业务系统中,很大可能会存在,除了主键外,剩余列完全相同或部分核心字段完全相同的数据在同一个库表中存在。


举例,如下截图所示:

解决Mysql中删除重复记录的问题

该表中,主键为第1列ID和第2列Wid,两行数据的仅更新日期和标记列(2,3)不同,剩余列完全相同。

随着记录的增多,我们检索的需要,仅需要将Mid相同的记录保留住更新日期最新的一条记录。


2、如何仅保留最新日期的一条记录,删除其余日期较早的相同Wid的记录?

以下是删除操作sql的分解操作步骤。


步骤1:找出重复的记录。

select wid from   search_dispos_copy group by wid having count(wid) > 1;

1

步骤2:找出重复记录中,区分标志字段的最大值。

select max(update_time) from   search_dispos_copy group by article_id having count(wid )>1;

1

步骤3:查询出重复记录的ID信息。

select id, wid, update_time from search_dispos_copy

where wid in (select wid from search_dispos_copy group by wid having count(wid) > 1)

and update_time not in (select max(update_time) from search_dispos_copy group by wid having count(wid )>1);

order by wid;

1

2

3

4

步骤4:删除对应的ID记录。

整理出id信息,以逗号分隔,id是唯一值


1)删除空行操作

sed -i ‘/^$/d’ ./id_list.txt


2)换行符转化为逗号

cat id_list.txt | tr “\n” “,” > id_list_a.txt


3)删除操作

delete from msearch_dispose_articles_copy where id in ();

()里面放入4.2中 list_a存储的记录即可。


3、讨论

为了标注一条记录的状态,设计的时候我们会关联库表中的一条记录。但这条记录在库表中是唯一的,标注状态的改变体现在表中是相同记录行的某一特征列的改变。

因此,我们要做的是更新记录,而不是再次插入操作。

这样,也就避免了出现1中的“相同记录”。

上一篇:MySql-Proxy之多路结果集归并


下一篇:Docker技术入门与实战(第2版)3.3 搜寻镜像