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。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

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

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • do you know what i mean_do you know what

    do you know what i mean_do you know whatOriginalLinkQ: “HowdoyouknowGodisreal?” -GregoryM.A: Thisisthequestionthateverysinglepersonatonepoint(hopefully)intheirlifetimewillask.Mostpeoplewillprobablyaskitmanyt

  • python随机产生数字_随机数生成excel

    python随机产生数字_随机数生成excel使用场景:随机短信验证码importrandomimportstring#指定随机数长度r_num=4#生成数字+字母(字符串序列)token=string.ascii_letters+string.digits”’string.ascii_letters:生成大小写字母(type:字符串)string.digits:生成数字…

  • 一文弄懂什么是Precision,Recall,F1score,以及accuracy[通俗易懂]

    一文弄懂什么是Precision,Recall,F1score,以及accuracy[通俗易懂]近期在做实验的时候一直出现Precision,Recall,F1score,以及accuracy这几个概念,为了防止混淆,在这里写下学习笔记,方便以后复习。以一个二分类问题为例,样本有正负两个类别。那么模型预测的结果和真实标签的组合就有4种:TP,FP,FN,TN,如下图所示。TP实际为正样本你预测为正样本,FN实际为正样本你预测为负样本,FP实际为负样本你预测为正样本,TN实际为负样本…

    2022年10月14日
  • 网管员常用工具(二)「建议收藏」

    网管员常用工具(二)「建议收藏」EVERESTeverest中文版是一款系统硬件检测工具。everest中文版可以对上千种主板和硬件进行检测,可以有效地检测出用户电脑硬件的所有信息,尤其可以对各种型号处理器进行检测,让用户对自己电脑总体性能有个直观了解。HDTuneHDTunePro是一款小巧易用的硬盘工具软件,其主要功能有硬盘传输速率检测,健康状态检测,温度检测及磁盘表面扫描等。另外,还能检测出硬盘的固件版本、…

  • Python包管理必备–pip命令&设置镜像源[通俗易懂]

    Python包管理必备–pip命令&设置镜像源[通俗易懂]近期周围很多朋友询问,Python如何管理包和模块,并且很多常用的包使用pip安装的时候,总是因为网络问题中断,在学习新包时造成了很大的挫败感,这些问题也是之前自己在学习过程中,遇到的痛点,所以抽出精力,整理了下之前关于这块的学习笔记,形成文章,希望给其他python道友以帮助,也给自己后续查阅带来方便。Python语言的核心能快速上手并且极具吸引力的是其异常丰富和强大的包,这些包给我们封装好了日常工作中遇到的问题或需求的各种解决方案,所以在python基础知识较为牢固时,遇到具体问题,具体学习对应的包

  • java工厂模式三种详解(部分转载)

    java工厂模式三种详解(部分转载)工厂方法模式(FactoryMethod)工厂方法模式分为三种:1、普通工厂模式,就是建立一个工厂类,对实现了同一接口的一些类进行实例的创建。首先看下关系图:举例如下:(我们举一个发送邮件和短信的例子)首先,创建二者的共同接口:[java]viewplaincopypublicinterfaceSender{ publicvoidSe…

发表回复

您的电子邮箱地址不会被公开。

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