工程与技术实践 / 人类知识全景图 / 数据库演进

数据库演进全景图

回答“数据库已经承载生产状态以后,表结构、历史数据、服务边界和迁移路径怎样继续安全变化”

阅读边界: 这页不是数据库选型页,也不是 SQL 调优手册。 这里关注的是系统已经在生产里跑起来之后,数据库如何继续演进: schema 变更、在线迁移、双写双读、回填校验、数据 ownership、历史数据修复、回滚边界和旧链路退场。

一句话概括: 数据库演进的核心不是“跑一段迁移脚本”,而是让状态层在业务不停、版本共存、历史数据仍可信的前提下继续变化。
一、它真正回答什么问题
表面症状
数据层不敢动
中层根因
状态已经被多方依赖
关键识别
哪些变更可逆 / 不可逆
治理方式
分阶段迁移与校验
工程目标
状态可演进
组织结果
更敢改数据库
常见表象更可能的根因为什么它是数据库演进问题
应用回滚了,但数据回不去变更没有区分应用可逆和数据不可逆数据库状态一旦被写入,回滚模型就不同于代码
一个字段想删,查不清谁还在用字段依赖面没有观测,弃用流程缺失清理旧结构前必须知道真实消费面
服务拆出来了,但还共享同一批表数据 ownership 没有随服务边界一起演进共享数据库会把服务边界重新粘回去
回填脚本跑到一半失败,没人敢重跑迁移动作不可幂等、不可恢复、不可观测生产迁移必须像系统一样设计,而不是像一次性脚本
历史报表和新业务口径长期对不上历史数据迁移、口径切换和校验退场没有闭环数据库演进不只改当下结构,也会改变历史解释
二、什么算数据库演进
结构演进
  • 新增字段、改约束、拆表、合表、重命名、索引调整
  • 重点是兼容窗口、锁风险、版本共存和旧结构退场
数据演进
  • 历史数据回填、口径修正、去重、归档、冷热分层
  • 重点是幂等、校验、补偿和可重复执行
边界演进
  • 主数据归属、服务拆分、共享表退场、读写路径重划
  • 重点是 ownership、契约、双写双读和影子校验
判断标准: 如果一次改动会改变持久化状态、历史数据解释、读写路径或数据 owner,它就不只是一次普通发布,而是数据库演进动作。
三、最常见的六类演进动作
动作风险推荐方式不要怎么做
新增字段默认值、旧服务读取、新服务写入顺序先加 nullable 或安全默认值,再让应用逐步写入一次上线同时加字段、强依赖、删旧逻辑
删除字段仍有长尾消费者读取先观测使用面,标记弃用,确认清零后删除只搜代码仓库就认为没人用
重命名字段本质上通常是新增加删除新旧字段并存,双写,迁移读路径,再清理旧字段直接 rename column 期待所有版本同时升级
拆表 / 合表查询路径、事务边界和历史数据都变先建立新模型,回填,双写,影子校验,再切读把 schema 变更和业务切换压成一次大上线
索引调整建索引锁表、写放大、执行计划变化在线 DDL、低峰执行、观测慢查询和写入延迟只看读查询收益,不看写入成本
主数据迁移谁是事实源说不清,双写不一致明确 source of truth,设计双写/校验/切换/退场阶段两个系统长期都自称主数据
四、分阶段迁移的基本路径
1
Expand: 先扩展出新结构
让旧应用和新应用有一段可共存窗口
加新字段 / 新表
保持旧读写可用
补默认值与兼容逻辑
目标: 先制造过渡空间
关键: 不让任一版本应用立刻失效
2
Migrate: 再迁移写入与历史数据
把一次性脚本改成可观察、可重试、可校验的迁移动作
双写 / CDC
批量回填
差异校验
补偿修复
目标: 让新旧状态逐渐对齐
关键: 迁移必须幂等,失败后能继续
3
Switch: 切读路径和事实源
先影子读和比对,再把真实流量切到新结构
影子查询
灰度切读
监控业务指标
明确回退边界
目标: 让新结构真正承接业务读写
关键: 回退不等于简单回滚代码
4
Contract: 最后清理旧结构
确认没有依赖、没有回退需要,再删除旧字段、旧表和旧链路
观测旧依赖
标记退场
归档备份
删除旧结构
目标: 防止迁移长期留尾巴
关键: 不清理旧结构,复杂度会双倍存在
五、回滚边界要提前说清
变更类型回滚特点更稳的设计
只加字段且旧应用忽略通常较容易回滚应用让 schema 先行,应用慢慢使用
写入新字段但旧字段仍保留可以回到旧读路径,但要处理数据差异双写期间持续校验,准备补偿任务
删除字段 / 表通常不可直接回滚先长时间弃用和归档,再删除
全量历史数据重算回滚成本高,且可能影响报表和下游保留旧口径快照,分批切换,按租户或时间段验证
主数据源切换回滚涉及事实源和写入冲突切换前定义冻结窗口、冲突策略和恢复手册
六、常见误读
误读 1: 数据库迁移就是 DBA 跑 SQL。

真正危险的迁移通常跨应用、发布、数据口径、读写路径和业务 owner,不是单个 SQL 能解决的。

误读 2: 应用能回滚,发布就安全。

很多数据库变更一旦写入新状态,应用回滚只解决代码问题,不解决状态问题。

误读 3: 双写就能保证平滑迁移。

双写只是过渡手段,还必须有幂等、顺序、失败补偿、差异校验和退场计划。

误读 4: 迁移完成就是新链路上线。

旧字段、旧表、旧任务、旧报表和旧消费者没有退场,迁移就还在继续消耗组织注意力。

反直觉点:

数据库演进最容易被低估的工作,常常不是“怎么切过去”,而是“怎么确认旧世界真的可以退出”。

七、和仓库现有图谱怎么配合看
如果你正在处理什么问题建议配套页为什么连着看
想先建立数据库分类、存储、事务和高可用底层认知数据库数据库演进建立在基本数据库能力之上,而不是替代数据库基础
想把 schema 演进、回填和重放放进数据生产线数据工程很多数据库演进会继续影响下游数仓、报表、补数和数据质量
想把数据库迁移接回应用发布和灰度回滚发布工程数据库变更必须和应用版本、开关、灰度、回滚模型一起设计
想看后端系统里数据正确性和变更治理后端工程后端工程负责把数据层演进放回接口、事务、缓存、消息和交付链路
想看契约和字段语义怎样保护演进数据契约数据库结构变化最终要通过 API、事件和数据流契约传递给消费者
想看数据系统为什么必须考虑长期演进《DDIA》DDIA 提供编码与演进、日志、回放、重算和衍生数据的底层视角
想把共享数据库从单体迁移到服务边界《从单体到微服务》服务化迁移里最硬的部分,往往就是数据 ownership 和共享库退场
八、适合谁看
后端负责人 / Tech Lead
适合用来规划数据库变更、拆库拆表、字段退场和核心链路迁移。
平台 / 发布工程团队
适合把数据库迁移纳入发布模板、门禁、灰度和回滚体系。
数据工程团队
适合处理上游 schema 演进对下游补数、重放、指标口径和质量校验的影响。
架构师 / 迁移负责人
适合在服务拆分和数据 ownership 重划时,用它检查迁移阶段是否足够完整。