演示MySQL中,插入或替换、插入或更新、插入或忽略等语句的用法。
创建一个空表作为演示,其中字段id
为主键,字段num
为唯一索引
CREATE TABLE student (
id int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
num varchar(20) NOT NULL COMMENT '学生学号',
name varchar(20) NOT NULL COMMENT '学生姓名',
PRIMARY KEY (id),
UNIQUE KEY uk_num (num) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
尝试往表插入一条记录,如果记录不存在,则直接插入(insert);如果记录已存在,则先删除原记录,再插入(delete + insert)。
判断记录存在与否,是根据表的PRIMARY KEY
或者UNIQUE index
执行replace
语句,由于表中还没任何记录,所以插入的记录肯定在表中不存在。数据库直接插入记录,受影响行数为1
replace into student(id, num, name) values (1, '1001', '张三');
此时表所有记录如下图所示
继续执行另一个replace
语句,由于字段num
为唯一索引,尝试插入的记录的num
值也是1001
,所以表中其实已存在了重复的记录。数据库先把判断为重复的记录删除,再插入新记录,受影响行数为2
replace into student(id, num, name) values(2, '1001', '李四');
尝试往表插入一条记录,如果记录不存在,则直接插入(insert);如果记录已存在,则更新该记录,更新的字段由
ON DUPLICATE KEY UPDATE
子句中的UPDATE
指定。
判断记录存在与否,是根据表的PRIMARY KEY
或者UNIQUE index
为方便查看,这里先清除表所有记录
delete from student;
执行insert
语句,带上on duplicate key update
子句,由于表中暂时无记录,不会造成“记录存在”的情况,数据库直接插入记录,受影响行数为1
insert into student(id, num, name) values (1, '1001', '张三') on duplicate key update name = '李四';
继续执行刚刚的insert
语句,由于尝试插入的记录无论根据主键id
字段,还是唯一索引num
字段,都是表中已存在的记录,所以数据库根据update
指定的字段,更新记录的name
为“李四”,受影响行数为2(为啥是2,请继续往下看)
insert into student(id, num, name) values (1, '1001', '张三') on duplicate key update name = '李四';
此时表所有记录如下图所示
继续第三次执行刚刚的insert
语句,此时数据库受影响行数为0,差不多相当于数据库并没有执行这个语句,其对数据库记录不造成任何改变。
insert into student(id, num, name) values (1, '1001', '张三') on duplicate key update name = '李四';
With ON DUPLICATE KEY UPDATE, the affected-rows value per row is 1 if the row is inserted as a new row, 2 if an existing row is updated, and 0 if an existing row is set to its current values.
可知执行插入或更新语句时,如果原先记录不存在,那么插入新记录,受影响行数是1,这容易理解。但如果原先记录存在,执行更新操作时,则分两种情况:一种是update
指定的更新字段的值跟原先记录的不一样,则受影响行数是2,另一种是update
指定的更新字段的值跟原先记录的一模一样,则受影响行数是0
尝试往表插入一条记录,如果记录不存在,则直接插入(insert);如果记录已存在,则直接忽略,啥事也不干。
判断记录存在与否,是根据表的PRIMARY KEY
或者UNIQUE index
类似地,为方便查看,这里先清除表所有记录
delete from student;
执行下面insert
语句,跟普通的insert
语句差不多,只是多了一个修饰语ignore
insert ignore into student(id, num, name) values (1, '1001', '张三');
此时表所有记录如下图所示
继续执行刚刚的insert
语句,由于表中已存在对应记录,故数据库不执行任何操作,受影响行数为0
insert ignore into student(id, num, name) values (1, '1001', '张三');
如果将ignore
修饰符去掉,执行相应insert
语句,数据库报错,操作被中断。
insert into student(id, num, name) values (1, '1001', '张三');
执行操作 | SQL语法 | 记录不存在 | 记录存在 | 说明 |
---|---|---|---|---|
插入或替换 | replace 语句 | insert | delete + insert | MySQL对标准SQL的一个扩展 |
插入或更新 | insert 语句 | insert | update | MySQL insert 语句的一个子句 |
插入或忽略 | insert 语句 | insert | 空操作 | MySQL insert 语句的一个修饰符 |