开心一刻

  今天,她给我打来电话

  她:你明天陪我去趟医院吧

  我:怎么了

  她:我怀孕了,陪我去打胎

  我:他的吗

  她:嗯

  我心一沉,犹豫了片刻:生下来吧,我养!

  她:他的孩子,你不配养!

  我:我随孩子姓

需求背景

  最近接到一个数据迁移的需求,旧系统的数据迁移到新系统;旧系统不会再新增业务数据,业务操作都在新系统上进行

  为了降低迁移的影响,数据进行分批迁移,也就是说新旧系统会并行一段时间

  数据分批不是根据 id 范围来分的,也就说每批数据的 id 都是无规律的

  另外,为了保证新旧系统数据的对应,新系统的 id 尽可能的沿用旧系统的 id

  因为表 id 在新旧系统都是自增的,所以迁移的时候,旧系统的 id 可能在新系统已经被占用了,类似如下

  需求描述

  数据迁移的时候,尽可能沿用旧系统的 id,而冲突的 id 需要进行批量调整

  如何调整这批冲突的 id,正是我当下要实现的需求

  我的实现是根据业务数据的增长情况,结合目前新系统的最大 id 来预设一个起始的 id

  

  这个 SQL 该如何写?

  需求实现

  有小伙伴可能觉得,这还不简单?

  不就 5 条数据嘛,这么写不就搞定了

  多简单的事,还铺垫那么多,楼主你到底会不会?

  楼主此刻幡然醒悟:小伙伴,你好厉害哇哦

  但是如果冲突的数据很多了(几百上千),你也这样一条一条改?

  如果你真这样做,我是真心佩服你

  很显然,理智的小伙伴更多

  那该如何实现了?

  楼主就不卖关子了,可以用局部变量 +  UPDATE 来实现,直接上 SQL

  我们来看实际案例

  表 tbl_batch_update

  数据如下

  执行效果如下

  更新之后

  更严谨点

  该如何实现?  UPDATE 是不是也支持 ORDER BY ?

  还真支持,如下所示

  楼主平时使用 UPDATE 的时候,基本没结合 ORDER BY ,也没尝试过结合 LIMIT

  这次尝试让楼主对 UPDATE 产生了陌生的感觉,它的完整语法应该是怎样的?我们慢慢往下看

