在工作中,会遇到这样的情形,查询数据库中是否存在一条记录信息,如果不存在则插入一条新的信息,如果存在,则更新已有的信息。
面对这样的需求,之前采用的是先读取一遍数据库,判断是否有数据,如果没有则插入一条新信息,如果有,则更新已有信息,但是这种做法在高并发情况下可能存在多个线程查询时都没有数据,于是都往数据库中插入新的记录,在插入时则会抛出异常(说该信息已在数据库中)。
后来发现,在Mysql的语法中其实提供了这么一种操作,能够完成这样的任务。语法如下:
INSERT … ON DUPLICATE KEY UPDATE field1=value1, field2=value2,…, fieldn=valuesn;
这样的语句在执行时作为一个原子操作执行,如果数据库中没有该条记录,则插入,如果有,则更新这些字段(field1=value1, field2=value2,…, fieldn=valuesn);需要说明的是,数据库表必须含有一个唯一的索引,通过该索引来标记是否存在该条记录。
以后如果遇到类型的需求,可以使用该语句,避免在程序中进行相应的逻辑判断;另外提醒一下,后面的字段赋值语句是用逗号“,”隔开哦,而不是用使用"and"逻辑连接词,如“field1=value1 and field2=value2 and fieldn=valuesn“。
说明:
INSERT 语句的一部分,如果指定 ON DUPLICATE KEY UPDATE ,并且插入行后会导致在一个UNIQUE索引或PRIMARY KEY中出现重复值,则在出现重复值的行执行UPDATE,如果不会导致唯一值列重复的问题,则插入新行。如:
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;
这两条Sql语句的结果是相同的。
为甚说需要这种方式呢!这种方式不需要维护索引效率上比先删除再插入要快的多。
MySql 官方解释:https://dev.mysql.com/doc/refman/5.7/en/insert-on-duplicate.html