MySQL的replace into 与insert into on duplicate key update

Posted Firm陈

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MySQL的replace into 与insert into on duplicate key update相关的知识,希望对你有一定的参考价值。

1. insert into …on duplicate key update和replace into作用
表中存在重复数据(主键、唯一索引冲突)则更新,不存在则插入

2. 两者区别

  1. 表中存在自增值,有重复数据时,两种方法auto_increment都自动+1,但是replace into自增字段值+1,insert … on deplicate udpate自增字段值不变,用原有值。

  2. 当表中的某些字段中包含默认值的时候,replace操作插入不完全字段的记录,会导致其他字段直接使用默认值,而insert…on duplicate key update操作会保留该条记录的原有值

  3. 当与多条记录(一条以上)存在冲突时,insert…on duplicate key update操作会报字段冲突异常,replace into 则会更新成功

3. insert…on duplicate key update … 示例

-- 创建表,用于下面示例
 drop table IF EXISTS TEST1;
 CREATE TABLE  TEST1 (
      id int(11) NOT NULL AUTO_INCREMENT,
      uname varchar(64) ,
      cardNo varchar(128) not null,
      age int(4) ,
      PRIMARY KEY (id),
      UNIQUE KEY u_uname (uname),
      UNIQUE KEY u_cardNo (cardNo)  
  ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- 1. 执行第一次:(首次数据库表中没有数据,正常插入)
  insert into TEST1 (uname, cardNo, age) values ('cc','430xxx1',26) on duplicate key update uname=values(uname),cardNo=VALUES(cardNo),age = values(age);

-- 2. 执行第二次:(与第一次的唯一(uname)冲突,执行更新, update后未设置age,观察到age用原来字段值,id也是使用之前的值,未自增)
 insert into TEST1 (uname, cardNo,age) values ('cc','430xxx2',25) on duplicate key update uname=values(uname),cardNo=VALUES(cardNo);

-- 3.执行第三次:(无冲突,执行插入,观察 id 键值,出现了丢失,直接跳到了3)
  insert into TEST1 (uname, cardNo, age) values ('hh','430xxx3',24) on duplicate key update uname=values(uname),cardNo=VALUES(cardNo),age = values(age);

-- 4.执行第四次:(与第一条记录uname,第二条记录cardNo两个唯一索引冲突,执行报错)
    insert into TEST1 (uname, cardNo, age) values ('cc','430xxx3',23) on duplicate key update uname=values(uname),cardNo=VALUES(cardNo),age = values(age);


4. replace into …示例

-- 创建表,用于下面示例
 drop table IF EXISTS TEST1;
 CREATE TABLE  TEST1 (
      id int(11) NOT NULL AUTO_INCREMENT,
      uname varchar(64) ,
      cardNo varchar(128) not null,
      age int(4) ,
      PRIMARY KEY (id),
      UNIQUE KEY u_uname (uname),
      UNIQUE KEY u_cardNo (cardNo)  
  ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- 1. 执行第一次:(首次数据库表中没有数据,正常插入)
 replace into TEST1 (uname, cardNo, age) values ('_cc','436xxx1',26) ; 

-- 2. 执行第二次:(与第一次的唯一(uname)冲突,执行更新,未设置id,age字段值,观察到age用默认值null,id自增)
 replace into TEST1 (uname, cardNo) values ('_cc','436xxx2') ;

-- 3.执行第三次:(无冲突,执行插入)
 replace into TEST1 (uname, cardNo, age) values ('_hh','436xxx3',24) ;

-- 4.执行第四次:(与第一条记录uname,第二条记录cardNo两个唯一索引冲突,执行更新成功,影响条数是3)
 replace into TEST1 (uname, cardNo, age) values ('_cc','436xxx3',23) ;


总结:id为主键,sno唯一索引
添加数据 1(id),2(sno)则报错。交叉报错
解决:主键自增

以上是关于MySQL的replace into 与insert into on duplicate key update的主要内容,如果未能解决你的问题,请参考以下文章

MySQL的replace into 与insert into on duplicate key update

MySQL的replace into 与insert into on duplicate key update

mysql replace into用法详细说明

mysql中的replace into和insert into的效率问题

mysql duplicate key与replace into对比

MySql的replace into 语句