mysql replace into 的使用情况

mysql replace into 的使用情况

replace into的存在的几种情况

  • 当表存在主键并且存在唯一键的时候
    • 如果只是主键冲突
复制代码
mysql> select * from auto; +----+---+------+---------+ | id | k | v | extra | +----+---+------+---------+ | 2 | 2 | 2 | extra 2 | | 3 | 3 | 3 | extra 3 | | 4 | 1 | 1-1 | NULL | +----+---+------+---------+ 3 rows in set (0.00 sec) mysql> mysql> show create table auto\G *************************** 1. row *************************** Table: auto Create Table: CREATE TABLE `auto` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `k` int(10) unsigned NOT NULL, `v` varchar(100) DEFAULT NULL, `extra` varchar(200) DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `uk_k` (`k`) ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=latin1 1 row in set (0.00 sec)
复制代码

这里我们插入一条主键已经存在的4的数据

复制代码
mysql> replace into auto(id,k)values(4,5); Query OK, 2 rows affected (0.01 sec) mysql> select * from auto; +----+---+------+---------+ | id | k | v | extra | +----+---+------+---------+ | 2 | 2 | 2 | extra 2 | | 3 | 3 | 3 | extra 3 | | 4 | 5 | NULL | NULL | +----+---+------+---------+ 3 rows in set (0.00 sec) mysql> show create table auto \G *************************** 1. row *************************** Table: auto Create Table: CREATE TABLE `auto` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `k` int(10) unsigned NOT NULL, `v` varchar(100) DEFAULT NULL, `extra` varchar(200) DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `uk_k` (`k`) ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=latin1 1 row in set (0.00 sec)
复制代码

 发现,auto_increment并没有+1,而是针对原来的那一条id=4的记录进行了update,因为没有指定其他列(v,extra)的值,所以,update的时候都使用了默认值.

  • 如果主键跟唯一键都冲突并且在同一行里
复制代码
mysql> select * from auto; +----+---+------+---------+ | id | k | v | extra | +----+---+------+---------+ | 2 | 2 | 2 | extra 2 | | 3 | 3 | 3 | extra 3 | | 4 | 5 | NULL | NULL | | 5 | 6 | 6 | NULL | +----+---+------+---------+ 4 rows in set (0.00 sec) mysql> show create table auto \G *************************** 1. row *************************** Table: auto Create Table: CREATE TABLE `auto` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `k` int(10) unsigned NOT NULL, `v` varchar(100) DEFAULT NULL, `extra` varchar(200) DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `uk_k` (`k`) ) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=latin1 1 row in set (0.00 sec) mysql> mysql> mysql> replace into auto(id,k,extra)values(5,6,77); Query OK, 2 rows affected (0.01 sec) mysql> select * from auto; +----+---+------+---------+ | id | k | v | extra | +----+---+------+---------+ | 2 | 2 | 2 | extra 2 | | 3 | 3 | 3 | extra 3 | | 4 | 5 | NULL | NULL | | 5 | 6 | NULL | 77 | +----+---+------+---------+ 4 rows in set (0.00 sec) mysql> show create table auto \G *************************** 1. row *************************** Table: auto Create Table: CREATE TABLE `auto` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `k` int(10) unsigned NOT NULL, `v` varchar(100) DEFAULT NULL, `extra` varchar(200) DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `uk_k` (`k`) ) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=latin1 1 row in set (0.00 sec)
复制代码

我们发现,auto_increment也并没有+1,而是针对原来的那一条id=6的记录进行了update,因为没有指定其他列(v)的值,所以,update的时候都v使用了默认值变成了null

  • 如果主键跟唯一键都冲突不在同一行,对应2条记录呢

我们来看下:

