结论先行:数据迁移(Data Migration)的验收标准不是「导进去多少行」,而是总量对得上、金额对得上、业务能接着跑。顺序上只有一条稳妥路径:先在影子库(Shadow Database)试迁并做三方校验,再停机切换。跳过试迁直接切,等于把风险留到上线当天。
一、五步法:每一步都要有产出物
五步的产出物依次是:一份分级清单、一张字段映射表、一份试迁差异报告、一份校验结论、一份切换与回滚方案。缺任何一份,都不算准备完成。
顺序不能颠倒。没有映射表就试迁,跑出来的差异无法归因;没有试迁就定停机窗口,窗口长度全靠拍脑袋。
二、第一步:盘点与分级
先把数据分成四类,不同类走不同策略,这是控制工期的唯一办法。
- 主数据(Master Data):客户、供应商、物料、组织与人员。必须全量迁移,逐条校验,标识(ID)保持稳定。
- 业务数据:订单、合同、工单。按时间窗迁移,例如近三年在线、更早归档。
- 附件:图片、PDF、扫描件。迁的是路径与元数据,文件本体进对象存储(Object Storage)。
- 历史流程:已办结的审批轨迹。迁成只读快照,不进新引擎。
分级的意义在于定「迁多少、怎么迁、谁来认」。全部按最高标准迁,工期失控;全部按最低标准迁,业务断档。
这一步的产出是一张清单:表名、行数、字节数、归属系统、是否在线、责任人。旧系统迁移的顺序回答的是数据、表单、流程谁先谁后,本篇回答的是数据这一段的执行步骤与校验方法,两者对照着排期即可。
三、第二步:字段映射与清洗
映射表至少四列:旧表.旧字段、新表.新字段、转换规则、异常处理。四类问题会在这步集中暴露。
枚举对不上
旧系统 12 种单据状态,新系统 6 种。必须先做状态映射表,再明确「旧状态没有对应项」的数据去哪,是归入兜底状态还是留在归档表。
编码不统一
组织机构编码、物料编码、客户编码在旧系统里可能一物多码。迁移前要定主编码,其余存为别名,否则新系统里一个客户会变成三个。
空值与默认值
旧库用空串表示「无」,新库用 NULL 表示「无」,两者在唯一索引与统计口径里行为不同。要统一成一种,并把规则写进映射表。
重复数据
手机号、统一社会信用代码是天然的查重键。重复不一定要合并,但必须有判定规则和人工复核入口,不能靠脚本静默去重。
四、第三步:影子库试迁
影子库是与生产同构的一套环境,用来跑完整迁移而不影响业务。至少跑两轮,第二轮必须从零开始,不能修补第一轮的结果。
每轮记录三样:总耗时、各表耗时、差异条数。第二轮耗时才是可以承诺停机窗口的依据,第一轮通常受缓存和冷启动干扰。
试迁还要覆盖增量:全量跑完后,把旧系统在试迁期间新增的数据再补一次。增量脚本写不对,切换当天一定漏数。
五、最后两步:校验、切换与回滚
三方校验的四个口径
三方指旧系统、迁移脚本、新系统。校验分四个口径,缺一不可。
- 总量:逐表比对行数,允许有差异,但必须有清单和原因。
- 金额汇总:按客户、月份、单据类型三个维度求和,精度到分。
- 抽样:按业务类型分层抽样,逐字段比对,重点看日期、枚举、关联标识。
- 业务口径:让业务方自己查三个常用报表,与旧系统的数字对齐。
前三项是技术校验,第四项才是验收。技术全对而业务报表对不上,通常说明统计口径或软删除规则变了,这类问题不会报错,只会让数字慢慢偏。
三种切换方式的取舍
切换方式有三种,取舍看停机容忍度。
- 停机切换:冻结旧系统写入,跑全量加增量,校验通过后开放新系统。简单直接,要求业务能接受数小时不可用。
- 双写(Dual Write):新旧系统同时写,靠对账修差异。适合不能停机,但事务边界、失败补偿、幂等(Idempotent)都要自己处理,复杂度高一个量级。
- 按模块灰度:先切低风险模块,跑稳再切核心。折中方案,代价是两套系统并存一段时间。
回滚必须满足的三个条件
回滚不是点一下退回去。必须同时满足三个条件,缺一个就不要启动切换。
- 旧系统在回滚窗口内没有被降级或下线,随时可写回。
- 新系统产生的增量数据能回灌,或已明确哪些数据接受丢弃并经业务书面确认。
- 回滚演练至少做过一次,有明确的决策人、决策时点与最长时限。
双写与停机的取舍
判断标准只有一条:业务能接受多长不可用。能接受一个夜间窗口,就选停机切换,成本最低、可控性最高。
不能停机,再考虑双写。双写的前提是三件事做到位:写入幂等、失败可补偿、对账可自动跑。三件里缺一件,双写就会变成「两套系统都不准」。
灰度介于两者之间,适合模块边界清晰的老系统。它的隐性成本是并存期的权限、数据和运维要同时维护两套。数据主权怎么验证里提到的导出能力,正好用来证明并存期数据没有被单边锁死。
如果旧系统本身是 Excel 表格而不是数据库,迁移逻辑更轻:先定字段,再批量导入,流程最后补。这类场景可以参考Excel 表格升级成在线系统的实战路径。
猫拽低代码(CatPull)的表单字段以 DSL Schema 描述,旧字段到新字段的映射可脚本化生成,自托管部署时数据留在自己库里;但迁移脚本仍要自己写、自己验。
六、核对表与八个坑
迁移核对表
| 核对项 | 口径 | 通过标准 |
|---|---|---|
| 记录总数 | 逐表 count,含软删除数据 | 差异为 0,或有签字确认的差异清单 |
| 金额汇总 | 按客户、月份、单据类型三组维度求和 | 分位一致,误差为 0 |
| 关联完整性 | 抽查子表外键能否在主表命中 | 断链率 0,孤儿数据有登记 |
| 附件可达 | 随机抽 100 条附件链接实际下载 | 可下载率 100%,缺失项有台账 |
| 状态分布 | 状态映射后按状态计数比对 | 映射后分布一致 |
| 抽样一致 | 分类型抽 30 至 50 条逐字段比对 | 关键字段 100% 一致 |
| 时序一致 | 创建、更新、审批三个时间戳 | 时区与精度一致,无跨零点错位 |
| 并发影响 | 切换窗口内旧系统写入是否已冻结 | 冻结时点有记录,增量补偿有日志 |
最容易踩的八个坑
- 自增主键冲突:保留原标识到 legacy_id,新主键重新生成;关联表存映射关系,不要假设 ID 不变。
- 多表关联断链:父子单据、明细行、附件归属都要有映射表,迁完跑一次断链检查。
- 附件路径失效:旧系统存本地路径或带签名的链接,换域名后全部 404。要重写路径并去掉过期签名。
- 状态机枚举对不上:映射表写死没问题,但要给「无对应」的数据准备兜底状态,否则流程提交会卡住。
- 历史审批流无法回放:引擎版本不同,历史轨迹只能做只读快照,不能指望新引擎重跑一遍。
- 时区与金额精度:金额用定点数存分,别用浮点;时间统一存 UTC 或统一存本地,二选一,不能混。
- 软删除数据:迁了会撞唯一索引,不迁会让统计变少。先定规则,再定索引。
- 并发写入漏数:切换前必须冻结写入并记录冻结时点,增量从该时点开始补,不能凭日志时间猜。
FAQs
Q1:旧系统还能用,需要一次性全迁吗?
A:不必。主数据与在办业务先迁,历史数据做只读归档,是成本最低的组合。只有在合规要求「历史随时可查」时,才需要把历史全部在线迁入。
Q2:迁移脚本用厂商工具还是自己写?
A:看数据复杂度。字段一一对应用工具够用;存在枚举映射、编码合并、附件路径重写时,自己写脚本更可控。工具跑完同样要做本文这套校验,不能省。
Q3:停机窗口一般留多长?
A:以试迁第二轮的耗时为基准,再留一半缓冲。经验区间是万级到十万级数据安排在夜间数小时;超过这个量级,优先考虑分区迁移或灰度,而不是硬压窗口。
猫拽智库