• mysql update多字段时引发的一个问题


     【1】问题描述

    该问题已在mysql5.7  8.0 均已测试出现

    create table test111(id int primary key auto_increment,a int ,b int);

    update操作前          

      

     update操作后

      

    同理(无论加不加主键索引,效果均如上图!)

    我们发现,update多个列时,如果前一个列的值被改变,后一个列表达式中如果有引用到被改变列的值,那么是修改后的;

    本来应该是 最终 a=15,b=30的,结果b=35了! 这并不是我们想要的结果;

    【2】分析解决

    (2.1)其他数据库会这样吗?不会

    以mssql为例子

      

    这里  a=a+2,b=b+a  ,这里的 b=b+a 是  a=a+2 操作之前的数据

    oracle

      

    与上面一样,这里就不解释了

    (2.2)为什么mysql会这样?

    无论我测试8.0/5.7 版本,都会这样;

    核心是因为 mysql 有 mvcc ??(参考文档中的文章是这样说的)

      但我感觉,其实是因为

    1.我感觉多列update

    2.其实是拆成了 一个一个 update

    (2.3)总结

    1=》其他数据库:查出一版结果信息来后,锁定目标行数据加载到内存,然后引用次结果集上数据做计算

      =》一次性计算出所有结果=》生成的新结果集记录到脏页;

      =》注意这里的计算是整个多列update所有表达式都一起计算的;

    2=》mysql数据库:查出一版结果信息来后,锁定目标行数据加载到内存,然后引用次结果集上数据做计算曹邹

      =》会从左到右的执行 update 的 多列更新,先最左边这个,也就是说性质是类似拆成了多个update的形式;

      如:

        update test11 set a = a+5,b = b+a where id=1;

        先执行 update test11 set a=a+5;

        =》然后再 update test11 set b=b+a;  会重新来一遍当前读,所以这里的 a 是上一个 a=a+5 之后的结果值了;

    【3】解决方案

    (方法1)如果有依赖其他列操作的update,那么则一列一列update

    (方法2)反向计算回去:  

      常规:update test11 set a = a+5,b = b+a where id=1;

      反向计算回去:update test11 set a = a+5,b = b+a-5 where id=1;

    【参考文档】

    https://www.cnblogs.com/keme/p/13101115.html

  • 相关阅读:
    MySQL中文显示乱码
    mysql 存储引擎 InnoDB 与 MyISAM 的区别和选择
    mysql 分表的3种方法
    mysql 清空或删除表数据后,控制表自增列值的方法
    MySQL 下优化SQL语句的一些经验
    mysql 常用命令
    MySQL获得指定数据表中auto_increment自增id值的方法及实例
    SQL Server Alwayson创建代理作业注意事项
    LinkedList子类与Queue接口
    List接口
  • 原文地址:https://www.cnblogs.com/gered/p/15378423.html
Copyright © 2020-2023  润新知