Mysql on duplicate key update用法及优缺点

Mysql on duplicate key update用法及优缺点

大家好,又见面了,我是全栈君。

在实际应用中,经常碰到导入数据的功能,当导入的数据不存在时则进行添加,有修改时则进行更新,

  在刚碰到的时候,一般思路是将其实现分为两块,分别是判断增加,判断更新,后来发现在mysql中有ON DUPLICATE KEY UPDATE一步就可以完成(Mysql独有的语法)。

ON DUPLICATE KEY UPDATE单个增加更新及批量增加更新的sql

在MySQL数据库中,如果在insert语句后面带上ON DUPLICATE KEY UPDATE 子句,而要插入的行与表中现有记录的惟一索引或主键中产生重复值,那么就会发生旧行的更新;如果插入的行数据与现有表中记录的唯一索引或者主键不重复,则执行新纪录插入操作。

说通俗点就是数据库中存在某个记录时,执行这个语句会更新,而不存在这条记录时,就会插入。

注意点:

  因为这是个插入语句,所以不能加where条件。

  如果是插入操作,受到影响行的值为1;如果更新操作,受到影响行的值为2;如果更新的数据和已有的数据一样(就相当于没变,所有值保持不变),受到影响的行的值为0。

该语句是基于唯一索引或主键使用,比如一个字段a被加上了unique index,并且表中已经存在了一条记录值为1,

下面两个语句会有相同的效果:

INSERT INTO table (a,b,c) VALUES (1,2,3)  
  ON DUPLICATE KEY UPDATE c=c+1;  
  
UPDATE table SET c=c+1 WHERE a=1;

ON DUPLICATE KEY UPDATE后面可以放多个字段,用英文逗号分割。

再现一个例子:

INSERT INTO table (a,b,c) VALUES (1,2,3),(4,5,6)  
      ON DUPLICATE KEY UPDATE c=VALUES(a)+VALUES(b); 

表中将更改(增加或修改)两条记录。

项目中数据的操作有时候会令人头大,遇到一个需求:

需要将数据从A数据库的a数据表同步到B数据库的b数据表中(ab表结构相同,但不是主从关系。。。just同步过去)

第一次同步过去,b表为空,同步很简单。

但是当a表中的某些数据更新且增加了新数据之后,再想让两个表同步就有些麻烦了。(如果把b表清空,重新同步,数据量过大的话耗费的时间太长,不是一个好办法)

想着能不能按照时间段来做更新,这段时间内有新数据了,就插入数据,有数据更新了就更新数据。先说下我的思路:

步骤:

  1.首先我从a表取出某一时间段的数据(分段更新)

  2.往b表内放数据,根据主键判断b表是否已经有此条记录,没有此数据则插入,有了记录则对比数据是否一样,一样则不做更改,不一样就做更新操作。

此时使用该语句可以满足需要,但是要注意几个问题:

  • 更新的内容中unique key或者primary key最好保证一个,不然不能保证语句执行正确(有任意一个unique key重复就会走更新,当然如果更新的语句中在表中也有重复校验的字段,那么也不会更新成功而导致报错,只有当该条语句没有任何一个unique key重复才会插入新记录);尽量不对存在多个唯一键的table使用该语句,避免可能导致数据错乱。

  • 在有可能有并发事务执行的insert 语句情况下不使用该语句,可能导致产生death lock。

  • 如果数据表id是自动递增的不建议使用该语句;id不连续,如果前面更新的比较多,新增的下一条会相应跳跃的更大。

  • 该语句是mysql独有的语法,如果可能会设计到其他数据库语言跨库要谨慎使用。

产生death lock原理

insert … on duplicate key 在执行时,innodb引擎会先判断插入的行是否产生重复key错误,如果存在,在对该现有的行加上S(共享锁)锁,如果返回该行数据给mysql,然后mysql执行完duplicate后的update操作,然后对该记录加上X(排他锁),最后进行update写入。

如果有两个事务并发的执行同样的语句,那么就会产生death lock,如:

Mysql on duplicate key update用法及优缺点

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

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

(0)
上一篇 2022年2月19日 下午8:00
下一篇 2022年2月19日 下午8:00


相关推荐

  • 国内 OpenClaw 变天了!腾讯阿里字节华为百度小米全线下场,最快部署仅需 1 分钟?(全名单)

    国内 OpenClaw 变天了!腾讯阿里字节华为百度小米全线下场,最快部署仅需 1 分钟?(全名单)

    2026年3月12日
    1
  • mysql的反引号

    mysql的反引号mysql 的表名和字段名为何加上反引号 mysql 的反引号 在使用 mysql 数据库时 用第三方连接工具连接 经常需要导出表结构和数据等 但是在导出的语句中 表和表中的字段都用 table 反引号包裹 Tablestructu

    2026年3月18日
    2
  • Python实现向量自回归(VAR)模型——完整步骤「建议收藏」

    废话不多说,先开始分享:1.首先啥是VAR模型,我这里简略通俗的说一下,想看代码的童鞋直接跳到第3部分就好了:以金融价格为例,传统的时间序列模型比如ARIMA,ARIMA-GARCH等,只分析价格自身的变化,模型的形式为:其中称为自身的滞后项。但是VAR模型除了分析自身滞后项的影响外,还分析其他相关因素的滞后项对未来值产生的影响,模型的形式为:其中就是其他因子的滞后项…

    2022年4月15日
    1.2K
  • LVS+KeepAlived+Nginx高可用实现方案

    LVS+KeepAlived+Nginx高可用实现方案文章目录概念LVSKeepAlived为什么要使用准备这是一段血泪教程…概念LVS什么是lvsLVS是LinuxVirtualServer的简写,意即Linux虚拟服务器,是一个虚拟的服务器集群系统。本项目在1998年5月由章文嵩博士成立,是中国国内最早出现的自由软件项目之一。宗旨使用集群技术和Linux操作系统实现一个高性能、高可用的服务器.很好的可伸缩性(Scal…

    2022年7月24日
    12
  • 完全教程 Aircrack-ng

    完全教程 Aircrack-ng网页地图贴吧应用更多新闻知道百科图片小说文库音乐视频 aircrack 百度一下您可以仅查看 英文结果完全教程 Aircrack ng 激活成功教程 WEP WPA PSK 加密利器 51 2011 年 5 月 26 日 nbsp nbsp 步骤 5 打开 aircrack ng 开始激活成功教程 WEP

    2026年3月18日
    2
  • 关于开启curl扩展问题若干

    关于开启curl扩展问题若干笔者在尝试了很多次开启 curl 扩展无效后终获成功 在此就将走过的弯路罗列至此 以免需要的朋友再入歧途 正确的开启方法如下 nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp 1 打开 php ini 文件 去掉 extension php curl dll 前的 确保 php 扩展文件下有 php curl dll 文件 如果此时开启无效的话 则执行第二步 nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp 2 将 php 目录下 libe

    2026年3月26日
    2

发表回复

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

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