复制代码
mysql> show create table auto \G
*************************** 1. row *************************** Table: auto Create Table: CREATE TABLE `auto` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `k` int(10) unsigned NOT NULL, `v` varchar(100) DEFAULT NULL, `extra` varchar(200) DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `uk_k` (`k`) ) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=latin1 1 row in set (0.00 sec) mysql> select * from auto; +----+---+------+---------+ | id | k | v | extra | +----+---+------+---------+ | 2 | 2 | 2 | extra 2 | | 3 | 3 | 3 | extra 3 | | 4 | 5 | NULL | NULL | | 6 | 6 | 66 | NULL | +----+---+------+---------+ 4 rows in set (0.00 sec) mysql> replace into auto(id,k,v)values(6,2,88); Query OK, 3 rows affected (0.03 sec)
复制代码

像上面的,主键id=6对应一条记录,唯一索引k=2对应id=2的另外一条记录,所以我们当前插入的记录就会跟2行数据有冲突,我们replace into 看看会有什么结果

复制代码
mysql> replace into auto(id,k,v)values(6,2,88); Query OK, 3 rows affected (0.03 sec) mysql> select * from auto; +----+---+------+---------+ | id | k | v | extra | +----+---+------+---------+ | 3 | 3 | 3 | extra 3 | | 4 | 5 | NULL | NULL | | 6 | 2 | 88 | NULL | +----+---+------+---------+ 3 rows in set (0.00 sec) mysql> show create table auto \G *************************** 1. row *************************** Table: auto Create Table: CREATE TABLE `auto` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `k` int(10) unsigned NOT NULL, `v` varchar(100) DEFAULT NULL, `extra` varchar(200) DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `uk_k` (`k`) ) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=latin1 1 row in set (0.00 sec)
复制代码

我们发现auto_increment并没有+1,MySQL把原来的id=6的这条记录上进行uppdate,但是发现唯一索引k出现了冲突,所以就把对应冲突的那条数据删除,再进行更新,由于没有指定更新字段extra的数据,所以就把extra更新为默认数据

  • 如果仅仅是唯一键冲突呢?
复制代码
mysql> select * from auto; +----+---+------+---------+ | id | k | v | extra | +----+---+------+---------+ | 2 | 2 | 2 | extra 2 | | 3 | 3 | 3 | extra 3 | | 4 | 5 | NULL | NULL | | 5 | 6 | NULL | 77 | +----+---+------+---------+ 4 rows in set (0.00 sec) mysql> show create table auto \G *************************** 1. row *************************** Table: auto Create Table: CREATE TABLE `auto` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `k` int(10) unsigned NOT NULL, `v` varchar(100) DEFAULT NULL, `extra` varchar(200) DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `uk_k` (`k`) ) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=latin1 1 row in set (0.00 sec) mysql> mysql> replace into auto(k,v)values(6,66); Query OK, 2 rows affected (0.04 sec) mysql> select * from auto; +----+---+------+---------+ | id | k | v | extra | +----+---+------+---------+ | 2 | 2 | 2 | extra 2 | | 3 | 3 | 3 | extra 3 | | 4 | 5 | NULL | NULL | | 6 | 6 | 66 | NULL | +----+---+------+---------+ 4 rows in set (0.00 sec) mysql> show create table auto \G *************************** 1. row *************************** Table: auto Create Table: CREATE TABLE `auto` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `k` int(10) unsigned NOT NULL, `v` varchar(100) DEFAULT NULL, `extra` varchar(200) DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `uk_k` (`k`) ) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=latin1 1 row in set (0.00 sec)
复制代码

这时候,我们发现,,auto_increment已经+1了。MySQL这时候的执行步骤是,首先往表里面插入一条数据,这时候auto_increment+1,但是在插入的时候发现唯一索引的k冲突了,然后把冲突的这条数据删除,然后重新插入,对于没有指定其他列(extra)的值,如extra都使用了默认值变成了null

