谈谈维度数据建模原理

王建峰·2026年02月13日 20:21
谈谈维度数据建模原理

多数数据团队都面临着同样的难题:维度建模 。这个概念其实并不复杂,但标准的解释通常都使用相同的例子,缺乏更深入的理解。 

下面是 有关 星型模式的 内容 和 常见的例子。 

销售表、订单表、交易表……这些通常都是电商或零售场景,与你的实际业务截然不同。如果你处理的是SaaS指标、物联网传感器数据或医疗记录,你可能会开始怀疑这种方法是否真的适用于你。 

确实如此。但你必须停止思考具体的例子,而开始思考其背后的模式。 

本文将探讨以下内容: 

  • 事实维度 之间的根本区别
  • 如何确定事实表的 粒度
  • 每种表类型 实际包含哪些内容
  • 为什么这种结构在现代数据栈 中仍然有效
  • 从你要测量的内容开始

维度建模 最难的地方在于,大家都用同样的例子来解释它:销售表、订单表、交易表。这些例子反复出现。如果你的业务模式与零售业不同,你可能会觉得这些例子与 你无关。 

但以下方法对我有帮助:停止思考表。 

如果你的公司里发生了什么事的话,想想实际发生了什么。 

一位用户注册了。

一个支持工单已关闭。

传感器读数已收到。

付款已处理。

发生的事情就是 事实 。其他的一切都只是关于事情发生的时间、涉及的人员以及事件的类型等 背景信息。

拉尔夫·金博尔围绕这一区别构建了 一整套方法论。事实 是动词, 维度 是其他一切。 

这一点很重要,因为很多团队都试图将自己的业务生搬硬套到零售业的模式中。但其实,其本质远比这更复杂。 

任何产生事件的 业务流程 都可以用这种方式建模。问题不在于你是否有订单,而在于你是否有想要衡量和理解的事件发生。 

事实即行动

当你查看数据并试图确定哪些内容应该作为 事实表时 ,问问自己: 

  • 这里发生的是什么动作/事件?
  • 交易完成。发票已发送。页面已加载。这些 事件 都带有时间戳,通常还附带 计量数据
  • 这次销售成交价是多少
  • 页面加载花了 多长时间?
  • 测试 通过了 还是 失败了

事实 是可以计数、求和或取平均值的事物。它们是 数字 。它们发生在特定的时间点。你可能拥有数百万个这样的事实。 

这就是为什么 Kimball 坚持认为 事实表 应该主要由键和数字组成。 外键 指向 维度表 ,然后是度 量值 (收入、数量、持续时间等)。这些就是你在回答问题时需要汇总的数据。 

想想当有人索要 报告 时会发生什么。他们需要的是总计、平均值、计数以及随时间变化的趋势。所有这些都始于存储在最细粒度级别的 数值测量数据。事实表 就是这些数据的存储位置。 

测量本身可以是加性的、半加性的或非加性的

  • 像收入或数量这样的加性 指标,可以跨任何维度进行求和。
  • 像账户余额这样的半加性 变量,在某些维度上求和是有意义的,但在其他维度上则不然。
  • 像比率或百分比这样的非加性 量需要根据其他数据计算得出。

但无论类型如何,它们都是与特定业务事件 相关的数值。这就是规律。 

维度即背景

维度 描述 事实。它们回答诸如以下的问题: 

  • 谁参与其中?
  • 什么产品?
  • 哪位顾客?
  • 什么地点?
  • 什么时间段?

客户在销售前后都存在。产品无论今天是否有人购买,都会一直保留在您的产品目录中。这些实体是持久的,可以重复使用。您可能会在不同的 事实中引用 同一个客户数千次。 

这就是为什么维度可以很宽的原因。不仅仅存储客户 ID 和姓名,还存储他们的类型、细分、地区、注册日期、状态等等。 FILTER GROUP BY 所有你以后可能需要的 属性 。 

Kimball 将此称为“为了提高性能和易用性而进行的非规范化” 。 

