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

戳蓝字「TopCoder 」关注我们哦!

平常使用 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不会执行。具体验证可以通过以下几个命令:

show master status\G
set  binlog_format ='row'; // statement
show variables like 'binlog_format';
update xxx

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

TopCoder
我还没有学会写个人说明!
上一篇

使用Python+PyTorch预测野外火灾

下一篇

如何生成玫瑰?|数字艺术

你也可能喜欢

评论已经被关闭。

插入图片