1. 粒度概念与重要性

聊事实表设计,第一个绕不开的概念就是粒度。我见过太多项目,表结构画得漂漂亮亮,一跑查询就崩,或者业务方说“我要看每日数据,你这怎么只有月汇总?”——十有八九,是粒度没想清楚。

什么是事实表粒度

粒度,说白了就是一行事实记录代表什么。

举个例子。你有一张销售表,如果每行记录的是“某用户在某天买了一支笔”,那粒度就是交易明细。如果每行记录的是“某门店某天的总销售额”,那粒度就是日汇总。同一个业务,粒度不同,表里的行数、可分析的维度、能回答的问题,完全不一样。

粒度定义三要素:

  • 业务事件:一行对应一次什么事件?(下单、支付、退款…)
  • 维度组合:由哪些维度唯一确定一行?(日期+门店+商品+用户?)
  • 度量范围:这一行里的数值是单笔值还是聚合值?

我个人习惯,在设计任何事实表之前,先拿笔在纸上写一句话:“这张表的每一行,代表________。” 填不出来,就别急着建表。

粒度对数据分析的影响

粒度选得对不对,直接决定了你的数据仓库能不能用、好不好用。我总结了几点核心影响:

影响维度 细粒度(交易级) 粗粒度(汇总级)
查询灵活性 高,可以任意下钻、切片 低,只能按预聚合维度查询
存储成本 高,行数多 低,行数少
查询性能 慢(需扫描大量行) 快(数据量小)
ETL复杂度 低,直接加载源数据 高,需要做聚合逻辑
数据可回溯性 强,可还原任意中间状态 弱,丢失细节

你想想看,如果业务方突然说“我想看昨天上午10点到11点,华东区哪些商品卖得最好”,你的表粒度是“日+门店”,那就只能摊手了。反过来,如果粒度是“秒级交易”,但你的集群只有4台机器,跑一次全表扫描要半小时,业务方一样骂娘。

所以粒度选择,本质上是在灵活性和性能之间找平衡。没有的好坏,只有合不合适。

粒度选择错误案例

讲两个我亲身踩过的坑吧。

案例一:粒度太粗,业务方不认账

我曾经给一家零售企业做数仓。当时为了省存储,把销售事实表设计成“门店+日期+商品品类”的粒度,每天每个品类一条记录。结果上线第一天,运营总监就拍桌子:“我要看每个SKU的销量,你给我品类汇总有什么用?”

没办法,只能重做。那一次重构,光数据回溯就跑了三天三夜。嗯,从那以后,我再也不敢在没确认业务需求之前就拍粒度了。

案例二:粒度太细,查询跑不动

另一个项目是做用户行为分析。我把每次页面点击都记成一行,粒度细到“用户+时间戳+页面元素”。表倒是建得挺全,但业务方查“昨天首页UV”这种简单指标,一个SQL跑20分钟。为什么?因为表里有几十亿行,而且没有合适的索引和分区策略。

后来我加了分层聚合:保留一份细粒度原始表做归档,再建一张“小时+页面”的轻度汇总表给日常查询。这才把查询时间压到秒级。

这两个案例说明什么?粒度选错,要么数据不能用,要么系统扛不住。而且一旦上线再改,成本极高。

粒度选择的核心原则

结合这些教训,我总结了几条原则,供你参考:

  1. 先问业务问题:业务方最常查什么维度?最细要看到什么级别?
  2. 保留最细粒度:只要存储和性能扛得住,尽量保留源数据粒度。细节丢了就再也回不来了。
  3. 分层设计:细粒度表做底层,汇总表做上层。各取所需。
  4. 考虑增量:粒度越细,数据量增长越快。提前规划分区、归档策略。

一个小技巧:设计阶段,拿一张纸列出所有可能的业务查询场景,然后问自己:“这张表的粒度,能回答这些问题吗?” 如果有一半答不上来,说明粒度需要调整。

本章知识体系

下面这张图,帮你把本章的核心逻辑串起来:

事实表粒度选择知识体系 事实表粒度选择知识体系 粒度定义 业务事件 维度组合 度量范围 对数据分析的影响 粒度选择错误案例 查询灵活性 存储成本 查询性能 ETL复杂度 粒度太粗 粒度太细 核心原则:先问业务 → 保留最细 → 分层设计 → 考虑增量 粒度选择没有银弹,核心是理解业务需求,在灵活性和性能之间找到平衡点