我们先来看下MySQL官网对于两者的解释:

然后用一个小实例简单说明下:

replace into 和insert into都是基于唯一索引或主键基础上使用的,必须有主键或唯一索引

首先创建一张test表

DROP TABLE IF EXISTS `test`;
CREATE TABLE `test` (
  `id` bigint(20) NOT NULL COMMENT '主键ID',
  `name` varchar(50) DEFAULT NULL,
  `phone` varchar(50) DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='测试表';

执行单条语句测试

--执行单条数据的insert into
[SQL]INSERT INTO test (id, NAME, phone) VALUES('1', '张三', '13810597914');
受影响的行: 1
时间: 0.024s

--执行单条数据的replace into
[SQL]REPLACE INTO test (id, NAME, phone) VALUES('2', '李四', '13810597915');
受影响的行: 1
时间: 0.023s

由上可见: 当主键和唯一索引 'id' 列不重复,两者执行时间及影响行数(插入的方式)基本等同

--再来看看主键重复的情况 
--1、执行insert into
[SQL]INSERT INTO test (id, NAME, phone) VALUES('2', '李四san', '13810597915');
[Err] 1062 - Duplicate entry '2' for key 'PRIMARY'

--2、执行replace into
[SQL]REPLACE INTO test (id, NAME, phone) VALUES('2', '李四san', '13810597915');
受影响的行: 2
时间: 0.026s

可以看到inset into是不允许添加主键重复列的,而replace可以,且影响行数是2,再结合MySQL官网的文档解释是不是就清晰了,replace into用于不知道操作为更新还是新增的时候,使用时,先尝试直接向库中插入数据,遇到主键或唯一索引而引发的重复键错误时,删除掉冲突行并再次尝试插入,这个过程是MySQL自行处理的,并不会存在用户感知之类的

再说下MySQL replace into 的三种使用形式:

1. replace into test(id,name ...) values(...)

2. replace into test(id,name, ...) select ...

3. replace into test set id=value, name=value,...

第一种形式类似于insert into的用法,

第二种replace select的用法也类似于insert select,这种用法并不一定要求列名匹配,事实上,MYSQL甚至不关心select返回的列名,它需要的是列的位置。例如,replace into test ( id, name, phone) select id, name, address from test2;?这个例子使用replace into从?test2中将所有数据导入test1中。

第三种replace set用法类似于update set用法,使用一个例如“SET col_name = col_name + 1”的赋值,则对位于右侧的列名称的引用会被作为DEFAULT(col_name)处理。因此,该赋值相当于SET col_name = DEFAULT(col_name) + 1。

前两种形式用的多些。其中 “into” 关键字可以省略,不过最好加上 “into”,这样意思更加直观。另外,对于那些没有给予值的列,MySQL 将自动为这些列赋上默认值。

最后总结一下吧:

replace into执行过程主键冲突总是删除后插入新记录

replace into主键相同,主键之外字段会得到更新,主键不同功能同insert into 

replace into和insert into区别在于insert into插入与主键相同记录会报错而前者不会

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