一 介绍
  上一篇文章介绍了replace into的基本原理。本章内容通过一个例子说明 replace into 带来的潜在的数据质量风险,当涉及replace into操作的表含有自增主键时,主备切换后会造成数据覆盖等不一致的情况发生。
二 案例分析

在主库上操作

root@test 12:36:51>show create table t1 \G*************************** 1. row ***************************Table: t1Create Table: CREATE TABLE `t1` (`id` int(11) NOT NULL AUTO_INCREMENT,`name` varchar(20) DEFAULT NULL,PRIMARY KEY (`id`),UNIQUE KEY `name` (`name`)) ENGINE=InnoDB DEFAULT CHARSET=utf81 row in set (0.00 sec)root@test 12:37:41>insert into t1(name) values('a')

此时检查主备库上t1的表结构都是一样的,AUTO_INCREMENT 都是2.

root@test 12:37:51>show create table t1 \G*************************** 1. row ***************************Table: t1Create Table: CREATE TABLE `t1` (`id` int(11) NOT NULL AUTO_INCREMENT,`name` varchar(20) DEFAULT NULL,PRIMARY KEY (`id`),UNIQUE KEY `name` (`name`)) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf81 row in set (0.00 sec)

在主库上进行进行replace into操作

root@test 12:37:58>replace into t1(name) values('a'); root@test 12:38:40>replace into t1(name) values('a');root@test 12:38:49>select * from t1;+----+------+| id | name |+----+------+| 3 | a |+----+------+1 row in set (0.00 sec)

此时检查主备库中t1 表结构,请注意AUTO_INCREMENT=4

root@test 12:38:51>show create table t1 \\G*************************** 1. row ***************************Table: t1Create Table: CREATE TABLE `t1` (`id` int(11) NOT NULL AUTO_INCREMENT,`name` varchar(20) DEFAULT NULL,PRIMARY KEY (`id`),UNIQUE KEY `name` (`name`)) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf81 row in set (0.00 sec)

从库上t1的表结构 ,AUTO_INCREMENT=2

root@test 12:39:35>show create table t1 \G *************************** 1. row ***************************Table: t1Create Table: CREATE TABLE `t1` (`id` int(11) NOT NULL AUTO_INCREMENT,`name` varchar(20) DEFAULT NULL,PRIMARY KEY (`id`),UNIQUE KEY `name` (`name`)) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf81 row in set (0.00 sec)root@test 12:39:43>select * from t1;+----+------+| id | name |+----+------+| 3 | a |+----+------+1 row in set (0.00 sec)

【分析】
  表t1的表结构 AUTO_INCREMENT=2 而主库上的t1表结构的AUTO_INCREMENT=4.原本replace操作是在自增主键的情况下,遇到唯一键冲突时执行的是delete+insert,但是在记录binlog时,却记录成了update操作,update操作不会涉及到auto_increment的修改。备库应用了binlog之后,备库的表的auto_increment属性不变。
三 风险点:
  如果主备库发生主从切换,备库变为原来的主库,按照原来的业务逻辑再往下会发生什么?
root@test 12:40:46>replace into t1(name) values('a');  
Query OK, 2 rows affected (0.00 sec)
root@test 12:40:48>select * from t1;
+----+------+
| id | name |
+----+------+
|  2 | a    |  ---id由原来的3变成了2.
+----+------+
1 row in set (0.00 sec)
如果t1表本来就存在多条记录 ,主从切换之后,应用写新的主库则会发生主键冲突,这个留给各位读者自己测试一下。^_^
四 解决方法
  推荐使用 insert into table values(,....) on duplicate key update 语法结构来解决业务需求。 来避免replace into 给含有自增主键的表带来主从不一致情况。

root@test 01:14:28>insert into t1(name) values('a'); Query OK, 1 row affected (0.00 sec)
root@test 01:14:51>insert into t1(name) values('b'); Query OK, 1 row affected (0.00 sec)
root@test 01:14:54>insert into t1(name) values('c'); Query OK, 1 row affected (0.00 sec)
root@test 01:14:57>select * from t1;+----+------+| id | name |+----+------+| 1 | a || 2 | b || 3 | c |+----+------+3 rows in set (0.00 sec)
root@test 01:16:17>show create table t1 \G*************************** 1. row ***************************Table: t1Create Table: CREATE TABLE `t1` (`id` int(11) NOT NULL AUTO_INCREMENT,`name` varchar(20) DEFAULT NULL,PRIMARY KEY (`id`),UNIQUE KEY `name` (`name`)) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf81 row in set (0.00 sec)
root@test 01:16:26>insert into tt(name) values('a') on duplicate key update name='a'; Query OK, 1 row affected (0.00 sec)
root@test 01:17:09>show create table t1 \G*************************** 1. row ***************************Table: t1Create Table: CREATE TABLE `t1` (`id` int(11) NOT NULL AUTO_INCREMENT,`name` varchar(20) DEFAULT NULL,PRIMARY KEY (`id`),UNIQUE KEY `name` (`name`)) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf81 row in set (0.00 sec)