UPDATE

  下文都是基于 MySQL 8.0 的官方文档 UPDATE Statement 整理而来,推荐大家直接去看官方文档

  单表语法

  是不是有很多疑问:

  多表语法

  相比于单表,貌似更简单一些,不支持 ORDER BY 和  LIMIT

  LOW_PRIORITY

   UPDATE 的修饰符之一,用来降低 SQL 的优先级

  当使用 LOW_PRIORITY 之后, UPDATE 的执行将会被延迟,直到没有其他客户端从表中读取数据为止

  但是,只有表级锁的存储引擎才支持 LOW_PRIORITY ,表级锁的存储引擎包括: MyISAM 、 MEMORY 和 MERGE ,所以最常用的 InnoDB 是不支持的

  使用场景很少,混个眼熟就好

  IGNORE

   UPDATE 的修饰符之一,用来声明 SQL 执行时发生错误的处理方式

  如果没有使用 IGNORE , UPDATE 执行时如果发生错误会中止,如下所示

   9002 更新成 9003 的时候,主键冲突,整个 UPDATE 中止, 9000 更新成的 9001 会回滚, 9003 ~ 9005 还未执行更新

  如果使用 IGNORE ,会是什么情况了?

   UPDATE 执行期间即使发生错误了,也会执行完成,最终返回受影响的行数

  上述返回受影响的行是 2 ,你们说说是哪两行修改了?

  更多关于 IGNORE 的信息,请查看:The Effect of IGNORE on Statement Execution

  关于使用场景,在新旧系统并行,做数据迁移的时候可能会用到,主键或者唯一键冲突的时候直接忽略

  ORDER BY

  如果大家对 UDPATE 的执行流程了解的话,那就更好理解了

   UPDATE 其实有两个阶段: 查阶段 、 更新阶段

  一行一行的处理,查到一行满足 WHERE 子句,就更新一行

  所以,这里的 ORDER BY 就和 SELECT 中的 ORDER BY 是一样的效果

  关于使用场景,大家可以回过头去看看前面讲到的的需求背景,

  IGNORE 的案例 1 中的报错,其实也可以用 ORDER BY

  LIMIT

   LIMIT row_count 子句是行匹配限制。一旦找到满足 WHERE 子句的 row_count 行,无论这些行是否实际更改,该语句都会立即停止

  也是就说 LIMIT 限制的是 查阶段 ,与 更新阶段 没有关系

  注意:与 SELECT 语法中的 LIMIT

  还是有区别的

  value DEFAULT

   UPDATE 中 SET 子句的 value 是表达式,我们可以理解,这个 DEFAULT 是什么意思?

  我们先来看这么一个问题,假设某列被声明了 NOT NULL ,然而我们更新这列成 NULL

  会发生什么

  我们看下 SQL_MODE ,执行 SELECT @@sql_mode; 得到结果

   STRICT_TRANS_TABLES 表明启动了严格模式,对 INSERT 和 UPDATE 语句的 value 管控会更严格

  如果我们关闭严格模式,再看看执行结果

   name 字段声明成了 NOT NULL ,非严格 SQL 模式下,将 name 设置成 NULL 是成功的,但更改的值并非 NULL ,而是 VARCHAR 类型的默认值: 空字符串('')

  小结下

    1、严格 SQL 模式下,对 NOT NULL 的字段设置 NULL ,会直接报错,更新失败

    2、非严格 SQL 模式下,对 NOT NULL 的字段设置 NULL ,会将字段值设置字段类型对应的默认值

  关于字段类型的默认值,可查看:Data Type Default Values

  关于 sql_mode ,可查看:Server SQL Modes

  通常情况下,生成环境的 MySQL 一般都是严格模式,所以大家知道有 value DEFAULT 这回事就够了

  SET 字段顺序

  针对如下 SQL

  想必大家都很清楚

  然而,以下 SQL 中的 name 列的值会是多少

  我们来看下结果

   name 的值是不是和预想的有点不一样?

  单表 UPDATE 的 SET 是从左往右进行的,然而多表 UPDATE 却不是,多表 UPDATE 不能保证按任何特定顺序进行

总结

  1、不管是 UPDATE ,还是 DELETE ,都有一个先查的过程,查到一行处理一行

  2、 UPDATE 语法中的 LOW_PRIORITY 很少用, IGNORE 偶尔用, ORDER BY 和 LIMIT 相对会用的多一点,都混个眼熟

  3、 sql_mode 是比较重要的知识点,推荐大家掌握;生产环境,强烈推荐开启严格模式

参考

  UPDATE Statement

