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. 企业级数据大屏设计如何实现,div+html+echarts

    大屏是什么? 大屏设计是最近比较流行的概念,一般按照功能来分有几种: 1. 可交互的触摸屏,大多运用在互动教学课程或者报告演示现场,用户可结合交互操作来阐述具体内容.设计师需要对交互形式和传达内容作统 ...

  2. CodeForces 1409E Two Platforms

    题意 有 \(n\) 个点,分别位于 \((x_i,y_i)\),求最多能用两个长度为 \(k\) 的平台接住多少个点. \(\texttt{Data Range:}n\leq 2\times 10^ ...

  3. python实现常见的设计模式

    Pyhton实现常用的23种设计模式[详解] 关注公众号[轻松学编程],回复[设计模式],获取本文源代码. 在文章末尾可以扫码关注公众号. 一.概念 软件工程中,设计模式是指软件设计问题的推荐方案. ...

  4. Jmeter——ForEach Controller&Loop Controller

    今天来分享下Jmeter中的2款循环控制器,ForEach Controller和Loop Controller,在使用上还是有所区别. ForEach Controller ForEach Cont ...

  5. frida打印与参数构造

    title: frida打印与参数构造 categories: 逆向与协议分析 toc: true mathjax: true tags: frida HOOK 逆向 widgets: type: t ...

  6. 由python工作区导致的python代码能运行,但是PyCharm画红线的问题

    原文:https://www.zhihu.com/question/63028700 PyCharm在遇到模块找不到时,会使用红色波浪线提醒开发者. Python有一个工作区的概念,在默认情况下,当你 ...

  7. linux的mysql修改默认端口3306

    linux 修改mysql默认端口3306 cd /etc/mysql/my.cnf 修改两处 客户端的port=3306 和mysqld的服务器端口port=3306 [client] port=3 ...

  8. 强迫自己学Jquery

    Jquery 适合我吗? 里面有很多用不上的功能, 我需要什么,常用的判断,常用的扩展,来自Dojo的Hitch函数,事件绑定,样式处理(添加 删除 替换),Ajax,模块加载, 足够了,真心不想用这 ...

  9. linux 内核 同步原理

    中断分为同步中断和异步中断. 同步中断是由CPU控制单元产生的,"同步"是指只有在一条指令执行完毕后,CPU才会发出中断,比如系统调用 异步中断是由其他硬件设备依照CPU时钟信号产 ...

  10. Socket 套接字的系统调用

    socket 结构 /** * struct socket - general BSD socket * @state: socket state (%SS_CONNECTED, etc) * @ty ...