现在我们可以下结论了:

  1. 当replace into 记录只与主键冲突的时候,auto_increment不会增加,它会对与主键冲突的那一条记录进行更新,没有指定的列将会被更新为默认值
  2. 当replace into 记录与主键跟唯一索引同时冲突的时候,auto_increment不会增加
    1. 如果冲突的主键和索引在同一行记录,则replace into只做更新,对于没有指定值的其他列,将会被更新为默认值,
    2. 如果冲突的主键和索引分别对应2行数据,则MySQL将会删除唯一索引的那一行记录,更新对应主键的那一行记录。
  3. 当replace into 记录只与唯一索引进行冲突的时候,auto_increment + 1,再对数据进行更新。
  • 最后我们可以对总结分析下,MySQL对replace into的操作是首先是insert操作,如果insert失败,则对insert失败的这条记录进行update,如果update还是失败,则会进行delete操作之后再update。
  • 具体流程是这样的:insert记录,发现主键冲突,则update这一行,update的时候发现存在唯一键冲突,则delete对应的唯一键的行后再进行update。如果insert成功,auto_increment自然+1了,然后对这条记录进行update,update的时候发现存在唯一键冲突,则delete对应的唯一键的行后再进行update。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/119672.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 查询oracle视图创建语句及如何向视图中插入数据[通俗易懂]

    今天由于要测试接口,需要在数据库中插入一些测试数据。但当我在向数据库插入数据的时候,发现接口查询的是视图并不是表,所以将遇到的问题在这里记录一下。1.向视图插入数据的时候分两种情况1.1对于简单视图(视图建立在一张表上),跟表一样直接插入数据就好;1.2对于复杂视图(视图建立时包含多表关联、分组、聚合函数),这个时候不能直接插入数据,应该创建一个INSTEAD类型的触发器来操作,将要插入…

    2022年4月12日
    649
  • Spring学习– SpEL表达式

    Spring学习– SpEL表达式转载自 https://www.cnblogs.com/goodcheap/p/6490896.html目录Spring表达式语言(简称SpEL):是一个支持运行时查询和操作对象图的强大的表达式语言。语法类似于EL:SpEL使用#{…}作为定界符,所有在大括号中的字符都将被认为是SpEL,SpEL为bean的属性进行动态赋值提供了便利。通过SpEL可以实现:通过…

    2022年9月4日
    2
  • PHP– AWS S3云存储上传多文件与上传单个文件

    PHP– AWS S3云存储上传多文件与上传单个文件

    2022年2月10日
    45
  • SpringBoot(二十二)整合Mybatis,使用SqlSessionTemplate实现增删改查[通俗易懂]

    SpringBoot(二十二)整合Mybatis,使用SqlSessionTemplate实现增删改查[通俗易懂]在之前这篇基础上进行改造使用JdbcTemplate实现增删改查。SpringBoot版本:2.1.1目录结构如下:pom文件添加依赖,如下:<!–添加依赖以后Mybatis就自动配置好了,可以直接使用,具体自动配置代码到mybatis-spring-boot-autoconfigure包下查看–><!–上一篇博客里添加的spring-boot…

    2022年5月25日
    56
  • 树莓派3B+ 人脸识别(OpenCV)

    树莓派3B+ 人脸识别(OpenCV)树莓派3B+人脸识别(OpenCV)相信大家都看了前面的OpenCV安装和人脸检测教程,有了基础后,现在我们正式进入重头戏——人脸识别的教程。注意:该教程面向python2.7+OpenCV2.4.9(官方源)其它版本需进行一些小的修改,文中会具体注明。1.生成人脸识别数据目录结构./data数据根目录./data/gener…

    2022年6月25日
    20
  • 7道常见的数据分析面试题[通俗易懂]

    7道常见的数据分析面试题[通俗易懂]InfoQ内容来自极客时间《数据分析实战45讲》数据分析师近几年在国内互联网圈越来越火,很多开发都因为薪资和发展前景,希望转行到数据分析岗。今天,我们就来聊聊面试数据分析师的那些事。其实,数据分析能力是每个互联网人的必备技能,哪怕你没有转行数据分析师的计划,也推荐你看看这个专题,提升你的数据能力。数据分析的能力要求与数据分析相关的工作有一个特质,就是对数字非常敏感,同时也要求对数据具…

    2022年5月27日
    34

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号