知识全景图/ 软件工程与系统/ 数据库生产治理/ 数据库演进

数据库演进全景图

不要把演进写成迁移路线大全;先解释“数据库已经上线以后,为什么不能像改代码一样随便回滚”

这一页只做入口判断: 数据库演进不是新增知识分支,而是回答生产状态怎样继续变化。只要改动会影响表结构、历史数据、读写路径、事实源或旧字段退场,它就不是普通发布,而是数据库演进。
一、事故:代码回滚了,数据回不去

团队把 entries.category 迁移成 category_id。上线后发现报表错了,于是回滚应用镜像。结果旧代码读不到新写入的数据,新旧字段已经分叉。代码回滚成功,数据库状态没有回滚。

误判真实问题演进设计
应用能回滚,所以发布安全数据状态一旦写入,回滚模型不同每阶段写清可逆点和不可逆点
迁移脚本跑完就结束旧字段、旧报表、旧任务还在用退场也是迁移的一部分
新表上线就是新事实源新旧读写可能持续分叉影子校验和切读证据
二、判断一次改动是不是数据库演进,只问 6 个问题
问题如果答案是“是”
会改变持久化结构吗加字段、删字段、拆表、合表、改索引都算演进
会改变历史数据解释吗分类、金额、币种、状态、月报口径变化都要版本和校验
会改变事实源吗两个系统都自称主数据,会长期分叉
会影响下游读模型吗搜索、缓存、月报宽表、数仓都要对账或重建
应用回滚后数据能不能跟着退不能退就要写阶段回滚边界
旧结构什么时候退场没有 Contract,复杂度会永久翻倍
三、最小演进模型
evolution_change - change_id - old_structure - new_structure - phase: expand | migrate | switch | contract - reversible_until - affected_tables - affected_read_models - validation_query - owner
吸收点: 数据库演进要记录阶段,而不是只记录 SQL。因为不同阶段能退的东西不一样。
四、演进只有 4 个动作
阶段做什么事故防线
Expand先加新字段 / 新表,让旧应用仍能跑防止一上线就打断旧版本
Migrate双写、回填、追增量、修差异防止新旧数据长期分叉
Switch影子读通过后灰度切到新读写路径防止没证明就一刀切
Contract旧依赖归零后删除旧字段、旧表、旧任务防止复杂度永久翻倍
关键边界: 最危险的不是切不过去,而是切过去以后旧世界不退场,系统永远背着两套语义。
五、用 6 个样本证明演进可信
样本通过标准
旧应用仍在线新结构上线后旧版本读写不报错
新旧双写失败一次能发现差异并幂等补齐
回填中断能续跑,重复批次不污染数据
影子读对比旧读和新读在关键查询上对得上
应用回滚知道哪些数据可退、哪些只能补偿前进
旧字段删除前真实读取、写入、报表、脚本依赖归零
六、下一步只按演进对象下钻
如果是一场具体 schema 迁移
如果是加字段、加索引、加约束
数据库迁移与在线演进里的 DDL、索引回填与锁风险。
如果演进后读模型分叉
如果演进失败要救数据
总结: 数据库演进不是迁移脚本大全。它只抓一个判断:生产状态怎样在旧版本、新版本、历史数据、下游读模型和旧结构退场之间继续可信变化。