mysql使用中关于INSERT的操作

615 阅读4分钟

本文已参与「新人创作礼」活动.一起开启掘金创作之路。

INSERT INTO

这个不用多说,用的最多的插入语句了,直接插入一条数据,如果主键/唯一索引等冲突,会报错。

REPLACE INTO

替换数据,insert into 的增强版,SQL 语句中必须存在主键或者唯一键,如果存在,则更新,否则插入。

在向表中插入数据的时候,经常遇到这样的情况:1. 首先判断数据是否存在; 2. 如果不存在,则插入;3.如果存在,则更新。

在MySQL 中有更简单的方法: replace into

replace into 跟 insert 功能类似,不同点在于:replace into 首先尝试插入数据到表中, 1. 如果发现表中已经有此行数据(根据主键或者唯一索引判断)则先删除此行数据,然后插入新的数据。 2. 否则,直接插入新数据。

replace into 有三种形式:

  • replace into tbl_name(col_name, ...) values(...)
  • replace into tbl_name(col_name, ...) select ...
  • replace into tbl_name set col_name=value, ...

新增一表测试表,sql如下 :

image.png

首先使用INSERT INTO向表中插入一条数据:

image.png

image.png

使用如下图所示中使用 replace into插入两条数据后发现base_code为11的唯一索引一行数据主键id由原来的1变成了2,执行结果也显示了3条生效,具体是因为在插入base_code 为11的这条数据时,发现唯一索引重复,mysql先执行了delete删除了这条数据,然后在执行了插入操作。

image.png

image.png

image.png

INSERT IGNORE INTO

插入数据,SQL 语句中必须存在主键或者唯一键,如果存在,则忽略,否则插入。

如下图,可以看到执行结果实际只有一条成功,其中base_code为11、33的数据由于重复了,故直接忽略。

image.png

INSERT INTO ON DUPLICATE KEY UPDATE

insert into on duplicate key update与replace into两个操作在插入的数据主键不存在的情况下没有实际上的区别,区别是当主键/唯一键存在的情况下, replace into 会把所有除了主键的数据全部替换(这是判断依据,自然没法修改) 成新的数据(没有的属性会自动设置为默认属性),insert into on duplicate key update 在主键存在的情况下会把要修改的属性字段替换掉,不在修改范围的字段不做操作,简单来说就是所谓的全部更新和部分更新的区别。

如下图所示:

image.png

image.png

那么为什么使用on duplicate key update时执行结果显示的是2行生效呢?

因为mysql主键自增有个参数innodb_autoinc_lock_mode,他有三种可能只0、1、2,mysql5.1之后加入的,默认值是1,之前的版本可以看做都是0,可以使用语句:select @@innodb_autoinc_lock_mode。若数据库值为1,当做简单插入(可以确定插入行数)的时候,直接将auto_increment加1,而不会去锁表,这也就提高了性能。当插入的语句类似insert into select ...这种复杂语句的时候,提前不知道插入的行数,这个时候就要要锁表(一个名为AUTO_INC的特殊表锁)了,这样auto_increment才是准确的,等待语句结束的时候才释放锁,其中还有一种称为Mixed-mode inserts的插入,比如INSERT INTO t1 (c1,c2) VALUES (1,'a'), (NULL,'b'), (5,'c'), (NULL,'d'),其中一部分明确指定了自增主键值,一部分未指定,我们这里讨论的INSERT ... ON DUPLICATE KEY UPDATE ...也属于这种,这个时候会分析语句,然后按尽可能多的情况去分配auto_increment自增id,其实简单来说就是我提前知道了你要插入多少行数据,然后生成了多少个id,但是你其中的有一些数据没有使用我生成的id,那怎么办,id已经生成了无法回滚了 。感兴趣的小伙伴可以参考这篇文档:www.cnblogs.com/abclife/p/7… 、 blog.itpub.net/15498/views…

实际业务场景: 当数据交换任务,进行数据库插入数据时,如果配置的映射列,不是所有映射列,则要使用on duplicate key update只更新或插入部分列的数据,不能使用replace into,否则会把其他列原有的值给删除掉了。