开心一刻
今天,她给我打来电话
她:你明天陪我去趟医院吧
我:怎么了
她:我怀孕了,陪我去打胎
我:他的吗
她:嗯
我心一沉,犹豫了片刻:生下来吧,我养!
她:他的孩子,你不配养!
我:我随孩子姓
需求背景
最近接到一个数据迁移的需求,旧系统的数据迁移到新系统;旧系统不会再新增业务数据,业务操作都在新系统上进行
为了降低迁移的影响,数据进行分批迁移,也就是说新旧系统会并行一段时间
数据分批不是根据 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 类型的默认值: 空字符串('')
小结下
NOT NULL 的字段设置 NULL
NOT NULL 的字段设置 NULL
关于字段类型的默认值,可查看:Data Type Default Values
sql_mode ,可查看:Server SQL Modes
MySQL 一般都是严格模式,所以大家知道有 value DEFAULT
SET 字段顺序
SQL
想必大家都很清楚
SQL 中的 name
我们来看下结果
name
UPDATE 的 SET 是从左往右进行的,然而多表 UPDATE 却不是,多表 UPDATE
总结
UPDATE ,还是 DELETE
UPDATE 语法中的 LOW_PRIORITY 很少用, IGNORE 偶尔用, ORDER BY 和 LIMIT
sql_mode
参考