mysql更新数据查询还是老数据_mysql update语句和原数据一样会更新么

平常使用 mysql ,必不可少的会用到 update 语句,不知道小伙伴有没有这样的疑问?

如果 update 语句和原数据一样会更新么?更具体的来说,如果更新的数据前后是一样的,MySQL 会更新存储引擎中(磁盘)数据么?

关于这个问题,在分析之前我们可以思考下:update语句和原数据一样,有必要更新么?理论上来讲是没有必要的。MySQL Server 层在执行 sql 时,其实是不知道是否是一样的,因此可以猜想,如果 MySQL 已经知道原数据的话,这样可以和 update 语句做对比,这样一样的话可以不用更新了。

那么 MySQL 在执行update 语句时,什么时候会读取原数据呢?这就涉及到 binlog 的数据格式,binlog 数据格式相关配置项为binlog_format,该配置取值范围如下:statement:逻辑SQL格式,通过mysqlbinlog工具可进行查看,就是sql语句;

row:记录的是行更改日志,对于statement格式binlog复制潜在的问题可通过row来解决;

mixed:默认使用statement格式,某些操作下使用row格式,比如uuid/now/user等不确定函数。

注意:在msyql 5.1版本之前默认都是基于sql语句(statement)级别的,statement格式的binlog会造成某些操作在主从复制时出现问题,比如now/rand/uuid等。

row 格式的 binlog 会记录镜像数据,针对 update 来说,必须是前镜像数据才能判断出来update 语句是否和原数据一样。针对 row 格式的镜像数据配置,由配置项binlog_row_image来决定(该配置只在 row 模式下才起作用),该配置项官方文档如下:full: Log all columns in both the before image and the after image.

minimal: Log only those columns in the before image that are required to identify the row to be changed; log only those columns in the after image where a value was specified by the SQL statement, or generated by auto-increment.

noblob: Log all columns (same as full), except for BLOB and TEXT columns that are not required to identify rows, or that have not changed.

简单来说,full会记录所有列,noblob会记录除blob和text外的所有列,minimal只会记录需要的列。对于insert 来说,只有后镜像没有前镜像;对于update来说,有前镜像和后镜像;对于delete来说,只有前镜像没有后镜像。对于 full 和 noblob 没有什么好说的,对于minimal来说,insert 记录所有列后镜像,update 和 delete的话要分为几种情况:当存在主键索引或者唯一索引时,update记录主键列前镜像和更新列后镜像,delete 记录主键列前镜像。

只有普通二级索引时,update 记录所有列前镜像和更新列后镜像,delete 记录所有列前镜像。

针对minimal的binlog_row_image为什么要这么设计呢?有主键或者唯一键的话,可以通过其定位到唯一一条记录,因此没有必要记录整个列的镜像数据了,在只有二级索引或者其他情况下,只能记录整个列的镜像数据。

那么日常开发中,应该怎么配置binlog_row_image呢?建议配置成 full 模式,因为这样可以以空间换取更多的数据保证,可以避免binlog 的闪回功能。

回到最初提到的问题,可以知道,在binlog_format=row时,由于MySQL 需要在 binlog 里面记录数据对应字段,因此会进行数据的读取操作,此时就可以进行数据对比,重复数据的update不会执行。具体验证可以通过以下几个命令:

show master status\G

set binlog_format ='row'; // statement

show variables like 'binlog_format';

update xxx

针对 uddate 语句和原数据一样时可能不会进行更新操作,因此该场景下返回的影响行数可能为0。

推荐阅读CompletableFuture 应用实践​mp.weixin.qq.com6bcc7c0a6d96eeb9066fb38e21cb1b0c.pngJava线程池实现原理​mp.weixin.qq.com500a1a57618a9b12a8d3a07120e83409.png深入理解Java线程池​mp.weixin.qq.com8e4980ba6d9b4569c5a8bd62dbdf402e.pngJMM Java内存模型​mp.weixin.qq.com158b3f8f243c61fa1050d16d7ad374d8.pnghappens-before那些事儿​mp.weixin.qq.come3b831611301e10f024afa30a32542d1.png为什么说LockSupport是Java并发的基石?​mp.weixin.qq.com4f24ec71a4be9596d49fe1e845fdc306.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值