MySQL中 replace into是否像预期样:若表中有已经存在的数据,则把已经存在的数据删除,插入新数据?

准备数据


CREATE TABLE `test_replace` ( 
  `id` int(11) NOT NULL AUTO_INCREMENT, 
  `str1` char(10) DEFAULT NULL, 
  `str2` char(10) DEFAULT NULL, 
  PRIMARY KEY (`id`), 
  UNIQUE KEY `uqx_str` (`str1`) 
) ENGINE=InnoDB; insert into test_replace(id,str1,str2) values(2,1234,'aaabbbb'),(4,123456,'bbbbxxxx'); select * from test_replace; 
+----+--------+----------+ 
| id | str1   | str2     | 
+----+--------+----------+ 
|  2 | 1234   | aaabbbb  | 
|  4 | 123456 | bbbbxxxx | 
+----+--------+----------+ 
2 rows in set (0.00 sec)

replace into时存在主键冲突


replace into test_replace(id,str1,str2) values(2,'xxxx','yyy'); 
Query OK, 2 rows affected (0.00 sec) select * from test_replace; 
+----+--------+----------+ 
| id | str1   | str2     | 
+----+--------+----------+ 
|  2 | xxxx   | yyy      | 
|  4 | 123456 | bbbbxxxx | 
+----+--------+----------+

binlog中记录内容

replace into时存在唯一索引冲突


replace into test_replace(id,str1,str2) values(8,'xxxx','ppppp'); 
Query OK, 2 rows affected (0.01 sec) select * from test_replace; 
+----+--------+----------+ 
| id | str1   | str2     | 
+----+--------+----------+ 
|  4 | 123456 | bbbbxxxx | 
|  8 | xxxx   | ppppp    | 
+----+--------+----------+ show create table `test_replace`\G 
*************************** 1. row *************************** 
       Table: test_replace 
