一、简介
维度建模是数据仓库大师Ralph Kimball提出的,是数据仓库工程领域最流行的数仓建模方法。它以需求为出发点构建模型,其核心目标是构建易理解、高性能、可扩展的模型,支撑业务分析需求
。
维度建模常用于数仓中DWD、DWS层的建设。下面是维度建模的一个案例,用于描述订单销售业务过程
二、事实表
维度建模,将数据仓库中的表主要划分为事实表、维度表两种类型。
在现实世界中,每一个操作型事件,基本都是发生在实体之间的,伴随着这种操作事件的发生,会产生可度量的值,而这个过程就产生了一个事实表,存储了每一个可度量的事件。
以订单销售业务为例:一次订单购买事件,涉及主体包括客户、商品,产生的可度量值 包括商品购买数量、金额
等
事实表有三种类型,可分为事务事实表、周期快照事实表、累积快照事实表
。注意:这里需要值得注意的是,在事实表的设计中,注意一个事实表只能有一个粒度,不能将不同粒度的事实建立在同一张事实表中。
- 事务事实表,它是
面向事务的,用于承载事务数据,通常粒度最细
,其粒度是每一行对应一个事务,例如订单销售事务事实表。 - 周期快照事实表,
按固定时间间隔(如每天、每周)记录业务过程的状态或指标,用于监控趋势变化
。它不跟踪具体事务,而是记录某一时间点的状态快照,例如库存每日快照表,账号余额每周快照表。 - 累计快照事实表,
用于跟踪单一业务实体的全生命周期过程,记录从开始到结束的多个关键事件的时间戳及状态变化
,同一行数据会随着流程推进多次更新,适合分析流程时效性,通常这类事实表比较少见,如订单全生命周期表。
事实表的设计原则
明细层设计(DWD层):
- 仅退化必要的维度(如 动态价格字段)。
- 其他维度属性通过外键关联维度表,确保数据一致性和灵活性。
汇总层设计(DWS层):
- 根据查询需求
退化高频维度字段
(如 product_category, city)。 - 通过预聚合和冗余维度提升查询性能。
- 根据查询需求
维度退化的决策需要分层处理,DWD层谨慎退化(仅限必要场景),DWS层主动退化(优化查询性能)
,最终目标是通过合理的设计,在数据一致性、存储效率和查询性能之间找到平衡。
下面是一个维度退化的样例
-- DWD层(规范化设计)
CREATE TABLE dwd_fact_sales_order (
order_item_key BIGINT,
date_key INT,
product_key INT,
customer_key INT,
promotion_key INT,
order_id VARCHAR, -- 退化维度
quantity INT,
unit_price DECIMAL,
...
);
-- DWS层(退化维度提升性能)
-- dws_sales_daily依然是事实表,只是它是聚合事实表,粒度比dwd_fact_sales_order大
CREATE TABLE dws_sales_daily (
date_key INT,
product_category VARCHAR, -- 从dim_product退化
customer_province VARCHAR, -- 从dim_customer退化
total_sales DECIMAL,
total_orders INT
);
三、维度表
维度代表分析事务时所关注的视角或角度
。在维度建模中,维度是描述业务过程中各种环境或情境的属性,例如时间、地点、买家、卖家等。说白一点就是后续分析时通过哪些条件来分析。
下面是时间维度和客户维度的样例
缓慢变化维(Slowly Changing Dimensions)
维度的属性并不是始终不变的,它会随着时间的流逝发生缓慢的变化,这种随时间发生变化的维度
我们一般称之为缓慢变化维(SCD)。比如员工表中的部门维度,员工的所在部门有可能两年后调整一次。
四、模型分类
维度建模按数据组织类型划分可分为星型模型、雪花模型、星座模型
。
- 星型模型
星型模型主要是维表和事实表,以事实表为中心,所有维度直接关联在事实表上,呈星型分布
。开头的订单销售案例就是星型模型(一般利用维度退化等操作,反范式设计,利用适当冗余来避免模型过于复杂,提高易用性和分析效率,性能相对较高) - 雪花模型
雪花模型,在星型模型的基础上,维度表上又关联了其他维度表
。这种模型维护成本高,性能方面也较差,所以一般不建议使用。尤其是基于hadoop体系构建数仓,join越多性能越差
。(维度表的设计更加规范,符合范式,有效降低数据冗余,维度表之间不会相互关联,但是性能较低) - 星座模型
星座模型,是对星型模型的扩展延伸,多张事实表共享维度表
。数仓模型建设后期,大部分维度建模都是星座模型。(星座模型其实就是星型模型的集合)
五、维度建模步骤
维度建模的步骤本质是 "从业务需求出发,自顶向下设计
":
- 明确分析什么(业务过程) → 比如:下单、支付、物流等
- 细化到具体每一行数据(粒度) → 比如:每个订单,有些情况是每个订单下还有子订单
- 确定分析角度(维度) → 比如:时间维度、用户维度、商品维度、地域维度
- 定义量化指标(事实) → 比如:订单事实表
- 落地为物理模型(将维度与事实关联,形成星型模型或雪花模型)
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。