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)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • client profile_clienttop

    client profile_clienttopscreenX:鼠标在显示屏幕上的坐标。clientX:鼠标在页面显示区域的坐标。注:以上两个都是各浏览器通用的。pageX:FF特有,鼠标在页面上的位置,从页面左上角开始定位,这个可以很方便在整个页面上进行定位,IE没有直接替换的属性。layerX:FF特有,鼠标相对于“触发事件的元素的层级关系中离该元素最近的,设置了position的父元素”的边界的位置,从border的左…

    2022年10月29日
    0
  • Innodb_large_prefix

    Innodb_large_prefix

    2021年10月22日
    84
  • 分布式数据存储系统的三要素是什么_分布式存储和集中式存储

    分布式数据存储系统的三要素是什么_分布式存储和集中式存储顾客:生产和消费数据顾客相当于分布式存储系统中的应用程序。根据数据的产生和使用,顾客分为生产者和消费者两种类型。生产者负责添加数据,消费者负责使用数据根据数据的特征,不同的数据划分为三类:结构化数

    2022年8月1日
    7
  • 使用线程池来创建线程的方法_线程池多线程实现

    使用线程池来创建线程的方法_线程池多线程实现1.如何使用线程池来创建线程?java中提供了一个静态工厂方法来创建不同的线程池: Executors通过静态方法创建出的线程都实现了ExecutorService接口。常用的方法包括:newFixedThreadPool(intthreads);创建一个固定数目的线程池newCachedThreadPool();创建一个可缓存的线程池,调用execute方法将重用以前…

    2022年10月21日
    0
  • python对随机森林分类结果绘制roc曲线

    python对随机森林分类结果绘制roc曲线上图:附上代码:一个函数,传入三个参数…..传入参数,训练模型,然后:fit=model.fit(x_train,y_training)#ROCy_score=model.fit(x_train,y_training).predict_proba(x_test)#随机森林fpr,tpr,thresholds=roc_curve(y_test,…

    2022年5月17日
    83
  • 用Java实现文本编辑器

    用Java实现文本编辑器源码里有注释:importjava.awt.*;importjava.awt.event.*;importjava.io.*;importjavax.swing.*;importjavax.swing.text.*;//简单的文本编辑器publicclassEditorextendsJFrame{ publicJTextPanetextPane=new…

    2022年6月3日
    33

发表回复

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

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