Create Table: CREATE TABLE `test_replace` ( 
  `id` int(11) NOT NULL AUTO_INCREMENT, 
  `str1` char(10) DEFAULT NULL, 
  `str2` char(10) DEFAULT NULL, 
  PRIMARY KEY (`id`), 
  UNIQUE KEY `uqx_str` (`str1`) 
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8
###下一次插入非冲突数据时自增主键为9

binlog中记录内容

replace into时存在主键冲突&唯一索引冲突


replace into test_replace(id,str1,str2) values(8,'123456','主键和唯一索引冲 
突'); 
Query OK, 3 rows affected (0.01 sec) ####插入了这条数据后,原来的两条数据(主键4,8)变成了一条(主键 8),数据丢失!!!
select * from test_replace; 
+----+--------+-----------------------------+ 
| id | str1   | str2                        | 
+----+--------+-----------------------------+ 
|  8 | 123456 | 主键和唯一索引冲突          | 
+----+--------+-----------------------------+ show create table test_replace\G 
*************************** 1. row *************************** 
       Table: test_replace 
Create Table: CREATE TABLE `test_replace` ( 
  `id` int(11) NOT NULL AUTO_INCREMENT, 
  `str1` char(10) DEFAULT NULL, 
  `str2` char(10) DEFAULT NULL, 
  PRIMARY KEY (`id`), 
  UNIQUE KEY `uqx_str` (`str1`) 
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8 
1 row in set (0.00 sec)

binlog中记录内容

存在问题

场景2:

  • replace into时存在唯一索引冲突:会把冲突数据删掉,插入新数据,但binlog中记录的是update格式,从库同步update binlog不会更新该表的自增主键,主库自增主键9,从库自增主键8,若主从库角色发生切换后,新主库会存在主键冲突问题
  • replace into唯一索引冲突会导致下游大数据hive(同步binlog写入hive中)中数据和mysql中数据不一致问题(hive基于唯一主键进行处理,mysql一条数据,hive中多条数据情况)

场景3:

  • replace into时存在主键冲突&唯一索引冲突:会把表中主键冲突和唯一索引冲突的数据都删掉,再插入新数据,丢失一条数据

经验证:mysql5.7 和mysql8.0均是上诉情况

结论

replace into在只存在主键冲突时会按预期的那样;若只有唯一索引冲突时 主从切换后导致新主库主键冲突错误、下游大数据数据不一致问题;同时存在主键冲突和唯一索引冲突可能会导致丢失数据。业务上不应使用replace into,应该在代码对唯一数据冲突作处理

MySQL replace into那些隐藏的风险的更多相关文章

  1. MySQL replace into 使用详解 及 注意事项

    REPLACE的运行与INSERT很相似.只有一点例外,假如表中的一个旧记录与一个用于PRIMARY KEY或一个UNIQUE索引的新记录具有相同的值,则在新记录被插入之前,旧记录被删除.注意:除非表 ...

  2. MySQL replace函数替换字符串语句的用法(mysql字符串替换)

    MySQL replace函数我们经常用到,下面就为您详细介绍MySQL replace函数的用法,希望对您学习MySQL replace函数方面能有所启迪. 最近在研究CMS,在数据转换的时候需要用 ...

  3. MySQL "replace into" 的坑

    MySQL 对 SQL 有很多扩展,有些用起来很方便,但有一些被误用之后会有性能问题,还会有一些意料之外的副作用,比如 REPLACE INTO. 比如有这样一张表: CREATE TABLE `au ...

  4. MySQL replace into 说明(insert into 增强版)

    MySQL replace into 说明(insert into 增强版) 在插入数据到一个表时,通常是这种情况:1. 先推断数据是否存在: 2. 假设不存在,则插入:3.假设存在,则更新. 在 S ...

  5. MySQL replace into (insert into 的增强版)

    在使用SQL语句进行数据表插入insert操作时,如果表中定义了主键,插入具有相同主键的记录会报错:  Error Code: 1062. Duplicate entry 'XXXXX' for ke ...

  6. mysql replace into 的使用情况

    replace into的存在的几种情况 当表存在主键并且存在唯一键的时候 如果只是主键冲突 mysql> select * from auto; +----+---+------+------ ...

  7. 细说mysql replace into

    replace语句在一般的情况下和insert差不多,但是如果表中存在primary 或者unique索引的时候,如果插入的数据和原来的primary key或者unique相同的时候,会删除原来的数 ...

  8. Mysql replace into

    mysqlsql serverinsert 在向表中插入数据的时候,经常遇到这样的情况:1. 首先判断数据是否存在: 2. 如果不存在,则插入:3.如果存在,则更新. 在 SQL Server 中可以 ...

  9. MySQL "replace into" 的坑以及insert相关操作

    下面我们主要说一下在插入时候的几种情况: 1:insert ignore 2:replace into 3:ON DUPLICATE KEY UPDATE 关于insert ignore: 关于rep ...

随机推荐

  1. vue获取路由中的值

    vue中获取路由中的值 在vue中如何获取路由中的值呢?大家先看下面这段代码: this.$route.params && this.$route.params.id 这行代码就是在v ...

  2. 【ELK】Centos7 安装 ELK 7.6.2 和 UI 管理界面以及测试例子

    1. 初始化环境 1.0 初始化环境官网参考 https://www.elastic.co/guide/en/elasticsearch/reference/current/system-config ...

  3. 三年工作经验,从小厂离职后,我凭什么拿到了阿里的offer

    本篇文章主要记录分享我的面试准备过程. 很多朋友问我为什么离职 关于离职原因,马云有一句经典的话"要么钱没给到位,要么心委屈了",想必大家耳熟能详了,我这里再细说一下我个人离职原因 ...

  4. 快来,我悄悄的给你说几个HashCode的破事。

    这是why技术的第 72 篇原创文章 Hash冲突是怎么回事 在这个文章正式开始之前,先几句话把这个问题说清楚了:我们常说的 Hash 冲突到底是怎么回事? 直接上个图片: 你说你看到这个图片的时候想 ...

  5. IDEA创建maven项目没有src/main/java目录问题解决

    IDEA创建maven项目没有src/main/java目录问题解决          今天新建一个maven项目的时候,没有src文件目录,查了网上很多,依然没有解决,后来发现是VM Options ...

  6. NOI2020D1T1美食家

    传送门:QAQQAQ 完了完了NOI签到题全班打不出来,真就全部成为时代的眼泪了... 首先$O(mT)$的$dp$显然,然后因为$T$很大$w$很小矩阵快速幂显然,但是有$k=200$卡不过去. 然 ...

  7. 手写Koa.js源码

    用Node.js写一个web服务器,我前面已经写过两篇文章了: 第一篇是不使用任何框架也能搭建一个web服务器,主要是熟悉Node.js原生API的使用:使用Node.js原生API写一个web服务器 ...

  8. VSCode--HTML代码片段(基础版,react、vue、jquery)

    起因是最近在学习前端,看的网上的demo也是在react.vue.jquery之间穿插,为了方便一键生成html模板(懒)写demo,有了以下折腾. 本人使用的前端编辑工具是vscode(方便.懒), ...

  9. Blog.Core 项目已完成升级.NET5.0

    (是时候拿出来这种图了) 本文首发于公众号,但是会有新的内容加进来,所以就在博客园新开了一篇,望见谅.截止发稿,Blog.Core项目Master分支已经迁移到了5.0,新建了3.1的分支. 开心的锣 ...

  10. Torrent文件的解析与转换

    Torrent简介 BitTorrent协议的种子文件(英语:Torrent file)可以保存一组文件的元数据.这种格式的文件被BitTorrent协议所定义.扩展名一般为".torren ...