在规范化的数据库 中,客户信息会被分散在多个表中:一个表存储客户基本信息,一个表存储地址,另一个表存储属性。但在 星型模式 中,所有信息都集中在一个宽维度表中。这样一来, 查询 就更简单、更快捷,因为无需通过 连接 多个表来获取客户基本信息。 

时间也是如此。你可以直接在事实表中存储时间戳,然后就万事大吉了。但如果你构 建一个合适的 时间维度 (这是 Kimball 的核心模式之一),你就能获得星期几、会计期间、是否为节假日、季度和年份等信息。所有这些 时间维度 都能满足你的需求,而无需在每个查询中都编写日期计算。 

时间维度很特殊,因为 每个事实都发生在某个时间点上 ,但企业对时间的看法却各不相同。 

  • 零售商很重视 节假日销售旺季
  • B2B公司关注的是 财政季度
  • 订阅制企业非常重视 计费周期

时间 维度 使得所有这些不同的时间观变得明确和可及。 

维度也包含 层级结构 。产品属于子类别,子类别属于类别,类别属于部门。位置可以是商店,位于区,区,地区,国家。这些层级结构使您能够在不更改底层事实表的情况下,分析 不同详细程度的事实。

粒度问题确实至关重要

这是大多数团队都会遇到的难题: 

事实表中的“一行”具体指的是什么? 

金博尔称之为“ 粒度声明” ,这是尺寸建模中最关键的决策。如果出错,其他一切都将崩溃。 

如果你在对电子商务数据进行建模,一行数据是指购物车结算单吗?还是指购物车中的每个商品?答案会彻底改变一切。 

选择购物车结算后,您将无法询问哪些商品是一起购买的。由于您过早地汇总了数据,因此也无法查看每笔订单的平均商品数量。 

选择商品明细后,即可进行分析。每个商品扫描都对应一行,包含其自身的价格、折扣和数量。您可以根据需要汇总到 订单级别,也可以在商品级别 进行分析。 

粒度通常 与业务流程的自然单位 相匹配。 

我见过很多人在这个选择上纠结不已,试图找到一种能够解答所有问题的完美谷物。 

但还有一种更简单的思考方式:你的 业务流程 中的 最小事件是什么?你最关心衡量的 最小事件是什么? 

  • 对于零售销售点而言,它是对单个商品的扫描。
  • 对于订阅制企业而言,这可能是特定订阅期的计费事件。
  • 对于网站分析而言,它可以是页面浏览量或点击事件。
  • 对于制造业而言,它可能是指装配线上生产的单个零件。

一旦你确定了那个 原子事件 ,那就是你的基石。其他一切都由此展开。 

难点在于抵制 预先汇总 的诱惑。你可能会想:“我们总是看每日总量,为什么不把谷物按天计算呢? ” 

但如果有人问起每小时的交易模式,你就答不上来。或者他们想查看具体的交易记录,但数据却不存在。 

Kimball的建议是,将 事实以最符合业务逻辑的粒度存储,然后在报表层 根据需要进行汇总。存储成本低廉,但灵活性至关重要。 

为什么星型模式在今天仍然适用

星型模式 源于 Kimball 在数据仓库时代的工作,当时连接操作成本高昂,计算速度缓慢。如今这些 限制 已不复存在。但这种模式得以保留,是因为它解决了另一个问题:人类的好奇心。 

当有人提出关于业务的 新问题 时,他们几乎总是以新的方式将相同的 维度 组合起来。 

  • 显示各地区的收入情况。
  • 现在按产品类别划分。
  • 现在按客户群体划分。
  • 现在按月计算。

这些操作实际上只是根据不同的 维度属性 对同一个事实表 进行筛选分组 。星型模式使这种操作自然而然地发生。你无需从头开始重建查询,只需重新排列各个部分即可。 

想想实际情况会如何。 

业务部门有人要求生成一份 报告 。然后他们又要求生成同一份报告的 不同切片版本 。接着他们想添加另一个 筛选条件 。然后他们又想查看不同时间段的数据。如果使用设计良好的星型模式,这些请求都变得非常简单。你只需要修改GROUP BY相应的WHERE条件语句即可。 