五 总结
  由于replace into操作在遇到主键冲突的时候 会修改主键的值,所以如果业务逻辑强依赖自增ID,绝对不要用replace,普通环境也不建议这样用,因为replace into 操作可能会导致主键的重新组织.推荐使用 insert into table values(,....) on duplicate key update 来解决业务需求。

【MySQL】replace into 浅析之二相关推荐

  1. MySQL/InnoDB处理AUTO_INCREMENT(二)

    2019独角兽企业重金招聘Python工程师标准>>> MySQL/InnoDB处理AUTO_INCREMENT(二) http://dev.mysql.com/doc/refman ...

  2. mysql replace报错_Mysql中replace与replace into的用法讲解

    Mysql replace与replace into都是经常会用到的功能:replace其实是做了一次update操作,而不是先delete再insert:而replace into其实与insert ...

  3. 【笔记】MySQL的基础学习(二)

    [笔记]MySQL的基础学习(二) MySQL 老男孩  一 视图 视图其实就是给表起个别名 1.创建视图 格式:CREATE VIEW 视图名称 AS SQL语句 CREATE VIEW v1 AS ...

  4. MySQL:讨人喜欢的 MySQL replace into 用法(insert into 的增强版)

    讨人喜欢的 MySQL replace into 用法(insert into 的增强版) 在向表中插入数据的时候,经常遇到这样的情况:1. 首先判断数据是否存在: 2. 如果不存在,则插入:3.如果 ...

  5. MySQL Replace INTO的使用

    MySQL Replace INTO的使用 今天DST里面有个插件作者问我关于Replace INTO和INSERT INTO的区别,我和他说晚上上我的blog看吧,那时候还在忙,现在从MYSQL手册 ...

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

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

  7. MySQL的基本查询(二)

    MySQL的基本查询(二) 文章目录 MySQL的基本查询(二) 3. Update 4. Delete 5. 插入查询结果 6. 聚合函数 7. group by子句的使用 3. Update 语法 ...

  8. MySQL replace into 用法

    MySQL replace into 用法(insert into 的增强版) 在向表中插入数据的时候,经常遇到这样的情况:1. 首先判断数据是否存在: 2. 如果不存在,则插入:3.如果存在,则更新 ...

  9. MySQL Replace()函数

    转载自  MySQL Replace()函数 MySQL REPLACE字符串函数简介 MySQL为您提供了一个有用的字符串函数REPLACE(),它允许您用新的字符串替换表的列中的字符串. REPL ...

最新文章

  1. 中科大计算机专业跟浙江大学计算机专业相比,浙大计算机研究生近年录报比与中国科学技术大学的比较...
  2. A. Case of the Zeros and Ones
  3. 元宇宙深度研究报告:元宇宙是互联网的终极形态?
  4. [links]一写国内外著名人物的blog链接
  5. python中的operator库
  6. Web服务的体系架构
  7. 汇编语言---冒泡法排序
  8. --------》》》》【醒目】一些比较有用的东西
  9. spring boot 2.0 源码分析(三)
  10. Linux文本模式自动登录,Linux开机自动登录(文本模式)
  11. linux文件系统变为只读的修复
  12. Java集合框架类图
  13. Java -Dfile.encoding=UTF-8 出现乱码问题原因分析
  14. J-link 报错解决方法
  15. 利用tushare数据计算期货主力合约的活跃度
  16. ubuntu下lnmp安装mysql密码_Ubuntu LNMP环境搭建
  17. pdf电子书转换成txt文档
  18. 在软件开发中如何将看板方法与 Scrum 集合使用?
  19. 深度:中老年网民电商渗透率超40%,拼多多/淘宝/京喜/有赞如何布局老年电商市场?
  20. 《数理天地》期刊简介及投稿邮箱

热门文章

  1. java 通用类型_Java获取通用类型的集合
  2. oracle说不能初始化失败,PLSQLDeveloper 提示不能初始化?
  3. java 错误码设计_关于Java中异常的设计
  4. nodejs mysql数据推送_使用Nodejs实现实时推送MySQL数据库最新信息到客户端
  5. 关于CodeReview
  6. 附件下载原来如此简单
  7. php容器原理,容器与依赖注入的原理
  8. c语言状态机实现坐标切换,C语言状态机最优模式(转)
  9. Vue购物商城项目(二) 数据请求使用
  10. Linux引出环境变量的关键字,学习记录008-linux常用命令/设置系统and用户环境变量two(示例代码)...