聊聊数据仓库中的缓慢变化维度(SCD)

虽然我的主业是实时计算和批量计算,并不是数仓,但是在日常工作中绝对少不了与数仓打交道。并且我也算是参与过离线数仓建设的,维度建模的基础还是不能忘。本文就作为一篇抄书笔记吧。

SCD简介

顾名思义,缓慢变化维度(slowly changing dimension, SCD)就是数据仓库维度表中,那些随时间变化比较不明显,但仍然会发生变化的维度。考虑以下两个情境:

  • 在员工维度表中,某员工原来在北京分公司工作,后来调往上海分公司,那么“工作地点”就是一个缓慢变化维度;
  • 在采购维度表中,办公电脑原来从戴尔供应商处进货,后来换成了联想,那么“供应商”就是一个缓慢变化维度。

处理缓慢变化维度是Kimball数仓体系中永恒的话题,因为数据仓库的本质,以及维度表在维度建模中的基础作用,我们几乎总是要跟踪维度的变更(change tracking),以保留历史,并提供准确的查询和分析结果。在《The Data Warehouse Toolkit, 3rd Edition》一书的第5章,Kimball提出了多种缓慢变化维度的类型和处理方法,其中前五种是原生的,后面的方法都是混合方法(hybrid techniques),因此下面来看看前五种,即Type 0~Type 4。

SCD Type 0: Retain Original(维持原状)

一种特殊的SCD类型,即不管维度属性的实际值如何变化,数仓中维度的值都会维持第一次的值。它主要适用于那些本身含义就是“原始值”(original)的维度,比如在用户维度表中,用户注册时使用的原始用户名(original_user_name)。如果它发生变化,那么变化后的值是无效的,会被抛弃。

SCD Type 1: Overwrite(覆盖)

最简单的SCD类型,即一旦维度属性的实际值发生变化,就会直接覆写到数仓中。数仓中的维度属性总是且仅仅保存着最近一次变更的值(most recent assignment)。书中的例子如下:

在上图中,Department Name维度发生了变化,并且新值直接覆盖了上一次的值。虽然它很容易实现,但是这样做会丢掉所有变更历史,并且在跨时域查询时,有可能会得到错误的结果。在实际操作中,这种方式几乎总是一种不良设计。

SCD Type 2: Add New Row(添加新行)

最主要、最常用的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处理方式能够非常有效且精确地保留历史与反映变更,但缺点是会造成数据的膨胀,因为即使只有一个维度变化,也要创建新行。

SCD Type 3: Add New Attribute(添加新属性列)

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 Type 4: Add Mini-Dimension(添加微维度)

当维度的变化没有那么“缓慢”时,前面三种类型的处理就都显得力不从心了(特别是对于规模非常大的维度表,比如有百万甚至千万行)。这种维度一般就不再称为SCD,而称为“快速变化维度”(rapidly changing dimensions, RCD)。当RCD的规模比较小时,还能够采用Type 2或者Type 3来撑着,但规模很大时,就只能采用Type 4了。Type 4的方式是将那些快速变化的维度从原来的大维度表中拆分出来单独处理,是为微维度(mini-dimension)。

以书中的内容为例,如果顾客维度中有一部分人口统计学(demographic)维度是RCD,就将它们拆成单独的维度表:

其中,微维度表的维度最好是少量、分段的(banded)离散值,例如:

SCD处理方式的对比

下表仍然来自《数据仓库工具箱》的原文。注意其中除了Type 0~4之外,还有三种混合方式,即Type 5~7。

最后善意提醒,《数据仓库工具箱(第三版)》这本书一定要读英文原版,千万不要读中译本。中译本错误百出,很多地方读起来都不通顺,令人窒息。

民那晚安~

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,732评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,496评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,264评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,807评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,806评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,675评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,029评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,683评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,704评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,666评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,773评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,413评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,016评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,204评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,083评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,503评论 2 343

推荐阅读更多精彩内容