sql冷热数据分离核心是按访问频次分层存储:热层(主库)存高频数据,温层(归档库)存中频历史数据,冷层(对象 存储 / 列存)存低频长期数据,并通过 自动化 归档与统一 路由 实现性能、成本与可用性平衡。

SQL 历史数据归档与冷热数据分离,核心是把“常查常用”的热数据留在主库保障性能,把“极少访问但需保留”的冷数据迁出或降级存储,降低主库压力、提升查询效率、控制存储成本。
明确冷热数据边界
不能只按时间一刀切(比如“一年前都是冷数据”),要结合业务访问特征判断:
- 订单表中,近 90 天的订单状态变更频繁、客服常查,属热数据;超 180 天且已完成 / 关闭的订单,基本只用于审计或对账,属冷数据
- 日志类表(如操作日志、登录日志)通常写多读少,30 天内可能用于问题排查(热),超过 90 天基本无人访问(冷)
- 用户行为埋点数据,实时分析用最近 7 天,T+ 1 报表用近 30 天,其余可归档为冷数据
建议用实际慢查询日志 + 应用层访问埋点统计,识别真实访问频次,再定义冷热阈值。
设计分层存储结构
主库不承担所有数据存储责任,应构建三级结构:
- 热层(OLTP 主库):仅存当前业务强依赖的数据,保留索引、约束、事务一致性。表结构保持原样,但数据量可控(例如≤500 万行 / 表)
- 温层(归档库 / 历史库):同构 数据库 (如mysql 从库、postgresql只读实例),存放近 1–3 年仍需 SQL 即席查询的历史数据。可去冗余字段、删非必要索引、启用压缩行格式
- 冷层(对象存储 / 列存引擎):用 Parquet+MinIO/S3 或clickhouse/Doris 存 5 年以上数据。按时间分区(如dt=20230101),支持低成本批量读取和简单聚合,不支持高频点查或事务
实现自动化归档流程
避免手工导出导入,用可监控、可回滚的脚本或 工具 链完成迁移:
- 在业务低峰期(如凌晨 2–4 点)执行归档任务,每次处理固定批次(如 10 万行),防止长事务锁表
- 归档前先逻辑标记(如加 archived_at 字段并置值),再 异步 物理迁移;迁移成功后才 delete 源数据,保留回滚窗口
- 使用pt-archiver(MySQL)、pg_cron + copy(PostgreSQL)或自研归档服务,记录每批次的起止 ID、耗时、行数、错误日志
- 归档后自动校验:对比源表与目标表的count、SUM(金额)、MIN/MAX 时间戳等关键指标,失败则告警并暂停后续批次
统一访问入口与 路由 策略
应用无需感知数据在哪一层,由中间层或 DAO封装 透明路由:
- 简单场景:在 DAO 方法中根据查询条件中的时间范围自动选择数据源(如 create_time > ‘2024-01-01’ 走主库,否则走归档库)
- 复杂场景:引入轻量查询网关(如 ShardingSphere-proxy),配置规则将带 WHERE dt BETWEEN ‘20220101’ AND ‘20231231’ 的 SQL 自动路由至历史库
- 冷数据查询走 API 化封装(如提供 /api/archive/order/detail), 后端 对接对象存储 +spark/flink查询引擎,返回jsON 结果
不复杂但容易忽略。