#数据仓库# #DataVault# #哈希值# #PostgreSQL#
前言 | Data Vault介绍
本文是构建基于Data Vault建模思想的数据仓库的系列文章的其中一篇,后续还会有很多章节帮助我们一起来逐步理解DV数据仓库的一些关键知识点。
文章中的SQL语法基于PostgreSQL 14.1 版本;
关于Data Vault数据仓库的定义如下所示:
A detail oriented, historical tracking and uniquely linked set of normalized tables that support one or more functional areas of business. It is a hybrid approach encompassing the best of breed between 3NF and Star Schemas. The design is flexible, scalable, consistent and adaptable to the needs of the enterprise.
其中关键点有下面几个:
- 面向细节的(是指DV模型抽象了从业务系统的3rd Normal Form过来的业务数据,与业务系统的颗粒度保持一致,并未进行聚合)
- 能够追踪历史(DV数据模型中的一种机制,会保存所有历史数据)
- 被唯一连接起来的范式化数据表集合(DV数据模型,通过Link表,将不同实体Hub及其属性Satellite关联起来)
- 位于在第三范式和星型模型之间(从数据架构角度看,DV是位于源系统与星型模型之间的)
- 设计灵活,可扩展,一致,适应性强(主要是指DV模型对于业务对象的抽象设计能够具有很高的适应性及扩展性)
下面是DV数据模型的一个示意图,可以看到Data Vault数据模型主要包含Hub,Satellite和Link三类数据对象,以及PIT和Bridge等辅助对象。
- Hub:唯一的业务主键列表。
- Link:唯一的代表两个或多个业务键之间关系的列表。
- Satellite:由 CDC(变化数据捕获)驱动,并按变化率或类型划分(分类)数据,包含“随时间变化的描述性信息”的数据。
数据架构
基于Data Vault数据仓库架构如下图蓝色区域所示,基本分为如下4层:
- Staging Area (数据临时存储层,包含CDC逻辑)
- Persistant Staging Area(数据永久存储层)
- Raw Data Vault(抽象数据模型层,抽象为Hub,Satellite和Link)
- Dimensional Data Modeling & Data Mart (数据展现层,星型模型和Cube)
为了演示的目的,我们基于PostgreSQL 14.1建立对应的数据分层,分层以Schema为分层依据,命名规范如下所示:
Layer Name | Description | Remark |
000_SRC | Source Data | 仅用于此例子演示目的 |
100_STG | Staging Area | 数据临时存储层 |
150_PSA | Persistant Staing Area | 数据永久存储层 |
200_RDV | Raw Data Vault | 原始Data Vault模型层 |
300_DWA | Dimensional Data Warehouse & Data Mart Applications | 多维数据仓库和数据集市层 |
数据流向按"000_SRC" -> "100_STG" -> "150_PSA" -> "200_RDV" -> "300_DWA"顺序,如下所示;
其中包含了一个源数据表OFFER
-- 源数据表OFFER
CREATE TABLE IF NOT EXISTS "000_SRC"."OFFER"
(
"OfferID" integer NOT NULL,
"Offer_Long_Description" character varying(100) COLLATE pg_catalog."default",
CONSTRAINT "OFFER_pkey" PRIMARY KEY ("OfferID")
)
核心 | 哈希值计算方法
我们曾经在上一篇文章你所不了解的数据仓库第一层中提及CDC的概念,即Change Data Capture,那么今天这篇文章可以说是实现CDC中的关键一步,也是构建Data Vault数据仓库模型中的一个通用计算哈希值(哈希完整记录)的方法。
哈希值(HASHKEY):通常是对业务主键进行哈希计算后的结果值;
哈希完整记录(HASH_FULL_RECORD):通常是对卫星表中所有带有描述性信息,和业务主键一起进行哈希计算后的结果值;
- 哈希完整记录列通常用于检测卫星表中的数据的更改,且可用于比较多个单独列的数据变动情况。
- 使用哈希值的主要目的是用于改善数据差异计算的性能,尤其是当多个描述性字段都有变化的情况,变化的字段越多,其性能改善越显著;
- 哈希值的目的不是加密,也不是保护数据。由于哈希值的确定性,大多数哈希算法可以应用于平均跨越多个分区或分片的随机分布。换句话说,哈希值可以支持大数据环境下,集群模式分布式数据库中数据的负载均衡,且具有预测性,如对于下面的MD5计算,其结果无论在任何国家地区的数据节点,其计算结果永远是"399BD1EE587245ECAC6F39BEAA99886F";
SELECT UPPER(MD5('PostgreSQL'::text))
哈希值的计算顺序如下所示:
其目的如下:
- 通过COALESCE函数将NULL值转换为空;
- 通过TRIM函数将主键两边的空去除;
- 通过CONCAT连接多个业务主键(如一个业务主键由多个子属性字段构成);
- 通过MD5函数计算哈希值;
- 通过UPPER函数将计算后的哈希值转换为大写(为了便于在不同平台比对数据差异);
具体代码如下:
SELECT "OFFER"."OfferID",
"OFFER"."Offer_Long_Description",
UPPER(MD5(CONCAT(TRIM(BOTH FROM COALESCE("OFFER"."OfferID"::text, ''::text
) -- END COALESCE
) -- END TRIM
, '' ) -- END CONCAT
) -- END MD5
) -- END UPPER
AS "HASHKEY"
FROM "000_SRC"."OFFER"
除此之外,哈希值(HASHKEY)将会在后续计算CDC的过程中参与到数据集合的JOIN操作中,通过将业务主键转换为哈希值,能够显著提高数据在做笛卡尔积的性能。
此为后话,我们下期再聊~
祝各位2022年,新年快乐!
2022,02,03 凌晨
参考文献
Hash Diff calculation with SQL Server (Datavault Series) | Hans Michiels – Blog and more
Hash Keys in the Data Vault – Scalefree Blog