这就是星型模式成为 商业智能基础的 原因。从数据库理论的角度来看,它并非最优雅的结构,但它符合人们实际 探索数据的 方式。他们会进行切片、切块、向下钻取、向上汇总等操作。星型模式让所有这些操作都变得简单。 

自 Kimball 在 20 世纪 90 年代首次提出这一概念以来,现代工具和技术已经发生了翻天覆地的变化。我们现在有了列式数据库、分布式系统和语义层。但其核心思想始终未变:将 事件本身 与其发生的上下文分离。这将有助于您构建一个灵活的基础,以便回答 业务问题 。 

每张表里实际放的是什么

1. 事实表

它们包含三种类型的列:外键、度量和退化维度。 

外键连接到您的 维度表 。每个事实表至少需要一个 时间维度键 ,但大多数事实表会有多个维度键,例如 customer_key、product_key、location_key 等,基本上涵盖参与该事件的所有实体。 

这些 测量结果 是需要汇总的数值。正如我之前提到的,金博尔区分了三种类型。 

收入或数量等可累加的事实 可以按任何维度进行求和。

账户余额或库存水平等半加性 事实可以按某些维度求和,但不能按时间求和。

像单价或比率这样的非加性 事实需要在计算中使用,而不是直接汇总。

退化维度 是指那些因为不属于其他任何维度而保留在事实表中的描述性属性。订单号就是一个典型的例子。它们对于每笔交易都是唯一的,基数很高,而且本身没有值得构建维度的属性。这就是为什么它们被保留在事实表中的原因。 

2. 维度表

维度表以 代理键开始。 这是一个在 ETL 过程中生成的顺序整数,并非源系统中的自然键。例如,CRM 系统中的客户 12345 在 维度表 中可能拥有代理键 1。此步骤通常在黄金层完成。这些代理键用于显式地作为与事实表的连接列。 

所以你可能会想,为什么要使用代理键呢? 

答案很简单: 运营 和历史。 

如果源系统 中的客户 ID 发生变更,您可以处理此变更,而无需更改引用该客户的所有事实表行。更重要的是,您还可以跟踪缓慢变化的维度。当客户从 A 细分市场迁移到 B 细分市场时,您可以在维度中保留这两个版本,并使用不同的代理键和有效日期范围。这样,您就可以使用当时的上下文来分析 历史事实。

接下来是 属性 。这些是 描述性的字段 FILTER,例如人员信息GROUP BY。这可能包括姓名、类型、类别、状态、描述等等。 

维度也包含 层次结构 ,并且它们是非 规范化的 。 

产品维度在同一行中包含 SKU、子类别、类别和部门。

位置维度包括商店、地区、区域、国家。

这种冗余是故意的。您可以按任意级别分组,而无需额外的连接。 

一般来说,这两种类型的表都是 宽表非规范化的 。您已将源表连接在一起,以便于使用。客户维度表可能合并来自客户主表、客户细分表和客户地理位置表的数据。 

随着模型的扩展,保持 事实表为数值型维度表为描述型的原则对于保持模型的清晰度至关重要。这种严格的原则也会影响查询性能 。当您明确事实表仅包含数值度量和外键时,就可以采用与维度表不同的优化方法。 

事实表由于外键基数低且度量值均为数值型,因此可以很好地 压缩。它们基于外键建立索引,以实现快速连接。维度表则基于用户筛选的属性建立索引 。这种清晰的分离使您可以根据各自的访问模式进行优化。 

一个实际例子

我们以医院的病人就诊为例。每次就诊都是一个事实。它发生在某个时间,涉及病人与医生,最终可能得出诊断结果。 

但是就诊期间开具的处方药呢?这些是就诊的 组成部分,还是独立的事实 ? 

这取决于你的 数据结构 。如果一行代表一次就诊,那么药物信息就会成为问题。一次就诊可能开三张处方,也可能一张也没有。你无法干净利落地存储长度可变的列表。 

但如果你的每一份处方都对应一排谷物,那么现在你可以问:哪些药物是同时开的?续药率是多少?平均每次就诊开多少张处方? 