记一次批量更新整型类型的列 → 探究 UPDATE 的使用细节的更多相关文章

  1. 深入理解Java的整型类型:如何实现2+2=5?

    先看下这段神奇的Java代码: public static void main(String[] args) throws Exception { doSomethingMagic(); System ...

  2. 零基础如何学好Python 之int 数字整型类型 定义int()范围大小转换

    本文主题是讲python数字类型python int整型使用方法及技巧.它是不可变数据类型中的一种,它的一些性质和字符串是一样的,注意是整型不是整形哦. Python int有多种数字类型:整型int ...

  3. golang的数据类型之整型类型

    数据类型: 整数 : int, int32, int64, uint, uint32, uint64 字符串 : string 布尔:bool 浮点:float32 float64 uint 表示无符 ...

  4. MySql中4种批量更新的方法update table2,table1,批量更新用insert into ...on duplicate key update, 慎用replace into.

    mysql 批量更新记录 MySql中4种批量更新的方法最近在完成MySql项目集成的情况下,需要增加批量更新的功能,根据网上的资料整理了一下,很好用,都测试过,可以直接使用. mysql 批量更新共 ...

  5. 一些平台无关的整型类型,int8_t,uint8_t....

    pecific integral type limits Specifier Common Equivalent Signing Bits Bytes Minimum Value Maximum Va ...

  6. MySQL各种日期类型与整型(转)

    日期类型 存储空间 日期格式 日期范围 datetime 8 bytes YYYY-MM-DD HH:MM:SS 1000-01-01 00:00:00 ~ 9999-12-31 23:59:59 t ...

  7. Docs-.NET-C#-指南-语言参考-关键字-内置类型-值类型:整型数值类型

    ylbtech-Docs-.NET-C#-指南-语言参考-关键字-内置类型-值类型:整型数值类型 1.返回顶部 1. 整型数值类型(C# 参考) 2019/10/22 “整型数值类型”是“简单类型”的 ...

  8. 计算机二级-C语言-字符数字转化为整型数字。形参与实参类型相一致。double类型的使用。

    //函数fun功能:将a和b所指的两个字符串分别转化成面值相同的整数,并进行相加作为函数值返回,规定只含有9个以下数字字符. //重难点:字符数字转化为整型数字. #include <stdio ...

  9. MySQL 整型

    MySQL中我们建表的时候,类型可以用bigint(20), 这是什么意思呢? 首先我们看bigint, MySQL的整型类型有这样几种: 类型      占用字节 tinyint        1 ...

随机推荐

  1. 001 Security概述

    1.Spring Security概述 Spring Security是用于解决认证与授权的框架 SpringSecurity默认要求所有的请求都是必须先登录才允许的访问 BCrypt加密算法 BCr ...

  2. 对象数组的foreach循环操作和集合容器

    ForEach标签可以循环数组,list,map集合 采用 foreach循环遍历 ,并每次循环允许执行一次回调函数 for (容器中元素类型 临时变量: 容器变量) { System.out.pri ...

  3. static关键字和代码块

    static关键字 static修饰的变量称为静态变量/共享变量/类变量 用于修饰类的成员,如成员变量.成员方法以及代码块等,内static修饰的成员具备一些特殊性 1.静态变量 在java类中使用s ...

  4. JVM内存模型和结构详解(五大模型图解)

    JVM内存模型和Java内存模型都是面试的热点问题,名字看感觉都差不多,实际上他们之间差别还是挺大的. 通俗点说,JVM内存结构是与JVM的内部存储结构相关,而Java内存模型是与多线程编程相关@mi ...

  5. JUC源码学习笔记5——线程池,FutureTask,Executor框架源码解析

    JUC源码学习笔记5--线程池,FutureTask,Executor框架源码解析 源码基于JDK8 参考了美团技术博客 https://tech.meituan.com/2020/04/02/jav ...

  6. HCIA-datacom 4.3 实验三:网络地址转换配置实验

    实验介绍: 网络地址转换NAT(Network Address Translation)是将IP数据报文头中的IP地址转换为另一个IP地址的过程.作为减缓IP地址枯竭的一种过渡方案,NAT通过地址重用 ...

  7. Web 布局设计(一):固定侧边栏

    前言 闲着无事,做一些实战练习,今天实现一个如标题所示的布局设计.通过此次布局设计,我希望掌握position属性值 fixed.absolute.relative.width和height属性值 i ...

  8. Dart 异步编程(二):async/await

    对每一个异步任务返回的 Future 对象都使用链式操作-- then ,超过三个以上时,导致"倒三角"现象,降低代码的可阅读性. getHobbies() { post('htt ...

  9. 从零开始搭建react基础开发环境(基于webpack5)

    前言 最近利用闲暇时间把webpack系统的学习了下,搭建出一个react环境的脚手架,写篇文章总结一下,帮助正在学习webpack小伙伴们,如有写的不对的地方或还有可以优化的地方,望大佬们指出,及时 ...

  10. 01 - 快速体验 Spring Security 5.7.2 | 权限管理基础

    在前面SpringBoot 2.7.2 的系列文章中,已经创建了几个 computer 相关的接口,这些接口直接通过 Spring Doc 或 POSTMAN 就可以访问.例如: GET http:/ ...