星型模型、雪花模型、星座模型的区别

模型与算力

讲清星型、雪花与星座三种数仓建模方式的区别,给出按查询模式、维表变化和团队规模选型的判断清单。

做数仓建模时,建到一半常卡在一个问题上:事实表和维表到底要不要继续拆下去?拆了查询变复杂,不拆维表又到处重复。这篇把星型、雪花、星座三种结构的差别拆开讲,并给出一个可以照着走的选型顺序,帮你在动手前先把结构定下来。

做数仓建模时,建到一半常卡在一个问题上:事实表和维表到底要不要继续拆下去?拆了查询变复杂,不拆维表又到处重复。这篇把星型、雪花、星座三种结构的差别拆开讲,并给出一个可以照着走的选型顺序,帮你在动手前先把结构定下来。先说明一点:这三种不是「谁更高级」的排名关系,而是三套适配不同查询模式和团队分工的摆法。

判断自己该用哪种,通常不用看太多理论。你只需要回答三个问题:事实表的行代表什么粒度、高频查询会跨几层取维属性、维表属性会不会被上游反复覆盖。这三个答案基本就决定了结构走向。下面按「差在哪 → 怎么比 → 怎么选 → 别踩什么坑」的顺序来。

三种结构到底差在哪

星型是最直白的一种:一张事实表直接连一圈维表,维表不再往下拆。查询时 join 的层数最少,写 SQL 的人看一眼就明白。代价是维表里会有重复值,比如同一城市名在订单维、客户维里各存一份,改一次得批量刷。

雪花是把维表继续做规范化:把城市、品类这类属性从主维表里剥出来,单独建子维表,再挂回去。好处是重复属性收拢到一处,改一处全生效;坏处是每次取那个属性都要多跳一层 join,链路长了,排查问题也要顺着往上找。

星座不是「更复杂的雪花」,它是另一种组织方式:多个事实表共用同一批维表,适合一个主题域里有多个业务过程的情况。比如订单和退款两条流程共用客户、商品、日期这几张维表。它的复杂度不取决于单个维表拆多深,而取决于共用维表的口径是否统一。

事实表
存业务过程发生的事,行代表某个粒度的一次记录
维表
存描述性属性,用来给事实表切分和筛选
规范化
把重复属性抽到单独表里,减少冗余但增加 join
共用维表
多张事实表指向同一张维表,接口一致才好共用

一张对照表:按维度比,不按好坏比

很多人问「哪种更好」,其实没有统一答案。下面按查询复杂度、存储与一致性、加载维护、适用边界四个维度对照着看。注意这里比的是取舍方向,具体到你的项目还要结合数据量和查询频次去站内资料区核对当时的参考数据。

对比维度星型雪花星座
查询 join 层数最少,一圈维表每取属性多跳一层取决于共用维表深度
存储与一致性维表有冗余,改要批量刷重复属性收拢一处,改一次生效多事实表共用,口径须先统一
ETL 与维护链路短,排查快链路长,上游变动影响下游接口多,需约定维表契约
适用边界口径稳定、查询频次高属性多且变动频繁多条业务线共用同一批维表

看这张表时有个容易忽略的点:星座模型的复杂度是「横向」的,多张事实表之间的维表口径要一致;雪花模型的复杂度是「纵向」的,同一条查询链上的层级要理清。两者出问题的表现不一样,排查顺序也不一样。

  • 查询复杂度:星型最少 join,雪花每次取属性都要多跳一层,星座看共用维表深度
  • 存储与一致性:雪花把重复属性收拢一处,改一次全生效;星型要改就得批量刷维表
  • 加载与维护:星型 ETL 链路短、排查快;雪花链路长,一处上游变动会顺带影响下游
  • 适用边界:星型适合报表口径稳定、查询频次高的场景;雪花适合维表属性多且变动频繁;星座适合同一批维表服务多条业务线

动手前的选型顺序

选型不是从「我要建哪种模型」开始,而是从业务过程开始。下面五步可以照着走,每步都有可验证的产出物,不是纯思考。走完还定不下来,说明口径本身没收敛,先把口径对齐再回来。

  1. 定业务过程和粒度写下事实表的每一行代表什么,比如「一次下单」还是「一个订单里的一件商品」。粒度定不下来,后面维表怎么摆都是错的。
  2. 数高频查询用到的维属性把报表里出现频率最高的几列列出来,看它们分别挂在哪张维表上。如果每次取属性都要跨三四层,说明维表拆过头了。
  3. 问维表的变更频率属性只增不改,星型就够;属性会被上游系统反复覆盖,考虑雪花,把易变属性收敛到一处,改一次全生效。
  4. 看团队分工与业务线数量多条业务线共用同一批维表时再考虑星座;只有一条主线时,先从一个星型主题域做起,跑顺了再扩。
  5. 落一份字段级对照记录把每张事实表、维表的字段来源、更新方式记下来。后面加维或合并维表时,靠这份记录判断影响面。

常见踩坑与不适用的情况

最常见的坑是把雪花当成「更规范」的默认选择,结果每个报表都要写一长串 join,维护成本反而超过省下的那点存储。还有一类是把事实性质的度量字段塞进维表,导致同一指标被重复计算,口径打架时很难定位。

星座模型另有一个专属问题:共用的维表口径没对齐,同一个人在订单事实和退款事实里对不上号。这类问题往往在建完跑了一段时间才暴露,回头改代价不小,所以共用维表之前先把接口约定写清楚。

也要说清楚什么情况下这套选型思路不适用。临时探索性分析、业务口径还没定的早期阶段,先按宽表把需求跑通,比纠结模型形状重要得多。另外,数据量很小的场景,join 带来的性能差异感知不明显,这时候优先选团队写起来最顺手的那种结构。

  • 把雪花当默认选择,结果每个报表都要写一长串 join
  • 维表里混进事实性质的度量字段,导致重复计算和口径打架
  • 星座模型共用的维表口径没统一,同一个人在不同事实表里对不上
  • 口径未定的早期阶段,先按宽表跑通,过早建模会把方向锁死
  • 数据量小的时候,优先选团队写起来最顺手的结构,不必硬套规范
下一步想对照官方接口和模型资料库把维表口径核清楚,可以到模型与接口资料区翻当时的参考数据,再决定结构。

常见问题

星型模型和雪花模型,我该直接用哪个?

先看查询模式。报表口径稳定、查询频次高,优先星型,join 少、排查快;维表属性多又会被上游反复覆盖,用雪花把属性收敛到一处,减少批量刷维。两者不是先后关系,同一个仓库里不同主题域可以各用各的,别为了统一牺牲效率。

星座模型是不是必须多个事实表?

核心是多个事实表共用同一批维表,如果只有一条业务过程,那就是普通星型,不用硬套星座。判断标准是:两个以上业务过程需要按同一套维度(比如同一批客户、同一批商品)对齐分析时,才值得把维表抽出来共用。

维表要不要拆得越细越好?

不是。拆分的代价是每次取属性多一跳,收益是存储省一点、变更只改一处。折中做法是只把变更频繁或层级深的属性拆出去(比如组织架构、品类树),城市、渠道这类低基数且稳定的属性留在主维表里,避免为了规范把查询写复杂。

本文依据各平台公开文档与官方公告整理,只做中文归纳;具体做法、参数与限制以官方文档为准。