最近工作很忙,很久没写博客,嘻嘻!今天写一遍关于MySQL重复数据处理的博客!前不久有个开发问我,能不能把重复的数据去除,留下唯一的数据。然后我问他为什么有这么重复的数据呢,他说写了程序去爬数据,爬到很多重复的。我擦,你就不能添加主键或者唯一键保证行数据的唯一性吗?表或结果集有时含有重复记录,有时它是允许的,但有时它被要求停止使用重复记录。有时,需要识别重复记录并从表中删除它们,下面我们举几个小例子说明下。

需求:

1、向一张表里插入数据,如果行数据存在就不插入,当行数据不存在就插入

2、删除一个表里出现相同的行记录

一、向一个表插入数据,表没有主键和唯一键的情况下,可以插入重复数据,而且不会报错:

mysql> show create table  user\G
*************************** 1. row ***************************
Table: user
Create Table: CREATE TABLE `user` (
`first_name` char(20) DEFAULT NULL,
`code` char(20) DEFAULT NULL,
`sex` char(10) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec) mysql>

往表里插入数据,可以插入大量的重复数据而且不会报错:

mysql> insert into user values ('aa','GZ','M');
Query OK, 1 row affected (0.05 sec) mysql> insert into user values ('aa','GZ','M');
Query OK, 1 row affected (0.04 sec) mysql> select * from user;
+------------+------+------+
| first_name | code | sex |
+------------+------+------+
| aa | GZ | M |
| aa | GZ | M |
+------------+------+------+
2 rows in set (0.00 sec) mysql>

为了防止表中被创建的多个记录具有相同的值,添加一个主键(PRIMARY KEY)到它的定义。 当要做这一点,也必须声明索引列是NOT NULL,因为PRIMARY KEY不允许NULL值:

mysql> show create table user\G
*************************** 1. row ***************************
Table: user
Create Table: CREATE TABLE `user` (
`first_name` char(20) NOT NULL DEFAULT '',
`code` char(20) NOT NULL DEFAULT '',
`sex` char(10) DEFAULT NULL,
PRIMARY KEY (`first_name`,`code`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec) mysql>

如果插入一条与现有记录重复到表,在列或定义索引列,表中一个唯一索引的存在通常会导致错误的发生:

mysql> insert into user values ('aa','GZ','M');
Query OK, 1 row affected (0.04 sec) mysql> insert into user values ('aa','GZ','M');
ERROR 1062 (23000): Duplicate entry 'aa-GZ' for key 'PRIMARY'
mysql>

可以看到了吧,报错了,如果是执行一个sql脚本,报错就可能退出脚本了,后面的SQL语句就不会执行了,当然你可以加上 -f 参数。但报错的提示总是让人感觉到不安,哈哈,我们可以用INSERT IGNORE和REPLACE INTO去插入数据,朋友友可以通过HELP INSERT 和 HELP REPLACE去了解下用法,这里不作过多的说明

mysql> select * from user;
+------------+------+------+
| first_name | code | sex |
+------------+------+------+
| aa | GZ | M |
+------------+------+------+
1 row in set (0.00 sec) mysql> insert ignore user values ('aa','GZ','M');
Query OK, 0 rows affected (0.00 sec) mysql>

可以看到用INSERT IGNORE的语法插入就没报错了,如果记录与现有现有不重复时,MySQL将其正常插入。如果记录是一个重复的,则 IGNORE 关键字告诉MySQL丢弃它而不会产生错误。

我们再来看看用REPLACE INTO的效果:

mysql> replace into user values ('aa','GZ','M');
Query OK, 1 row affected (0.05 sec) mysql> select * from user;
+------------+------+------+
| first_name | code | sex |
+------------+------+------+
| aa | GZ | M |
+------------+------+------+
1 row in set (0.00 sec)

可以看到没报错,使用REPLACE,如果记录是新的,它插入就像使用INSERT。如果它是重复的,新的记录将取代旧的记录。

INSERT IGNORE和REPLACE应根据实现的重复处理行为来选择。INSERT忽略保持第一套重复记录,并丢弃剩下的。REPLACE保持最后一组重复的和擦除任何较早的记录。

二、从查询结果消除重记录

方法一:

mysql> show create table user2\G
*************************** 1. row ***************************
Table: user2
Create Table: CREATE TABLE `user2` (
`first_name` char(20) DEFAULT NULL,
`code` char(20) DEFAULT NULL,
`sex` char(10) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec) mysql>

往表里插入相当数据做测试:

mysql> insert into user2 values ('bb','BJ','N');
Query OK, 1 row affected (0.03 sec) mysql> insert into user2 values ('bb','BJ','N');
Query OK, 1 row affected (0.02 sec) mysql> insert into user2 values ('cc','SH','M');
Query OK, 1 row affected (0.03 sec) mysql> insert into user2 values ('cc','SH','M');
Query OK, 1 row affected (0.03 sec)

我们可以从查询的结果中消除相同的记录:

mysql> SELECT DISTINCT first_name,code FROM user2 ORDER BY first_name;
+------------+------+
| first_name | code |
+------------+------+
| bb | BJ |
| cc | SH |
+------------+------+
2 rows in set (0.00 sec) mysql>

替代DISTINCT方法是添加GROUP BY子句列名称到选择的列。这有删除重复并选择在指定的列值的唯一组合的效果:

mysql> CREATE TABLE tmp SELECT first_name,code,sex FROM user2 GROUP BY (first_name,code);
ERROR 1786 (HY000): CREATE TABLE ... SELECT is forbidden when ENFORCE_GTID_CONSISTENCY = 1.
mysql> show variables like 'ENFORCE_GTID_CONSISTENCY';
+--------------------------+-------+
| Variable_name | Value |
+--------------------------+-------+
| enforce_gtid_consistency | ON |
+--------------------------+-------+
1 row in set (0.00 sec)

如果开了GTID复制的,这样的执行就会报错,所以要关了GTID复制的几个参数才可以,这变量只能修改配置文件才能生效,不支持在线修改,修改后重启再试试:

mysql> SELECT first_name,code,sex FROM user2 ;
+------------+------+------+
| first_name | code | sex |
+------------+------+------+
| bb | BJ | N |
| bb | BJ | N |
| cc | SH | M |
| cc | SH | M |
+------------+------+------+
4 rows in set (0.00 sec)
mysql> CREATE TABLE tmp SELECT first_name,code,sex FROM user2 GROUP BY first_name,code;
Query OK, 2 rows affected (0.44 sec)
Records: 2 Duplicates: 0 Warnings: 0 mysql>

可以看到可以创建表并且插入数据了。把原来的表DROP掉,再把临时表修改名字为之前的表名:

mysql> drop table user2;
Query OK, 0 rows affected (0.12 sec) mysql> rename table tmp to user2;
Query OK, 0 rows affected (0.13 sec) mysql> select * from user2;
+------------+------+------+
| first_name | code | sex |
+------------+------+------+
| bb | BJ | N |
| cc | SH | M |
+------------+------+------+
2 rows in set (0.00 sec) mysql>

方法二:

从表中删除重复记录的一个简单的方法就添加索引(INDEX) 或 主键(PRIMAY KEY)到该表。即使该表已经提供,可以使用此技术来删除重复的记录

mysql> SELECT * FROM user2;
+------------+------+------+
| first_name | code | sex |
+------------+------+------+
| bb | BJ | N |
| cc | SH | M |
| bb | BJ | N |
| cc | SH | M |
+------------+------+------+
4 rows in set (0.00 sec) mysql> ALTER IGNORE TABLE user2 ADD PRIMARY KEY (first_name,code);
Query OK, 4 rows affected (1.22 sec)
Records: 4 Duplicates: 2 Warnings: 0 mysql> SELECT * FROM user2;
+------------+------+------+
| first_name | code | sex |
+------------+------+------+
| bb | BJ | N |
| cc | SH | M |
+------------+------+------+
2 rows in set (0.00 sec) mysql>

总结:

   一、可以用INSERT IGNORE和REPLACE实现重复行数据处理,另一种方法是强制唯一性是增加唯一(UNIQUE)索引,而不是一个主键(PRIMARY KEY)来实现数据的唯一。

   二、通过CREATE TABLE tmp SELECT xx的方式来来创建表,要关闭GTID复制才能执行,如果线上的主从复制是基于GTID的,只能用添加索引(INDEX)或主键(PRIMAY KEY)到该表去消除相同的行记录了。

三、这些需求在现实生活中肯定会有的,所以希望大家多测试,分享更多的想法

作者:陆炫志

出处:xuanzhi的博客 http://www.cnblogs.com/xuanzhi201111

您的支持是对博主最大的鼓励,感谢您的认真阅读。本文版权归作者所有,欢迎转载,但请保留该声明。

MySQL重复数据处理的更多相关文章

  1. 删除MySQL重复数据

    删除MySQL重复数据 项目背景 在最近做的一个linux性能采集项目中,发现线程的程序入库很慢,再仔细定位,发现数据库里面很多冗余数据.因为在采集中,对于同一台设备,同一个时间点应该只有一个数据,然 ...

  2. 避免MySQL出现重复数据处理方法

    对于常规的MySQL数据表中可能存在重复的数据,有些情况是允许重复数据的存在,有些情况是不允许的,这个时候我们就需要查找并删除这些重复数据,以下是具体的处理方法! 方法一:防止表中出现重复数据 当表中 ...

  3. mysql重复索引、冗余索引、未使用索引的定义和查找

    1.冗余和重复索引 mysql允许在相同列上创建多个索引,无论是有意还是无意,mysql需要单独维护重复的索引,并且优化器在优化查询的时候也需要逐个地进行考虑,这会影响性能.重复索引是指的在相同的列上 ...

  4. mysql 重复数据防止插入:)

    insert into table (id, name, age) values(1, "A", 19) on duplicate key update name=values(n ...

  5. MySql重复查询

    MYSQL查询重复记录的方法很多,下面就为您介绍几种最常用的MYSQL查询重复记录的方法,希望对您学习MYSQL查询重复记录方面能有所帮助. 1.查找表中多余的重复记录,重复记录是根据单个字段(peo ...

  6. mysql重复数据查询

    假设有表test mysql> select * from test; +----+------+------+ | id | name | sex | +----+------+------+ ...

  7. mysql重复记录的查询删除方法

    1.查找表中多余的重复记录,重复记录是根据单个字段(peopleId)来判断select * from peoplewhere peopleId in (select   peopleId from  ...

  8. mysql重复start stop slave测试

    如题,测试重复start slave, stop slave是否会有报错. 版本 5.7.21 重复start slave测试 第一次start >start slave; Query OK, ...

  9. mysql海量数据处理步骤

    本文转自https://segmentfault.com/a/1190000006158186 当MySQL单表记录数过大时,增删改查性能都会急剧下降,可以参考以下步骤来优化: 单表优化 除非单表数据 ...

随机推荐

  1. Grafana的基本使用

    Grafana的基本使用 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 简单的来说,Grafana 是基于JS开发的,功能齐全的度量仪表盘和图形编辑器,帮助开发人员发现问题的工具. ...

  2. 创建 elasticsearch 用户

    创建 elasticsearch 用户 groupadd -g 3048 elasticsearch useradd -s /sbin/nologin -u 3048 -g elasticsearch ...

  3. ECharts图表引用json数据

    来讲两个图表,一个折线图,一个饼图. 先来看看效果图: 现在来看看代码,先来折线图,后台: (这里的后台太麻烦了,写的太多.可以使用Linq的方式,Linq比较简单写的也少.参考我的这篇文章的2018 ...

  4. mysql -- 动态获取结果集(重点)

    注意:语句传值的时候必须是带有@符号的参数,不能是自己的局部变量,一个@叫用户变量,两个@叫做全局变量.用户变量:当前用户的‘’全局变量‘’,用户状态存在时就存在,用户退出时消失. 初始版 delim ...

  5. Study 8 —— 行块元素及定位

    行&块元素display:inline;display:block;display:inline-block; 盒模型padding[内边距]padding: 上下内边距 左右内边距;padd ...

  6. 转--python 编码规范

    编程规范 1.1. 命名规范 1.1.1. [强制] 命名不能以下划线或美元符号开始和结尾 反例: name / __name / $Object / name / name$ / Object$ 1 ...

  7. webstorm常用功能FTP,及常用快捷键

    常用的FTP功能截图如下: 打开配置窗口 常用配置选项,填好FTP登录信息后点 Test FTP 测试一下,(测试之前,这里选“被动模式”) 默认选哪个FTP上传 注意这里的路径是开发后的上传和访问路 ...

  8. [NOIP2012提高]借教室 题解(二分答案+差分)

    [NOIP2012提高&洛谷P1083]借教室 Description 在大学期间,经常需要租借教室.大到院系举办活动,小到学习小组自习讨论,都需要向学校申请借教室.教室的大小功能不同,借教室 ...

  9. [BJWC2011]最小三角形(分治+最近点对)

    题面:BJWC2011 最小三角形 \(solution:\) 昨天才学完平面最近点对,今天就要求平面最近的三个点,显然不是巧合. 仔细一思考,我们用来求平面最近点对的方法不就可以用到三个点上吗? 就 ...

  10. [转]Linux/Windows下脚本对拍程序

    [新]简单写法 (转载自:https://blog.csdn.net/ylsoi/article/details/79824655) 要求:文件输入输出,且输入输出文件需要对应 Linux: #inc ...