Kimball维度建模技术概述
记录一下读《数据仓库工具箱》时的思考,摘录一些书中关于维度建模比较重要的思想与大家分享🤣🤣🤣
第二章前言部分作者提到:技术的介绍应该通过涵盖各种行业的熟悉的用例展开(赞同哈哈 确实比抽象地讲解概念要好理解🤣🤣🤣)。
书中从第三章开始是通过各行业的用例去讲解维度建模,第二章则是维度建模技术的总体介绍(很多概念,挺抽象的🤣🤣🤣)。
前言部分作者也有提到:我们并不期望您一开始就从头到尾阅读本章,但希望您能将本章作为所提供的技术参考。本节介绍的技术,在所有维度设计工作中都需要考虑。本书的每一章几乎都会涉及本节所介绍的概念。
Kimball维度建模技术概述01、基本概念
书接上回~🤣🤣🤣🤣🤣🤣
Kimball维度建模技术概述
2.2 事实表技术基础
2.2.1 事实表结构
- 发生在现实世界中的操作型事件,其所产生的可度量数值,存储在事实表中。
- 事实表的设计完全依赖于物理活动,不受可能产生的最终报表的影响。
主键:
- 通常为复合主键,由多个外键组合,唯一标识一条记录(例如 订单ID + 产品ID。)。
外键:
- 连接维度表的字段,提供事实表记录的上下文(如时间ID、产品ID、客户ID)。
度量值:
- 存储可聚合的指标数据(如销售额、订单数量、库存量)。
粒度:
- 每条记录代表的业务事件或过程的最小单位(如每笔订单的每个商品)。
字段名 | 类型 | 描述 |
---|---|---|
fact_id |
INT | 主键 |
time_id |
INT | 时间维度外键 |
product_id |
INT | 产品维度外键 |
customer_id |
INT | 客户维度外键 |
sales_amount |
DECIMAL | 销售金额 |
sales_quantity |
INT | 销售数量 |
Tip:事实表也可包含可选的退化维度键和日期/时间戳。(退化维度,在专栏里维度表技术基础里有讲~)
2.2.2 可加、半可加、不可加事实
事实表中的数字度量可划分为三类:
类别 | 定义 | 示例 | 适用场景 | 注意事项 |
---|---|---|---|---|
可加事实 | 在所有维度上都可以直接求和的度量值。 | 销售金额、销售数量、成本 | 适用于跨时间、产品、客户等维度的总量分析。 | 无需额外计算逻辑,直接进行求和操作即可。 |
半可加事实 | 只能在某些维度上求和,而在其他维度(通常是时间维度)上不能求和。 | 库存量、账户余额、银行存款 | 时间快照、状态监控场景,例如监控某日的库存或余额状态。 | 时间维度上不能直接求和,需通过取最近值或计算变化量等方式分析。 |
不可加事实 | 在所有维度上都无法直接求和的度量值,通常是比率或衍生指标。 | 利润率、平均单价、转化率 | 适用于分析比率、平均值或需要权重处理的业务场景,例如分析效率。 | 必须结合上下文设计加权平均、除法等逻辑,不能通过直接聚合获得结果。 |
类别 | 示例字段名 | 示例描述 | 是否可跨时间维度求和 | 处理方法 |
---|---|---|---|---|
可加事实 | sales_amount |
记录销售金额,例如一笔订单的总金额。 | 是 | 直接使用 SUM(sales_amount) 进行求和即可。 |
可加事实 | sales_qty |
记录销售数量,例如商品的销售件数。 | 是 | 可按时间、商品、客户等维度聚合计算总量。 |
半可加事实 | stock_qty |
记录某一时间点的库存量,例如每天的库存快照。 | 否 | 取最新时间点的值或计算时间点之间的变化量。 |
半可加事实 | account_bal |
记录某一时间点的账户余额,例如每天的账户快照。 | 否 | 取最后一个时间点的余额作为有效值。 |
不可加事实 | profit_margin |
记录利润率,例如单个商品的利润率。 | 否 | 按比率的定义公式重新计算(如总利润/总收入)。 |
不可加事实 | avg_price |
记录平均单价,例如按订单计算的商品平均单价。 | 否 | 通过加权计算重新求值(如总金额/总数量)。 |
2.2.3 事实表中的空值
事实表中可以存在空值度量(所有聚集函数sum、count等都可针对空值事实计算)。
但是事实表中的外键不能存在空值,因为它们是维度表与事实表之间的关联桥梁。空值的外键意味着事实表中的记录没有关联到任何有效的维度数据,无法确保确保数据的完整性和一致性(引发数据质量问题)。
2.2.4 事务事实表(Transactional Fact Table)
事务事实表记录的是单个业务事务或事件的详细信息,每条记录代表一个独立的操作,如一次购买、一次交易或一次订单等。数据粒度通常非常细,每一行记录都是一个具体的事务。
- 粒度细:每条记录表示一个单独的事件或操作。
- 数据量大:由于记录详细的事务,数据量较大,且随着业务发展不断增加。
- 高更新频率:事务数据通常在操作发生时实时更新。
- 适用于实时或近实时分析:事务事实表能提供详细的业务过程数据,用于监控和分析业务活动。
字段名 | 描述 |
---|---|
transaction_id |
事务ID(唯一标识) |
customer_id |
客户ID |
product_id |
产品ID |
time_id |
时间ID(外键) |
quantity |
销售数量 |
sales_amount |
销售金额 |
payment_status |
付款状态 |
2.2.5 周期快照事实表(Periodic Snapshot Fact Table)
周期快照事实表记录在特定时间点或时间段内的业务状态,通常会在某个固定时间间隔(如每天、每周或每月)进行快照。
每条记录通常代表某个周期结束时的业务状态,体现的是在该时间点的“快照”信息。
- 粒度较粗:每条记录代表一个周期的业务状态,而不是单个事务。
- 数据量较小:与事务事实表相比,周期快照事实表记录的数量较少,因为它仅记录周期性汇总的业务状态。
- 周期性更新:快照表通常定期(如每天、每月)更新,更新频率较低。
- 适用于趋势分析和汇总:周期快照表非常适合用于分析业务在特定时间点的状态变化,例如月度销售趋势、客户活跃度变化等。
字段名 | 描述 |
---|---|
snapshot_date |
快照日期 |
customer_id |
客户ID |
total_sales |
总销售金额 |
total_quantity |
总销售数量 |
total_orders |
总订单数量 |
2.2.6 累计快照事实表(Cumulative Snapshot Fact Table)
累计快照事实表记录的是某个度量数据(如库存数量、账户余额等)的累积变化情况。与周期快照表不同,累计快照表记录的是从一个起始点开始,随时间积累变化的数据状态。这种表适用于需要持续积累的度量数据,如库存、客户余额、累计销售等。
- 粒度较粗:每条记录通常表示某个特定时间点的累计度量数据。
- 持续更新:与周期快照表不同,累计快照表在每次数据更新时都会进行累积。它不会丢失先前的累积数据,而是随着时间推移不断更新。
- 适用于长期趋势分析:累计快照表能够帮助跟踪业务的长期变化,如追踪某个客户的累计购买金额、账户余额变化等。
字段名 | 描述 |
---|---|
snapshot_date |
快照日期 |
account_id |
账户ID |
balance |
累计余额 |
total_deposit |
累计存款 |
total_withdrawal |
累计取款 |
- 每条记录表示某个时间点的账户余额,包括从账户创建到该日期的所有存款和取款的累计情况。
特性 | 事务事实表 | 周期快照事实表 | 累计快照事实表 |
---|---|---|---|
粒度 | 细粒度,每个事件或事务一条记录 | 粗粒度,按周期(如日、月、年)记录状态 | 粗粒度,按累积数据(如累计销售额)记录 |
数据量 | 大,随时间增加,记录每个事务 | 相对较小,通常按周期记录数据 | 适中,数据随着累计情况不断增长 |
更新频率 | 高,实时或近实时更新 | 低,定期(如每日、每月)更新 | 持续更新,随着业务过程变化而更新 |
适用场景 | 详细的业务过程分析,如订单追踪 | 趋势分析、月度或季度报告等 | 长期数据跟踪,如账户余额、累计销售等 |
示例 | 每一笔订单的详细信息 | 月度销售汇总数据 | 客户账户余额的累计变化 |