mysql一条sql实现更新或者插入
业务场景
一批数据需要插入到数据库,根据数据中的某些字段(条件)判断这个数据是插入还是更新
例如:
有一个用户表(user),有id,name,sex,tel(唯一索引),email,address字段,其中tel字段是唯一不可重复的,如果一批数据插入这个表,通常的做法是先逐个查询再根据结构判断是插入还是更新。
其实mysql提供了一种更简单的实现方式
mysql实现方式
mysql提供的方式就是这种:存在即更新
ON DUPLICATE KEY UPDATE
该语法在insert的时候,如果insert的数据会引起唯一索引(包括主键索引)的冲突,即这个唯一值重复了,则不会执行insert操作,而执行后面的update操作。
例如:
insert into user(name,sex,tel,email,address)
values(#{user.name},#{user.sex},#{user.tel},#{user.email},#{user.address})
ON DUPLICATE KEY UPDATE
address = VALUES(address)
这句sql的执行是首先mysql会先尝试插入,如果插入失败就修改地址,返回的影响函数为2
注意事项
1、ON DUPLICATE KEY UPDATE 会以表的索引或主键(索引优先)为标识,进行数据查询更新。
(1)当存在索引时,以索引为身份标识,判定新旧两条记录是否为同一对象,从而进行更新;
(2)当索引不存在时,则以主键作为身份标识,进行数据更新。
2、匹配到多条记录时,只会更新一条记录,其它记录会忽略。
3、原表中存在的数据,但在新表中不存在时,新表数据更新到旧表中后,该记录不会被删除(如果需要标识数据已失效,需采用其它办法)
4、如果数据库使用自增主键,执行sql影响函数为2,会造成id跳跃一位。例如id为5的数据执行了更新,下一条插入的数据id为7,会跳跃6
5、在高并发的环境下会出现死锁的问题