1. 粒度概念与重要性
聊事实表设计,第一个绕不开的概念就是粒度。我见过太多项目,表结构画得漂漂亮亮,一跑查询就崩,或者业务方说“我要看每日数据,你这怎么只有月汇总?”——十有八九,是粒度没想清楚。
什么是事实表粒度
粒度,说白了就是一行事实记录代表什么。
举个例子。你有一张销售表,如果每行记录的是“某用户在某天买了一支笔”,那粒度就是交易明细。如果每行记录的是“某门店某天的总销售额”,那粒度就是日汇总。同一个业务,粒度不同,表里的行数、可分析的维度、能回答的问题,完全不一样。
粒度定义三要素:
- 业务事件:一行对应一次什么事件?(下单、支付、退款…)
- 维度组合:由哪些维度唯一确定一行?(日期+门店+商品+用户?)
- 度量范围:这一行里的数值是单笔值还是聚合值?
我个人习惯,在设计任何事实表之前,先拿笔在纸上写一句话:“这张表的每一行,代表________。” 填不出来,就别急着建表。
粒度对数据分析的影响
粒度选得对不对,直接决定了你的数据仓库能不能用、好不好用。我总结了几点核心影响:
| 影响维度 | 细粒度(交易级) | 粗粒度(汇总级) |
|---|---|---|
| 查询灵活性 | 高,可以任意下钻、切片 | 低,只能按预聚合维度查询 |
| 存储成本 | 高,行数多 | 低,行数少 |
| 查询性能 | 慢(需扫描大量行) | 快(数据量小) |
| ETL复杂度 | 低,直接加载源数据 | 高,需要做聚合逻辑 |
| 数据可回溯性 | 强,可还原任意中间状态 | 弱,丢失细节 |
你想想看,如果业务方突然说“我想看昨天上午10点到11点,华东区哪些商品卖得最好”,你的表粒度是“日+门店”,那就只能摊手了。反过来,如果粒度是“秒级交易”,但你的集群只有4台机器,跑一次全表扫描要半小时,业务方一样骂娘。
所以粒度选择,本质上是在灵活性和性能之间找平衡。没有的好坏,只有合不合适。
粒度选择错误案例
讲两个我亲身踩过的坑吧。
案例一:粒度太粗,业务方不认账
我曾经给一家零售企业做数仓。当时为了省存储,把销售事实表设计成“门店+日期+商品品类”的粒度,每天每个品类一条记录。结果上线第一天,运营总监就拍桌子:“我要看每个SKU的销量,你给我品类汇总有什么用?”
没办法,只能重做。那一次重构,光数据回溯就跑了三天三夜。嗯,从那以后,我再也不敢在没确认业务需求之前就拍粒度了。
案例二:粒度太细,查询跑不动
另一个项目是做用户行为分析。我把每次页面点击都记成一行,粒度细到“用户+时间戳+页面元素”。表倒是建得挺全,但业务方查“昨天首页UV”这种简单指标,一个SQL跑20分钟。为什么?因为表里有几十亿行,而且没有合适的索引和分区策略。
后来我加了分层聚合:保留一份细粒度原始表做归档,再建一张“小时+页面”的轻度汇总表给日常查询。这才把查询时间压到秒级。
这两个案例说明什么?粒度选错,要么数据不能用,要么系统扛不住。而且一旦上线再改,成本极高。
粒度选择的核心原则
结合这些教训,我总结了几条原则,供你参考:
- 先问业务问题:业务方最常查什么维度?最细要看到什么级别?
- 保留最细粒度:只要存储和性能扛得住,尽量保留源数据粒度。细节丢了就再也回不来了。
- 分层设计:细粒度表做底层,汇总表做上层。各取所需。
- 考虑增量:粒度越细,数据量增长越快。提前规划分区、归档策略。
一个小技巧:设计阶段,拿一张纸列出所有可能的业务查询场景,然后问自己:“这张表的粒度,能回答这些问题吗?” 如果有一半答不上来,说明粒度需要调整。
本章知识体系
下面这张图,帮你把本章的核心逻辑串起来: