INSERT REPLACE UPDATE区别

本文探讨了在MySQL中处理数据记录的常见场景,包括如何使用replace into、insert into on duplicate key update等语句高效地检查并更新记录。同时介绍了insert ignore、insert delayed等特性,以及在大规模数据更新时的策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在日常的开发中,经常会遇到如下的场景:查看某条记录是否存在,不存在的话创建一条心记录,存在的话更新某些字段。一般的处理方式如下

$result = mysql_query('select * from xxx where id = 1');
$row = mysql_fetch_assoc($result);
if($row){
    mysql_query('update ...');
}else{
    mysql_query('insert ...');
}

这样的写法可能有如下几点缺陷:

  • 少量的性能消耗。执行了两次sql,按照一条sql一去一回两次网络传输的话,那么这就是4次。
  • 麻烦。一个很简单的逻辑缺要写十来行代码。
  • 在高并发下会出问题。比如当我们获取到了需要的数据,在更新之前,有另外一个请求恰好删除了该条记录,我们的更新操作就没起到作用;再或者,如果我们更新操作的写法有问题,比如更新列a,我们使用a = $row[a] + 1而不是a = a +1这种原子性的操作,有可能别的请求已经修改过了该字段,从而造成数据出错。

在mysql中,replace into ...和insert into ... on duplicate key update ... 都可以实现,那么这两种有什么区别呢
replace into和on duplcate key update都是只有在primary key或者unique key冲突的时候才会执行。如果数据存在,replace into则会将原有数据删除,再进行插入操作,这样就会有一种情况,如果某些字段有默认值,但是replace into语句的字段不完整,则会设置成默认值。而on duplicate key update则是执行update后面的语句.自增主键不会发生改变

insert into test values(null, 'unique', '654321') on duplicate key update id=LAST_INSERT_ID(id),col1 = 'update_unique';

insert ignore表示,如果表中如果已经存在相同的记录,则忽略当前新数据;
测试代码如下:

create table testtb(
  id int not null primary key,
  name varchar(50),
  age int
);
insert into testtb(id,name,age)values(1,"bb",13);
select * from testtb;
insert ignore into testtb(id,name,age)values(1,"aa",13);
select * from testtb;//仍是1,“bb”,13,因为id是主键,出现主键重复但使用了ignore则错误被忽略
replace into testtb(id,name,age)values(1,"aa",12);
select * from testtb; //数据变为1,"aa",12

INSERT IGNORE INTO与INSERT INTO的区别就是INSERT IGNORE会忽略数据库中已经存在的数据,如果数据库没有数据,就插入新的数据,如果有数据的话就跳过这条数据。这样就可以保留数据库中已经存在数据,达到在间隙中插入数据的目的。

用于INSERT 语句的DELAYED 选项是MySQL 相对于标准SQL 的扩展。如果您的客户端不能等待INSERT 完成,则这个选项是非常有用的。当您使用MySQL 进行日志编写时,这是非常常见的问题。您也可以定期运行SELECT 和UPDATE 语句,这些语句花费的时间较长。

当一个客户端使用INSERT DELAYED 时,会立刻从服务器处得到一个确定。并且行被排入队列,当表没有被其它线程使用时,此行被插入。

使用INSERT DELAYED 的另一个重要的好处是,来自许多客户端的插入被集中在一起,并被编写入一个块。这比执行许多独立的插入要快很多。

说明: INSERT DELAYED INTO,是客户端提交数据给MySQL,MySQL返回OK状态给客户端。而这是并不是已经将数据插入表,而是存储在内存里面等待排队。当mysql有空余时,再插入。

  这样的好处是,提高插入的速度,客户端不需要等待太长时间。坏处是,不能返回自动递增的ID,以及系统崩溃时,MySQL还没有来得及插入数据的话,这些数据将会丢失。

注意,当没有使用表时,INSERT DELAYED 比常规的INSERT 要慢。对于服务器来说,为每个含有延迟行的表操纵一个独立的线程,也是一个额外的系统开销。这意味着只有当您确认您需要时,才应使用INSERT DELAYED 。

Mysql 大表更新策略

如果是在数据量比较小的情况下(万级别),可以直接执行sql语句,但是如果数据量达到一个量级后,就会出现一些问题,比如主从架构部署的Mysql,主从同步需要需要binlog来完成。全表update会给主库生成binlog、从库接收binlog写数据带来很大的压力。解决方法加Limit,where加主键

update aa set status=4 where status=1 and id<10000 limit 1000

配合循环执行,更新成功会返回变更行数。注意:使用where条件会自动排除更新过的数据。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值