你通过改变衡量标准,改变了人们自然而然会提出的 问题。

这个例子说明了一点:同一个业务流程 通常可以有多种有效的建模方式。例如,你可以创建一个就诊 事实表, 其中每一行代表一次就诊;然后再创建一个单独的处方事实表,其中每一行代表一张处方。这两个事实表可能共享一些维度(例如患者、医生、时间),但它们衡量的是不同的内容。 

这就是 Kimball 所说的星座模式或事实星座。它指的是多个事实表共享 一致的维度 。这种模式在实际应用中很常见,因为大多数企业都有 多个 需要衡量的流程。 

医院可能还会有实验室检查数据表、手术数据表和计费数据表。这些都是独立的 数据 声明,分别 衡量 患者护理的不同方面。但它们都通过患者、医生、医疗机构和时间等 共同维度相互关联。

关键在于明确定义每个 事实表 衡量的内容,并确保粒度定义清晰。如果粒度模糊,查询就会变得混乱,结果也会变得不可靠。 

为什么你应该创建星型模式

此时,你可能会想: 

为什么不直接编写自定义查询?为什么不使用一个大表? 

原因有三。 

1. 组织

随着团队的壮大,清晰的组织架构意味着每个人都知道在哪里查找信息以及各项工作之间的联系。这样就无需每次都重复造轮子。 

当一位新分析师加入团队时,他们可以通过了解业务流程 来理解模型。 

事实 是已经发生的事情,而 背景 则是事件发生的语境。 

这些 关系 很明确。他们不需要逆向工程别人的自定义查询来弄清楚收入是如何计算的。 

2.决策

你在定义 关系 ,你在决定 逻辑 ,你不是简单地把源系统提供的数据传递给你。 

源系统是为 运营而 构建的,而非为分析而构建的。它们针对快速记录交易进行了优化,但并不擅长回答业务问题。它们存储数据的方式可能对应用程序来说很合理,但却不适合 生成报表 。 

构建 维度模型 时,你是在将运营数据转化为 分析数据。你要根据企业对这些概念的理解 ,定义什么是客户、什么是产品、什么是销售。你要解决不一致之处,规范定义,并选择如何处理特殊情况。 

这正是价值所在。不仅是整理数据,更重要的是阐明数据 含义。 

3. 可扩展性

你在 建立一套规范 。当有新人加入或需要添加新的数据源时,都有一套固定的模式可以遵循。你是在有计划地构建,而不是随意发挥。 

随着 数据仓库的 增长,你会添加更多的事实表、维度表和数据源。如果每个表、维度表和数据源的构建方式各不相同,缺乏 统一的 方法,那么复杂性就会变得难以承受。但如果你始终遵循 维度建模原则 ,那么每个新增的表都能完美地融入现有的数据结构中。 

新的事实表可以 重用现有维度 。新维度遵循与旧维度 相同的模式 。由于所有内容都以相同的方式组织,分析师可以轻松地找到所需信息。 

金博尔明白,这个模型是将你的商业理论具体化。这个模型应该能简化简单的问题,也能让复杂的问题变得可行。 

当有人问“上个季度的销售额是多少”时,这个 问题 应该很简单明了。 

当他们问“上个季度东北地区首次购买我们高端产品线的客户销售额是多少”时,这个问题应该 很复杂,但并非不可能 。 

这就是一个好的维度模型 的检验标准。它不会强迫你费尽周折才能回答合理的业务问题。 

本文来自微信公众号 “数据驱动智能”(ID:Data_0101),作者:晓晓,36氪经授权发布。

+1
31

好文章,需要你的鼓励

参与评论
评论千万条,友善第一条
后参与讨论
提交评论0/1000
特邀作者

TA没有写简介,但内敛也是一种表达

下一篇

当AI搜索变成“聊家常”,你的关键词策略该升级了。

2026-02-13

36氪APP让一部分人先看到未来
36氪
鲸准
氪空间

推送和解读前沿、有料的科技创投资讯

一级市场金融信息和系统服务提供商

聚焦全球优秀创业者,项目融资率接近97%,领跑行业