最常见的方式就是为字段设置主键或唯一索引,当插入重复数据时,抛出错误,程序终止,但这会给后续处理带来麻烦,因此需要对插入语句做特殊处理,尽量避开或忽略异常。

新建了一个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数据库中是否存在这条数据,如果不存在,则正常插入,如果存在,则忽略: