最常见的方式就是为字段设置主键或唯一索引,当插入重复数据时,抛出错误,程序终止,但这会给后续处理带来麻烦,因此需要对插入语句做特殊处理,尽量避开或忽略异常。
新建了一个User
测试表,主要有id,username,sex,address
这4个字段,其中主键为id(自增),同时对username字段设置了唯一索引。
insert ignore into
插入数据时,如果数据存在,则忽略此次插入,前提条件是插入的数据字段设置了主键或唯一索引
。
测试SQL语句如下,当插入本条数据时,MySQL数据库会首先根据username
唯一索引检索已有数据,如果存在,则忽略本次插入,如果不存在,则正常插入数据:
insert ignore into User(username, sex, address) values('James', 'male', 'SH');
运行第一次,数据库正常插入一条数据,影响行数为1。
运行第二次,因为数据库存在一条数据,忽略本次插入,影响行数为0。
on duplicate key update
插入数据时,如果数据存在,则执行更新操作,前提条件同上,也是插入的数据字段设置了主键或唯一索引。
测试SQL语句如下,当插入本条记录时,MySQL数据库会首先根据username
唯一索引检索已有数据,如果存在,则执行update更新操作,如果不存在,则直接插入:
insert into User(username, sex, address) values('Allen', 'male', 'NJ') on duplicate key
update sex = 'male', address = 'NJ';
运行第一次,数据库不存在,插入一条数据,影响行数为1。
运行第二次,因为数据库存在,且更新字段数据一样,不做任何操作,影响行数为0。
insert into User(username, sex, address) values('Allen', 'female', 'BJ') on duplicate key
update sex = 'female', address = 'BJ';
运行一次,数据库存在,且更新字段数据不一样,更新数据,影响行数为2。
replace into
插入数据时,如果数据存在,则删除再插入,前提条件同上。
测试SQL语句如下,当插入本条记录时,MySQL数据库会首先根据username
唯一索引检索已有数据,如果存在,则先删除旧数据,然后再插入,如果不存在,则直接插入:
replace into User(username, sex, address) values('Tom', 'female', 'BJ');
运行第一次,数据库不存在,插入一条数据,影响行数为1。
运行第二次,因为数据库存在,先删除数据,然后再插入数据(注意这里是重新插入,不是更新),所以影响行数为0。
insert if not exists
insert into … select … where not exist ..
. ,这种方式适合于插入的数据字段没有设置主键或唯一索引,当插入一条数据时,首先判断MySQL数据库中是否存在这条数据,如果不存在,则正常插入,如果存在,则忽略: