数据建模是创建数据及其在组织或系统内的关系的概念表示的过程。维度建模是一种以用户直观且易于理解的方式呈现数据。它还提供高性能访问、灵活性和可扩展性,以适应业务需求的变化。
在本文中,我们将深入概述数据建模,特别关注 Kimball 的方法。此外,还将介绍用于以用户友好且直观的方式呈现数据的其他技术。现代数据仓库的一项特别有趣的技术是将数据存储在一个宽表中,尽管这种方法可能并不适合所有查询引擎。我们还将介绍可在数据仓库、数据湖、数据湖屋等中使用的技术。但是,为特定用例和查询引擎选择适当的方法非常重要。
什么是维度建模
每个维度模型都由一个或多个具有多部键的表(称为事实表)以及一组称为维度表的表组成。每个维度表都有一个主键,该主键与事实表中多部分键的组成部分之一精确对应。这种独特的结构通常称为星型模式。在某些情况下,可以使用称为雪花模式的更复杂的结构,其中维度表连接到较小的维度表
维度建模的好处
维度建模提供了一种实用且有效的方法来组织和分析数据,从而带来以下好处:
- 业务用户简单易懂。
- 改进的查询性能可加快数据检索速度。
- 灵活性和可扩展性,以适应不断变化的业务需求。
- 确保跨多个来源的数据一致性和集成。
- 增强的用户采用率和自助服务分析。
既然我们已经讨论了维度建模是什么以及它给组织带来的价值,那么让我们探讨一下如何有效地利用它。
数据和维度建模方法
虽然我打算主要关注 Kimball 的方法,但在深入探讨之前,让我们简要介绍一下其他一些流行的技术。
Inmon方法论
Inmon 建议在数据仓库中使用标准化数据模型。该方法支持数据集市的创建。这些数据集市是数据仓库的较小的专门子集,可满足特定业务领域或用户组的需求。这些旨在为特定业务职能或部门提供更加定制和高效的数据访问体验。
数据拱顶
Data Vault 是一种专注于可扩展性、灵活性和可追溯性的建模方法。它由三个核心组件组成:Hub、Link 和 Satellite。
中心表
中心表是所有不同实体的集合。例如,帐户中心将包括帐户、account_ID、load_date 和 src_name。这使我们能够跟踪记录加载时的原始位置,以及是否需要从业务密钥生成的代理密钥。
链接表
链接表在中心表之间建立关系并捕获不同实体之间的关联。它们包含相关中心表的外键,从而能够创建多对多关系。
卫星表
卫星表存储有关中心的描述信息,提供附加上下文和属性。它们包括历史数据、审计信息以及与特定时间点相关的其他相关属性。
Data Vault 的设计允许灵活且可扩展的数据仓库架构。它促进数据可追溯性、可审计性和历史跟踪。这使得它适合数据集成和敏捷性至关重要的场景,例如在高度监管的行业或快速变化的业务环境中。
单个大表
大表将数据存储在一张宽表中。使用一张大表或非规范化表可以简化查询、提高性能并简化数据分析。它消除了复杂连接的需要,简化了数据集成,并且在某些情况下可能是有益的。然而,它可能会导致冗余、数据完整性挑战以及维护复杂性增加。在选择单个大表之前请考虑具体要求。
AND交易AS (
SELECT 1000001 AS order_id, TIMESTAMP ( '2017-12-18 15:02:00' ) AS order_time,
STRUCT( 65401 AS id, 'John Doe' AS name, 'Norway' AS location) AS customer,
[
STRUCT( 'xxx123456' AS sku, 3 AS数量, 1.3 AS价格),
STRUCT( 'xxx535522' AS sku, 6 AS数量, 500.4 AS价格),
STRUCT( 'xxx762222' AS sku, 4 AS数量, 123.6 AS价格)
] AS订单
UNION ALL
SELECT 1000002 , TIMESTAMP ( '2017-12-16 11:34:00' ),
STRUCT( 74682 , 'Jane Smith' , '波兰' ) AS客户,
[
STRUCT( 'xxx635354' , 4 , 345.7 ),
STRUCT( 'xxx828822' , 2 , 9.5 )
] AS订单
)
从交易中选择 *
对于一张宽表,我们不需要连接表。我们可以只用一张表来汇总数据并进行分析。此方法可提高 BigQuery 的性能。
从交易 t、UNNEST (t.orders)中选择customer.name、sum (a.quantity)作为按 customer.name分组。
Kimball方法论
Kimball 方法非常强调创建称为数据仓库的集中式数据存储库。该数据仓库作为单一事实来源,以一致且结构化的方式集成和存储来自各种业务系统的数据。
该方法为设计、开发和实施数据仓库系统提供了一套全面的指南和最佳实践。它非常重视创建维度数据模型,并优先考虑简单性、灵活性和易用性。现在,让我们深入研究 Kimball 方法的关键原则和组成部分。
实体模型到维度模型
在我们的数据仓库中,数据源通常位于实体模型中,这些实体模型被规范化为多个表,其中包含应用程序的业务逻辑。在这种情况下,这可能具有挑战性,因为需要了解表和底层业务逻辑之间的依赖关系。创建分析报告或生成统计数据通常需要连接多个表。
要创建维度模型,数据需要经过提取、转换和加载 (ETL) 过程,将其非规范化为星型模式或雪花模式。此过程中的关键活动包括识别事实表和维度表以及定义粒度。粒度决定了事实表中存储的详细程度。例如,可以每小时或每天聚合交易。
假设我们有一家销售自行车和自行车配件的公司。在这种情况下,我们有以下信息:
- 交易
- 商店
- 客户
- 产品
根据我们的业务知识,我们知道我们需要收集有关销售量、一段时间内的数量以及按地区、客户和产品细分的信息。有了这些信息,我们就可以设计我们的数据模型。交易表将充当我们的事实表,商店、客户和产品表将充当维度表。
事实表
事实表通常表示业务事件或事务,并包括与该事件关联的度量或度量。这些指标可以包含各种数据点,例如销售额、销售数量、客户互动、网站点击或任何其他可提供业务绩效洞察的可衡量数据。事实表还包括与维度表建立关系的外键列。
事实表设计的最佳实践是将所有外键放在表的顶部,然后进行测量。
事实表类型
- 事务事实表提供了最低级别的粒度,因为一行代表事务系统中的一条记录。数据每天或实时刷新。
- 定期快照事实表捕获某个时间点(例如月底)事实表的快照。
- 累积快照事实表总结了流程开始和结束之间的可预测步骤中发生的测量事件。
- 无事实事实表保存有关发生的事件的信息,无需任何指标。
维度表
维度表是维度建模中的一种表,包含描述性属性,例如有关产品、其类别和类型的信息。维度表为事实表中存储的定量数据提供上下文和视角。
维度表包含一个唯一键,用于标识表中的每条记录,称为代理键。该表可以包含业务键,该业务键是来自源系统的键。一个好的做法是生成代理键而不是使用业务键。
创建代理键有多种方法:
- 哈希:可以使用 MD5、SHA256 等哈希函数(例如 md5(key_1, key_2, key_3) )生成代理键。
- 递增:使用始终递增的数字生成的代理键(例如 row_number()、identity)。
- 连接:通过连接唯一键列生成的代理键(例如 concat(key_1, key_2, key_3) )。
- -Unique generated:使用生成唯一标识符的函数(例如GENERATE_UUID())生成的代理键
选择的方法取决于用于处理和存储数据的引擎。它会影响查询数据的性能。
维度表通常包含层次结构。
a) 例如,父子层次结构可用于表示员工与其经理之间的关系。
b) 属性之间的层次关系。例如,时间维度可能具有年、季、月、日等属性,形成层次结构。
维度表的类型
一致维度:
一致维度是可以被多个事实表使用的维度。例如,区域表可以由不同的事实表使用。
退化维度:
当属性存储在事实表而不是维度表中时,就会出现退化维度。例如,可以在事实表中找到交易号。
垃圾维度:
该属性包含不适合现有维度表的无意义属性,或者是表示各种状态组合的标志和二进制值的组合。
同一扮演维度:
同一维度键在事实表中包含多个外键。例如,日期维度可以引用事实表中的不同日期,例如创建日期、订单日期和交货日期。
静态维度:
静态维度是通常永不改变的维度。它可以从参考数据加载,无需更新。一个例子是公司的分支机构列表。
桥接表:
当事实表和维度表之间存在一对多关系时,将使用桥接表。
缓慢变化的维度
缓慢变化的维度(SCD)是维度建模中的一个概念。它处理维度表中维度属性随时间的变化。SCD 提供了一种机制,用于在业务实体发展及其属性变化时维护维度表中的历史和当前数据。SCD 有六种类型,但最流行的三种是:
- SCD 类型 0:在此类型中,仅将新记录导入到维度表中,而不进行任何更新。
- SCD 类型 1:在此类型中,将新记录导入维度表,并更新现有记录。
- SCD 类型 2:在此类型中,导入新记录,并为更改的属性创建具有新值的新记录。
例如,当 John Smith 搬到另一个城市时,我们使用 SCD Type 2 来保存与伦敦相关的交易信息。在本例中,我们创建一条新记录并更新前一条记录。因此,历史报告将保留他在伦敦购买的信息。
MERGE INTO client AS tgt
USING (
SELECT
Client_id,
Name,
Surname,
City
GETDATE() AS ValidFrom
' 20199 -01 -01 ' AS ValidTo
from client_stg
) AS src
ON (tgt.Clinet_id = src.Clinet_id AND tgt.iscurrent = 1 )
匹配后更新设置 tgt.iscurrent = 0 , ValidTo = GETDATE(),当 不匹配时
INSERT (Client_id, name, Surname, City, ValidFrom, ValidTo, iscurrent)
VALUES (Client_id, name, Surname, City, ValidFrom, ValidTo, 1 );
这就是当我们将新值和以前的值保留在不同的列中时 SCD 3 的外观。
星型模式与雪花型模式
设计数据仓库最流行的方法是使用星型模式或雪花模式。星型模式具有事实表和与事实表相关的维度表。在星型模式中,存在事实表和与事实表直接相关的维度表。另一方面,雪花模式由事实表、与事实表相关的维度表以及与这些维度表相关的附加维度组成。
这两种设计之间的主要区别在于它们的标准化方法。星型模式保持数据非规范化,而雪花模式确保规范化。星型模式旨在提高查询性能。雪花模式是专门为处理大维度的更新而定制的。如果您在更新大量维度表时遇到挑战,请考虑转换到雪花模式。
数据加载策略
在我们的数据仓库、数据湖和数据湖屋中,我们可以有各种加载策略,例如:
全量加载:全量加载策略是将源系统中的所有数据加载到数据仓库中。此策略通常用于出现性能问题或缺少可以通知行修改的列的情况。
Incremental Load:增量加载策略涉及仅加载自上次数据加载以来的新数据。如果源系统中的行无法更改,我们可以根据唯一标识符或创建日期仅加载新记录。我们需要定义一个“水印”,用于选择新行。
Delta Load:Delta加载策略侧重于仅加载自上次加载以来已更改或增量的记录。它与增量加载的不同之处在于它专门针对增量更改而不是所有新记录。Delta 加载策略在处理大量数据更改时非常高效,并可显着减少所需的处理时间和资源。
加载数据的最常见策略是先填充维度表,然后填充事实表。这里的顺序很重要,因为我们需要使用事实表中维度表的主键来创建表之间的关系。有一个例外,当我们需要在维度表之前加载事实表时,这种技术名称就是延迟到达维度。
在这种技术中,我们可以在维度表中创建代理键,并在填充事实表后通过 ETL 过程更新它。