在数据仓库的维度建模(Dimensional Modeling) 体系中,事实表(Fact Table) 和 维度表(Dimension Table) 是构成星型模型(Star Schema)的两大核心组件。它们分工明确、相辅相成,共同支撑高效的业务分析。
一、事实表(Fact Table)
1. 定义
事实表用于存储业务过程中的可度量的数值型指标(即“事实”),以及关联维度的外键。
2. 核心特征
- 内容:
- 外键(Foreign Keys):指向各个维度表的主键(如
user_id,product_id,date_id)。 - 事实(Facts):可量化的业务指标,通常是数字(如销售额、订单数、点击次数)。
- 外键(Foreign Keys):指向各个维度表的主键(如
- 粒度(Grain)明确:每一行代表一个原子业务事件或汇总单元。
例如:“2024年11月5日,用户U1001在商品P2002上完成了一笔订单,金额为99元”。 - 数据量大:通常包含数百万至数十亿行。
- 字段少但行多:列数不多(主要是外键 + 少量事实),但记录数巨大。
3. 事实的类型
| 类型 | 说明 | 示例 |
|---|---|---|
| 可加性事实 | 可沿所有维度汇总 | 销售额、订单数 |
| 半可加性事实 | 仅能沿部分维度汇总 | 账户余额(可按用户汇总,不能按时间直接相加) |
| 不可加性事实 | 不能直接汇总,需通过其他事实计算 | 利润率、平均单价 |
4. 示例
-- 订单事实表(粒度:每笔订单中的每个商品项)
fact_order_item (
order_id STRING, -- 订单ID(也可作为退化维度)
user_id STRING, -- → dim_user
product_id STRING, -- → dim_product
date_id INT, -- → dim_date (格式: 20241105)
channel_id INT, -- → dim_channel
quantity INT, -- 事实:购买数量(可加)
sales_amount DECIMAL, -- 事实:销售金额(可加)
discount DECIMAL, -- 事实:折扣金额(可加)
cost DECIMAL -- 事实:成本(可加)
)
二、维度表(Dimension Table)
1. 定义
维度表用于描述业务过程的上下文信息(即“谁、什么、何时、何地、如何”),提供分析的分类和描述属性。
2. 核心特征
- 内容:
- 主键(Primary Key):唯一标识一个维度成员(如
user_id,product_sk)。 - 属性(Attributes):描述性文本或分类字段(如用户姓名、商品类目、城市、是否节假日)。
- 主键(Primary Key):唯一标识一个维度成员(如
- 数据量小:通常几千到几百万行(远小于事实表)。
- 字段多但行少:包含大量描述性列,用于下钻(Drill-down)分析。
- 去规范化(Denormalized):为提升查询性能,常将相关属性冗余存储(如商品表直接包含“类目名称”,而非只存“类目ID”)。
3. 常见维度类型
- 时间维度(Time):年、季度、月、日、星期、是否节假日
- 用户维度(User):用户ID、姓名、性别、年龄、地域、会员等级
- 产品维度(Product):商品ID、名称、品牌、类目、价格区间
- 地理维度(Location):国家、省份、城市、区域
- 退化维度(Degenerate Dimension):没有独立维度表的属性(如订单号、发票号),直接放在事实表中
4. 示例
-- 用户维度表
dim_user (
user_id STRING, -- 主键
user_name STRING,
gender STRING, -- '男'/'女'
age INT,
city STRING, -- '北京市'
province STRING, -- '北京市'
member_level STRING, -- '普通'/'黄金'/'钻石'
register_date DATE,
is_new_user BOOLEAN
)
-- 日期维度表
dim_date (
date_id INT, -- 主键,如 20241105
full_date DATE, -- 2024-11-05
year INT, -- 2024
month INT, -- 11
day INT, -- 5
weekday STRING, -- '星期三'
is_weekend BOOLEAN, -- false
is_holiday BOOLEAN -- false
)
三、事实表 vs 维度表 对比总结
| 特性 | 事实表(Fact Table) | 维度表(Dimension Table) |
|---|---|---|
| 核心内容 | 业务指标(数字) + 外键 | 描述属性(文本/分类) + 主键 |
| 数据量 | 非常大(亿级) | 相对较小(万~百万级) |
| 字段特点 | 列少、行多 | 列多、行少 |
| 更新频率 | 通常只追加(INSERT) | 可能更新(如SCD Type 2) |
| 查询角色 | 被聚合(SUM, COUNT) | 用于过滤(WHERE)、分组(GROUP BY)、展示(SELECT) |
| 模型位置 | 星型模型的“中心” | 星型模型的“辐射点” |
四、它们如何协同工作?
当分析师想查询 “2024年11月北京市黄金会员用户的总销售额” 时:
SELECT
SUM(f.sales_amount) AS total_sales
FROM fact_order_item f
JOIN dim_user u ON f.user_id = u.user_id
JOIN dim_date d ON f.date_id = d.date_id
WHERE
d.full_date >= '2024-11-01'
AND d.full_date <= '2024-11-30'
AND u.city = '北京市'
AND u.member_level = '黄金';
- 事实表 提供
sales_amount进行求和。 - 维度表 提供
city和member_level用于筛选,full_date用于时间范围过滤。
✅ 总结一句话:
事实表回答“有多少”,维度表回答“是什么、谁、何时、何地”。
二者结合,才能让数据既可度量又可理解,支撑灵活、高效的业务分析。

2万+

被折叠的 条评论
为什么被折叠?



