前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >mysql update语句和原数据一样会更新么

mysql update语句和原数据一样会更新么

作者头像
luoxn28
发布2021-01-18 14:46:49
1.7K0
发布2021-01-18 14:46:49
举报
文章被收录于专栏:TopCoderTopCoder

平常使用 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 模式下才起作用),该配置项官方文档如下:

  1. full: Log all columns in both the before image and the after image.
  2. 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.
  3. 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不会执行。具体验证可以通过以下几个命令:

代码语言:javascript
复制
show master status\G
set  binlog_format ='row'; // statement
show variables like 'binlog_format';
update xxx

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

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-01-01,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 TopCoder 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云数据库 SQL Server
腾讯云数据库 SQL Server (TencentDB for SQL Server)是业界最常用的商用数据库之一,对基于 Windows 架构的应用程序具有完美的支持。TencentDB for SQL Server 拥有微软正版授权,可持续为用户提供最新的功能,避免未授权使用软件的风险。具有即开即用、稳定可靠、安全运行、弹性扩缩等特点。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档