数据仓库设计之维度建模
在数据仓库系统中,DIM层(Dimension Layer)主要用于存储维度数据,这些数据提供了描述性信息,以支持对事实数据的理解和分析。
1. 维度建模理论
1.1 基础概念
事实表(Fact Table):记录了企业的度量值或指标,比如销售额、成本等。这些数据通常是数值型的,并且可以被聚合;
维度表(Dimension Table):提供关于事实表中的数据的上下文信息,如时间、地点、产品等。维度表包含描述性属性,它们帮助解释事实表中的数据。
星型模式(Star Schema):一种简单的维度模型结构,其中事实表位于中心,周围是多个维度表。每个维度表直接连接到事实表。
雪花模式(Snowflake Schema):在星型模式的基础上进一步规范化维度表,将一些维度表拆分为更细粒度的表,以减少冗余。
1.2 设计原则
1.2.1 层次结构
如果维度中有层次关系,应当在设计时体现出来。如时间维度中的年->季度->月,应在维度表中体现。
1.2.2 代理键(Surrogate Key)
使用代理键作为维度表的主键,通常是一个自增的整数ID。代理键的优点是可以在不影响现有数据的情况下更新维度表中的自然键。
优点
简洁且固定大小,有助于提高数据库操作效率。
不受业务规则变更的影响,保证了数据的一致性和稳定性。
便于处理缓慢变化维度的问题,特别是当需要保留历史版本时。
支持跨多个维度表的一致性引用,即一致性维度。
缺点
对于最终用户来说不如自然键直观。
需要额外的映射机制来关联自然键与代理键,增加了系统的复杂度。
1.2.3 自然键(Natural Key)
自然键是指数据源中已经存在的唯一标识符,它能够唯一地识别一条记录。这个键通常来自于业务流程本身,例如客户的身份证号码、产品的SKU码等。
使用自然键作为辅助键,如日期、产品ID等,用于连接事实表。自然键可以确保数据的一致性。
优点
直接反映了业务实体的特性。
对于用户来说比较直观,容易理解。
缺点
可能会因为业务规则的变化而改变,导致数据仓库中的历史数据变得不一致。
有时可能不够简洁,长度较长,影响数据库性能。
如果自然键不是数值型,则可能需要更多的存储空间。
在处理缓慢变化维度时可能会遇到困难,尤其是在类型2(添加新行并更新现有行)的情况下。
1.2.4 保持数据的原子性和一致性
维度表中的每一列都应该表示一个独立的概念,避免在单个字段中存储复合信息。同时,要确保数据的一致性和准确性。
1.2.5 采用标准化命名
为了提高可读性和可维护性,维度表中的字段命名应当遵循一定的规范,使字段名清晰明了。
1.2.6 处理缓慢变化维度(SCD)
缓慢变化维度(Slowly Changing Dimensions, SCD)是数据仓库设计中的一个重要概念,涉及到如何处理维度表中的数据在一段时间内发生的变化。当维度表中的某些属性随时间变化时,需要妥善处理这些变化,以保持数据的历史记录和一致性。关于 SCD 的设计请参考《数据仓库设计之缓慢变化维度(SCD)》
2. 维度表的设计
维度表主要用于存储描述性信息。它们通常与事实表关联,提供上下文信息。基于上面的设计原则,维度表的设计需要考虑数据粒度、属性完整性、历史数据处理、性能优化等方面。
2.1 设计流程
维度表的设计流程如下:
3. 示例
3.1 日期维度表
日期维度表是数据仓库中常见的维度表之一,主要用于提供与日期相关的详细信息,如下面的维度表 dim_common_date:
DROP TABLE IF EXISTS dim_common_date;
CREATE EXTERNAL TABLE IF NOT EXISTS dim_common_date (
date_id INT, -- 代理键
year INT, -- 年,如:2024
quarter INT, -- 季度,范围:[1,2,3,4],如:1
month INT, -- 月,范围:[1,2,...,12],如:2
day INT, -- 日,范围:[1,2,...,31],如:3
week_of_year INT, -- 周,范围:[1,2,...,53],如:1
day_of_week INT, -- 周几
dt DATE, -- 日期,如:2024-02-03
is_weekend BOOLEAN, -- 是否为周末
is_holiday BOOLEAN, -- 是否为公共假日
holiday VARCHAR(255), -- 节假日,如:春节
season VARCHAR(10), -- 季节,范围:[春,夏,秋,冬]
primary key(date_id) disable novalidate
) COMMENT '日期维度表'
STORED AS ORC
LOCATION '/data/jhiot/dim/db/common_date/'
TBLPROPERTIES ('orc.compress' = 'snappy');
首先,dim_common_date 表我们采用了 Hive 中的外部表,用于存储丰富的日期相关信息。这里选择外部表的主要原因是数据共享、数据保留、数据更新以及多系统集成的需求。该表中的数据存放在指定的HDFS路径下(LOCATION指定的 /data/jhiot/dim/db/common_date/ 路径下),使得数据可以被多个表或系统共享,并且在删除表时不会删除实际数据。如下图:
下图为在 Hive 中查询的日期维度表数据:
其次,指定表的存储格式为 ORC(Optimized Row Columnar),这是一种高效的数据存储格式,适用于大数据处理。ORC 格式支持压缩、列式存储、索引等特性,能够提高查询性能和存储效率。
在表属性 TBLPROPERTIES 中设置了 ORC 文件的压缩方式为 Snappy,Snappy 是一种高效的压缩算法,能够在保持较高压缩率的同时提供较快的解压速度,适合大数据场景。