虽然我的主业是实时计算和批量计算,并不是数仓,但是在日常工作中绝对少不了与数仓打交道。并且我也算是参与过离线数仓建设的,维度建模的基础还是不能忘。本文就作为一篇抄书笔记吧。
顾名思义,缓慢变化维度(slowly changing dimension, SCD)就是数据仓库维度表中,那些随时间变化比较不明显,但仍然会发生变化的维度。考虑以下两个情境:
处理缓慢变化维度是Kimball数仓体系中永恒的话题,因为数据仓库的本质,以及维度表在维度建模中的基础作用,我们几乎总是要跟踪维度的变更(change tracking),以保留历史,并提供准确的查询和分析结果。在《The Data Warehouse Toolkit, 3rd Edition》一书的第5章,Kimball提出了多种缓慢变化维度的类型和处理方法,其中前五种是原生的,后面的方法都是混合方法(hybrid techniques),因此下面来看看前五种,即Type 0~Type 4。
一种特殊的SCD类型,即不管维度属性的实际值如何变化,数仓中维度的值都会维持第一次的值。它主要适用于那些本身含义就是“原始值”(original)的维度,比如在用户维度表中,用户注册时使用的原始用户名(original_user_name)。如果它发生变化,那么变化后的值是无效的,会被抛弃。
最简单的SCD类型,即一旦维度属性的实际值发生变化,就会直接覆写到数仓中。数仓中的维度属性总是且仅仅保存着最近一次变更的值(most recent assignment)。书中的例子如下:
在上图中,Department Name维度发生了变化,并且新值直接覆盖了上一次的值。虽然它很容易实现,但是这样做会丢掉所有变更历史,并且在跨时域查询时,有可能会得到错误的结果。在实际 *** 作中,这种方式几乎总是一种不良设计。
最主要、最常用的SCD类型,在我们日常以Hive为基础的数仓建设过程中,体现为拉链表技术。
这种类型在维度表中添加两个辅助列:该行的有效日期(effective date)和过期日期(expiration date),分别指示该行从哪个时间点开始生效,以及在哪个时间点过后会变为无效。每当一个或多个维度发生更改时,就创建一个新的行,新行包含有修改后的维度值,而旧行包含有修改前的维度值,且旧行的过期日期也会同步修改。书中的例子如下:
在上图中,当前有效列(current列)的过期日期会被记录为9999-12-31。当Department Name维度变化时,旧有的Product Key为12345的行的过期日期被更新为修改日期,并且新建了一个Key为25984的行,包含新的数据。
需要注意的是,这里的Product Key是所谓代理键(surrogate key),即不表示具体业务含义,而只是代表表内数据行的唯一ID。在处理SCD时,代理键可以直接用来区分同一自然键(natural key)的数据的新旧版本。上图中的SKU就是自然键。
这种类型的SCD处理方式能够非常有效且精确地保留历史与反映变更,但缺点是会造成数据的膨胀,因为即使只有一个维度变化,也要创建新行。
Type 2虽然非常好,但是当要在同一个时间维度内把新值和旧值关联起来时,就没有那么方便了。比如在上一节的表中,如果查询2013年2月1日以后的记录,就只能查到Department Name为“Strategy”的记录,而“Education”就被屏蔽了。Type 3就是一种与Type 2互补的类型。在Type 3的处理方法中,不会添加新行,而会添加一个新的属性列,该属性列中保存有对应维度的上一次变化的值。书中的例子如下:
在上图中新增了一个名称为“Prior Department Name”的列,保存着上一次变更的值。这样也解决了Type 2的数据膨胀问题,但是就只能保存一次变更历史,称为“变更现实”(alternate realities)。
另外仍然要注意,如果维度表中的许多维度都会发生类似的变更,那么就要新增很多列,这显然不太靠谱。所以这种类型经常用来处理那种变化可预测的(predictable)、“牵一发而动全身”的少数SCD。
当然,也可以根据实际需求新增多个列来保存多次变更历史:
当维度的变化没有那么“缓慢”时,前面三种类型的处理就都显得力不从心了(特别是对于规模非常大的维度表,比如有百万甚至千万行)。这种维度一般就不再称为SCD,而称为“快速变化维度”(rapidly changing dimensions, RCD)。当RCD的规模比较小时,还能够采用Type 2或者Type 3来撑着,但规模很大时,就只能采用Type 4了。Type 4的方式是将那些快速变化的维度从原来的大维度表中拆分出来单独处理,是为微维度(mini-dimension)。
以书中的内容为例,如果顾客维度中有一部分人口统计学(demographic)维度是RCD,就将它们拆成单独的维度表:
其中,微维度表的维度最好是少量、分段的(banded)离散值,例如:
下表仍然来自《数据仓库工具箱》的原文。注意其中除了Type 0~4之外,还有三种混合方式,即Type 5~7。
最后善意提醒,《数据仓库工具箱(第三版)》这本书一定要读英文原版,千万不要读中译本。中译本错误百出,很多地方读起来都不通顺,令人窒息。
民那晚安~
1、首先你得搞清楚建设数仓的目的是什么
是偏向于整合各系统数据,为数据分析决策服务,还是偏向于快速的完成分析决策需求?
如果是前者,那么在数据仓库建模的时候一般会选择ER建模方法;
如果是后者,一般会选择维度建模方法。
ER建模:即实体关系建模,由数据仓库之父BIll Inmon提出,核心思想是从全企业的高度去设计三范式模型,用实体关系描述企业服务。主张的是自上而下的架构,将不同的OLTP数据集中到面向主题的数据仓库中。
维度建模:由Kimball提出,核心思想是从分析决策的需求出发构建模型。这种模型由事实表和维表组成,即星型模型和雪花模型。Kimball倡导自下而上的架构,可以针对独立部门建立数据集市,再递增的构建,汇总成数据仓库。
2、其次你得进行深入的业务调研和数据调研
业务调研:深入的业务调研能使你更加明确数仓建设的目的;同时也利于后续的建模设计,随着调研的开展,如何将实体业务抽象为数仓模型会更加明朗。
数据调研:各部门或各科室的数据现状了解,包括数据分类、数据存储方式、数据量、具体的数据内容等等。这对后续的主数据串联或者维度一致性处理等等都是必须的基础。
3、然后是数据仓库工具选型
传统型数据仓库:一般会选择第三方厂家的数据库和配套ETL工具。因为有第三方支持,相对有保障;但缺点也很明显,受约束以及成本较高。
NoSQL型数据仓库:一般是基于hadoop生态的数据仓库。hadoop生态已经非常强大,可以找到各种开源组件去支持数据仓库。缺点是需要招聘专门人士去摸索,并且相对会存在一些未知隐患。
4、最后是设计与实施
设计:包括数据架构中的数据层次划分以及具体的模型设计;也包括程序架构中的数据质量管理、元数据管理、调度管理等;
实施:规范化的项目管理实施,但同时也需记住一点,数据仓库不是一个项目,它是一个过程。
什么是维度退化?
将维度退化到事实表中,减少事实表和维度表的关联
在维度建模的数据仓库中,有一种维度叫Degenerate Dimension,中文一般翻译为“退化维度”。这种退化维度一般都是事务的编号,如订单编号、发票编号等。这类编号需要保存到事实表中,但是不需要对应的维度表,所以称为退化维度。
退化维度经常会和其他一些维度一起组合成事实表的主键。在Kimball提出的维度建模中,事实表应该保存最细粒度的数据。所以对于象销售单这样的事实表来说,需要销售单编号和产品来共同作为主键,而不能用销售日期、商场、产品等用来分析的维度共同作为主键。
退化维度在分析中可以用来做分组使用。它可以将同一个事务中销售的产品集中在一起。
因为事实表主键的成员一般都是维度值所组成,但退化维度虽然也属于主键值,但没有单独的维度表,所以叫退化维度。
以上就是关于聊聊数据仓库中的缓慢变化维度(SCD)全部的内容,包括:聊聊数据仓库中的缓慢变化维度(SCD)、请问数据仓库都用什么建立、维度退化等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)