归档表应该如何设计?历史数据迁移后如何保证可查可追溯?
简化版
归档表用于把低频历史数据从在线主表迁走,降低主表体积和查询成本。设计时要保证归档条件明确、字段结构兼容、迁移幂等、查询入口可追溯,并保留审计和回滚方案。
详细版
订单、日志、流水等表持续增长后,在线表会变大,索引维护和备份成本上升。归档可以按时间、状态或业务闭环条件迁移历史数据。
常见方案是建同结构归档表,例如 order 和 order_archive,定期把已完成超过 1 年的订单迁走。迁移过程通常分批复制、校验、删除,避免一次性大事务。
归档不是把数据扔掉。用户查询历史订单、客服审计、财务追溯仍可能需要访问归档数据,因此要设计统一查询入口、权限和保留周期。
完整版教学
一、为什么要做归档
在线主表承担高频交易和查询,历史冷数据留得太多会拖累它。即使查询都走索引,索引体积、缓存命中率、备份恢复时间都会受影响。
假设订单表每月新增 3000 万行,一年就是 3.6 亿行。近 3 个月订单占 95% 查询,剩下 9 个月大多只是客服偶尔查。如果全放主表,成本不划算。
归档的目标是让热数据表保持轻,冷数据仍可查。
二、归档条件要业务闭环
不能只按创建时间粗暴归档。订单可能创建很久但仍在售后,合同可能过期但仍有争议,流水可能还在对账。
归档条件应该包含时间和状态。例如“已完成或已关闭,且最后更新时间超过 365 天,且无未完结售后”。
WHERE status IN ('FINISHED', 'CLOSED')
AND updated_at < NOW() - INTERVAL 365 DAY
AND after_sale_status = 'NONE'
这个条件体现的是业务生命周期,而不是单纯数据年龄。
三、归档表结构怎么设计
最简单是归档表和主表保持同结构,方便复制和查询。也可以在归档表额外增加 archived_at、archive_batch_no 字段用于追溯。
| 方案 | 优点 | 缺点 |
|---|---|---|
| 同结构归档表 | 迁移简单、兼容查询 | 字段演进要同步 |
| 压缩归档表 | 节省空间 | 查询复杂 |
| 冷存储/数仓 | 成本低 | 实时查询弱 |
在线业务还需要查历史时,同结构归档表更友好;纯审计分析可以进入数仓或对象存储。
四、迁移过程必须分批和可校验
归档不能一个大事务搬 1 亿行。应按主键或时间窗口分批,例如每批 1000 或 5000 行,复制成功后校验数量和关键金额,再删除主表数据。
选取一批 -> 插入归档表 -> 校验 -> 删除主表 -> 记录批次
迁移任务要幂等。重复执行同一批时,归档表唯一键能防止重复插入,批次表能记录进度。
五、查询入口和权限要提前设计
归档后,原来的订单详情页可能查不到历史订单。如果用户和客服仍需要查询,就要有统一查询入口:先查主表,查不到再查归档表,或按时间路由。
但归档数据往往更敏感,涉及长期历史和审计。权限、脱敏、导出限制要和在线表一致甚至更严格。
不能让归档变成“没人管的影子数据库”。
六、常见误区与追问
- 误区:归档就是删除旧数据。 归档是迁移到低频存储,仍要可查、可追溯。
- 误区:只按 created_at 归档就行。 要结合业务状态,避免迁走未完结数据。
- 误区:归档表不用索引。 归档查询低频但仍要按典型入口建必要索引。
- 追问:如何保证迁移不丢数据? 分批复制、唯一约束、数量校验、金额校验、批次记录和可回滚方案。
- 追问:字段变更时归档表怎么办? 主表和归档表 schema 要同步管理,或设计兼容层。
七、加强记忆
记忆钩子:归档不是把旧资料扔进地下室,而是贴好标签、登记批次、留好钥匙;平时不占客厅,但要找时能找回来。
回答这题时按“为什么归档、归档条件、表结构、迁移流程、查询追溯”讲。这样既覆盖性能,也覆盖数据治理和审计。