【声明】本文章来自穆晨 - 博客园,记录于此方便后期的学习和查阅
一、前言
数据仓库建模包含了几种数据建模技术,除了之前在数据库系列中介绍的ER建模、关系建模,还包括专门针对数据仓库的维度建模技术。
本文将重点介绍数据仓库的维度建模技术,并详细讨论基于ER建模、关系建模、维度建模的数据仓库总体建模体系:规范化数据仓库,维度建模数据仓库,以及独立数据集市。
二、维度建模的基本概念
维度建模(dimensional modeling)是一种专门用于分析型数据库、数据仓库、数据集市建模的方法。其本身也属于一种关系建模方法,相比数据库中的关系建模,增加了两个概念。
1. 维度表(dimension)
维度表:对分析主题所属类型的描述。比如"昨天早上张三在京东花费200元购买了一个皮包"。那么以购买为主题进行分析,可从这段信息中提取三个维度:时间维度(昨天早上)、地点维度(京东)、商品维度(皮包)。通常来说维度表信息比较固定,且数据量小。
2. 事实表(fact table)
事实表:对分析主题的度量。比如上面的例子中,200元就是事实信息。事实表包含了与各维度表相关联的外键,并通过JOIN方式与维度表关联。事实表的度量通常是数值类型,且记录数会不断增加,表规模迅速增长。
在数据仓库中,不需要严格遵守规范化设计原则(原因见系列文章的第1篇)。特别说明:本文示例中的主键、外键均只表示一种对应关系。
三、维度建模的三种模式
1. 星形模式(Star Schema)
星形模式:最常用的维度建模方式,由一个事实表和一组维度表组成,具有以下特点:
- 维度表只和事实表关联,维度表之间没有关联关系;
- 每个维度表的主键均为单列,且该键放置在事实表中,作为两表关联的外键;
- 以事实表为核心,维度表围绕核心呈星形分布。
2. 雪花模式(Snowflake Schema)
雪花模式:对星形模式的扩展,每个维表可继续向外连接多个子维度表。
星形模式中的维度表,相对雪花模式来说要大,而且不满足规范化设计。雪花模型相当于将星形模式的大维度表拆分成小维度表,满足了规范化设计。
事实上,雪花模型仅是一种理论上的模型,在实际应用中很少见,因为这样做会导致开发难度增大,而数据冗余问题在数据仓库中并不太care。
下图为使用雪花模式,进行维度建模的关系结构:3. 星座模式(Fact Constellations Schema)
星座模式:也是对星形模式的扩展,每个维度表可以关联到多个事实表。
星形模式和雪花模式都是多维度表对应单个事实表,但在很多时候维度空间内的事实表不止一个,即一个维表也可能被多个事实表用到。在业务发展后期,绝大部分维度建模都采用的是星座模式。
下图为使用星座模式,进行维度建模的关系结构:4. 三种模式对比
雪花模式是将星型模式的维度表进一步划分,使各维度表均满足规范化设计。而星座模式则是允许星形模式中出现多个事实表。
星形模式、雪花模式、星座模式的关系如下图所示:四、实例:零售公司销售主题的维度建模
在进行维度建模前,首先要了解用户需求。在数据库系列的第一篇中讲过,ER建模是当前收集和可视化需求的最佳技术。因此假定和某零售公司进行多次需求PK后,得到以下ER图: 利用建模工具将ER图直接映射到关系图:本例采用星形模型进行维度建模。不论采取何种模式,维度建模的关键在于明确下面四个问题:
1. 哪些维度对主题分析有用?
本例中,产品(PRODUCT)、顾客(CUSTOMER)、商店(STORE)、日期(DATE),4个维度对销售额分析是非常有帮助的;
2. 如何使用现有数据生成维表?
- 维度PRODUCT:由关系PRODUCT、关系VENDOR、关系CATEGORY连接得到;
- 维度CUSTOMER:即为关系CUSTOMER;
- 维度STORE:由关系STROE、关系REGION连接得到;
- 维度DATE:由关系SALESTRANSACTION中的TDate列分离得到。
3. 用什么指标来"度量"主题?
本例的主题是销售,而销量和销售额这两个指标,最能直观反映销售情况。
4. 如何使用现有数据生成事实表?
销量和销售额:由关系SALESTRANSACTION、关系SOLDVIA、关系PRODUCT连接得到。
明确上述四个问题后,便能轻松完成维度建模:可以发现维度建模结果中,存在三个问题:1) 维度表不满足规范化设计(不满足3NF);2) 事实表也不满足规范化设计(1NF都不满足);3) 维度建模中各维度的主键由 ***ID 变成 ***Key;
前两个问题,由于当前建模环境是数据仓库,没有更新操作,所以不需要严格做规范化设计,来消除冗余避免更新异常。
对于第三个问题,***Key这样的字段被称为代理键(surrogate key),是数据仓库的专业术语。它是一个通过自动分配整数生成的主键,没有任何业务意义,用于标识数据仓库表的记录唯一性。使用它主要是为了能够处理"缓慢变化的维度",本文后面会详细介绍。
五、事实表的其它属性
除了对应到维度表的外键和度量属性,通常情况下,事实表还会考虑另外两个属性:事务标识键(transaction identifier)和事务时间(transaction time)。
事务标识键通常被命名为TID,表示各种订单号、事务编号等。之所以没有将该属性放到维度表中,而是放到了事实表中,一个非常主要的原因是它的数量级太大了,每次查询都会耗费很多资源来Join。这种将某些逻辑意义上的维度属性放到了事实表中的做法,被称为退化维度(degenerate dimension)。
将事务时间维度放到事实表中,也是出于相同的考虑。然而这么设计又一次"逆规范化"了:事务标识键非主键,却能决定事务标识时间,显然违背了3NF。但现在是为数据仓库建模,所以这样做是OK的。
另外,在分布式的数据仓库中,事务时间这个字段非常重要。因为事实表的数量级非常大,Hive或者Spark SQL这类分布式数据仓库工具,都会对这些数据进行分区。任何成熟的分布式计算平台,都应该禁止开发人员建立非分区事实表,并默认分区字段为(当天)日期。
六、经典星座模型
1. 共享维度
以前文提到的零售公司为例,假如该公司质量监管部门希望用分析销售主题同样的方法分析劣质产品,那么此时不需要重新维度建模,只需往模型里加入一个新的劣质产品事实表。
新的数据仓库维度建模结果如下:2. 细节事实表和聚集事实表
细节事实表 (detailed fact tables) 中每条记录表示单一事实,而聚集事实表 (aggregated fact tables) 中每条记录则聚合了多条事实。从表的字段上看,细节事实表通常有设置TID属性,而聚集事实表则无。
两种事实表各有优缺点,细节事实表查询灵活,但响应速度相对慢;而聚集事实表虽然提高了查询速度,但会使查询功能受到一定限制。
常见的做法是使用星座模型,同时设置两种类型的事实表:聚集事实表 (可含多个) 和细节事实表。其中,聚集事实表使用细节事实表的维度。
如下维度建模中,采用星座模型综合了聚集事实表(2个)和细节事实表:七、缓慢变化维度问题(slowly changing dimension)
虽然维度表的数据比事实表更稳定。但随着业务的变化,维度表也会发生一些变化。在之前曾抛出一个问题:为什么维度建模后的关系不是***ID,而是***Key。其目的是为了解决一种被称为缓慢变化维度的问题,简称:SCD。
在现实世界中,维度的属性并不是静态的,它会随着时间发生缓慢的变化。这种随时间发生变化的维度,称之为缓慢变化维,并且把处理维度表的历史变化信息的问题称为处理缓慢变化维度的问题,有时也简称为处理SCD的问题。
根据变化剧烈程度,维度可以分为无变化维度、缓慢变化维度和剧烈变化维度。例如:一个人的身份证号、姓名、性别等信息属于不变数据;政治面貌、婚姻状态等属于缓慢变化数据;工作经历、工作单位、培训经历等在某种程度上属于急剧变化字段。
对于剧烈变化维度,通常情况下,会一分为二进行处理,把其中不常变动的部分单独抽出来作为一个维度表,按照缓慢变化维方式进行处理;另外一部分也单独抽取出来,通常作为维度的属性进行处理。
只有缓慢变化的数据,才适用于缓慢变化维度处理的方式。如果是每天时刻都在变化的数据就不适合这种方案了。因为那样会产生太多的记录,导致维度表记录过多,影响效率。
处理缓慢变化维的三种方法:
- 直接覆盖原记录:最容易实现,但是没有保留历史数据,无法分析历史变化信息。通常简称为“TYPE 1”。
- 添加维度行:当有维度属性发生变化时,会生成一条新的维度记录,主键是新分配的代理键 (***Key) ,实现维度表与事实表的关联;通过自然键 (***ID) 可以和原维度记录保持关联。通常简称为“TYPE 2”。
- 添加属性列:为发生变化的属性新增一列,记录变化前的数据,本属性字段使用TYPE 1来直接覆盖。其优点是可以同时分析当前及前一次变化的属性值,缺点是只保留了最后一次变化的信息。通常简称为“TYPE 3”。
处理缓慢变化维的方法概括:
- Type1-SCD :不记录历史数据,新数据覆盖旧数据;
- Type2-SCD :增加一条记录,保留所有记录,使用单独的专用字段 (***Key) 保存区别;
- Type3-SCD :添加历史列,用不同的字段保存变化痕迹,适用于变化不超过两次的维度。
对于 Type2-SCD中,仅依赖代理键 (***Key) 进行关联是不够的。还需要通过添加行标识符(列),说明数据记录是否是当前最新的;或者添加数据记录有效的开始时间和结束时间(2列)进行标识,结束时间为 Null 的是最新记录。当然,也可以同时添加行标识符和起止时间,综合使用。
如下是某公司的CUSTOMER表,张三是会员,其TaxBracket状态由Low变成了High。添加的行标识符(列)为Row Indicator,起止时间列为 Start Date 和 End Date。在实际建模中,可以综合使用三种方式,也可以对一个维度表中的不同属性使用不同的方式,这些,都需要根据实际情况来决定,但目的都是一样的,就是能够方便地分析历史变化情况。
八、数据仓库建模体系之规范化数据仓库
数据仓库建模体系:指数据仓库从无到有的一整套建模方法。最常见的三种数据仓库建模体系分别为:规范化数据仓库,维度建模数据仓库,独立数据集市。
规范化数据仓库 (normalized data warehouse) :按照规范化设计原则,创建分析型数据库,基于这个数据库为各部门建立数据集市。
首先对ETL得到的数据进行ER建模、关系建模,得到一个规范化的数据库。基于这个中心数据库,为公司各部门建立基于维度建模的数据集市。各部门开发人员大都从这些数据集市中提数,通常来说不允许直接访问中心数据库。
总体架构如下图所示:九、数据仓库建模体系之维度建模数据仓库
维度建模数据仓库(dimensionally modeled data warehouse)是一种使用交错维度进行建模的数据仓库。
首先设计一组常用的度集合(conformed dimension),然后创建一个大星座模型表示所有分析型数据。如果这些维度满足不了某些数据分析需求,就在数据仓库之上继续构建新的数据集市。
总体架构如下图所示:十、数据仓库建模体系之独立数据集市
独立数据集市:公司的各个组织自己创建并完成ETL,自己维护自己的数据集市。
从技术上来讲这是一种很不值得推崇的方式,因为将使信息分散,影响了企业全局范围内数据分析的效率。此外,各组织之间的ETL架构相互独立无法复用,也浪费了企业的开发资源。然而出于某些公司制度及预算方面的考虑,有时也会使用到这种建模体系。
其总体架构如下图所示:十一、三种数据仓库建模体系对比
规范化数据仓库和维度建模数据仓库分别是Bill Inmon和Ralph Kimball提出的方法。关于哪种方法更好,哪种方法更优秀的争论已经由来已久。随着两种数据仓库应用越来越多,人们也逐渐了解到两种数据仓库的优劣之处,如下表所示:产生这些区别的根本之处,在于规范化数据仓库需要对企业全局进行规范化建模,这将导致较大的工作量。但这一步必须完成好,才能继续往上建设数据集市。因此也就导致规范化数据仓库,需要一定时间才能投入使用,敏捷性相对后者来说略差。但是规范化数据仓库一旦建立好了,则以后数据就更易于管理。而且由于开发人员不能直接使用其中心数据库,更加确保了数据质量。还有由于中心数据库是采用规范化设计的,冗余情况也会更少。
维度建模数据仓库除了敏捷性更强,而且适用于业务变化比较频繁的情况,对开发人员的要求也没有规范化数据仓库那么高。总之各有利弊,具体实施时需要仔细的权衡。
数据仓库建模是一个综合性技术,需要使用到ER建模、关系建模、维度建模等技术。当企业业务越来越复杂的时候,这部分工作更是需要专门团队与业务方共同合作来完成。因此一个优秀的数据仓库建模团队,既要有坚实的数据仓库建模技术,还要有对现实业务清晰、透彻的理解。