中间表必须建,关键在于科学设计:优先固化高频、高开销、低更新、低延迟敏感的聚合指标;结构上精简字段、显性口径、合理分层时间维度、主键清晰;更新以t+1离线为主,辅以轻量实时;需规范命名、文档沉淀和权限治理。

SQL报表统计中,中间表(也称预计算表、汇总表)不是“要不要建”的问题,而是“怎么建才不踩坑”的问题。它本质是用空间换时间,但若设计不当,反而拖慢开发、增加维护成本、引发数据不一致。
明确预计算的边界:哪些指标值得固化?
不是所有字段、所有聚合都适合进中间表。优先固化:
- 高频访问的聚合结果:如“各门店近7日销售额”“用户月度活跃天数”,被多个报表反复调用;
- 计算开销大的逻辑:含多层JOIN、窗口函数、复杂CASE WHEN、跨月/跨年滚动计算等;
- 基表更新频率低、但查询频率高:比如用户基础属性表每日全量同步一次,但日报表每小时查多次;
- 下游对延迟不敏感:T+1可接受的场景比实时看板更适合预计算。
避免把明细字段(如订单ID、操作时间戳)或低频、易变口径(如临时活动补贴率)硬塞进中间表。
结构设计要点:字段精简 + 口径显性 + 时间粒度合理
一张好用的预计算表,结构比数据还重要:
- 只存聚合值,不存明细路径:例如存“门店A_202405销售额=128000”,不存“这笔销售来自哪个订单”;需溯源时通过关联主键回查原表;
- 口径字段必须显性化:加calc_type(如'pay_amount_excl_refund')、filter_cond(如'is_first_order=1 AND status=2'),避免“这个UV是怎么算出来的?”没人能答;
- 时间维度按需分层:日期(date_key)、周(week_start_date)、月(month_key)分别建字段,支持灵活切片;不要只留一个“stat_date”然后让前端自己推周/月;
- 主键清晰可重跑:推荐组合主键如 (dim_id, date_key, calc_type),确保单次任务失败后可精准覆盖重刷,不依赖delete+insert。
更新策略:T+1离线为主,轻量实时为辅
95%以上的报表中间表走离线调度更稳:
- 用Spark SQL或Hive SQL每日凌晨跑批,基于前一天的全量/增量事实表聚合;
- 关键指标(如GMV、DAU)增加校验逻辑:与上游明细sum做diff告警,误差>0.1%自动钉钉通知;
- 真需要准实时(如小时级经营看板),可用Flink CDC捕获业务库变更,仅更新受影响的聚合行(如更新某订单状态后,只重算该用户当日订单数),而非全量重刷;
- 禁止“定时truncate+全量重算”——数据量大时IO爆炸,且窗口期无数据。
治理与协作:命名规范 + 文档沉淀 + 权限隔离
中间表一旦泛滥,就会变成“幽灵表”:
- 命名带业务域+周期+粒度:如dws_sale_store_day_agg(销售域-门店-日聚合),不用tmp_report_xxx或summary_v2_bak;
- 每张表配轻量README:写清来源表、计算逻辑SQL片段、更新时间、负责人、最后一次校验时间;放在数据平台表详情页或内部Wiki;
- 权限分级:开发组可读写,分析组只读,业务方仅开放BI工具内建模权限,禁止直接select *;
- 定期下线机制:连续90天无人查询、无血缘关系的表,自动邮件提醒负责人,过期未响应则归档。










