缓慢变化维度

引言

在数据仓库的世界里,维度表就像一本“说明书”,记录了业务中重要实体的详细信息,比如客户是谁、产品是什么、时间是哪天。这些信息帮助我们理解和分析数据。不过,现实生活中,事情总在变化,比如客户搬家了、产品改名了,这些变化虽然不频繁,但确实会发生,我们称之为“缓慢变化维度”(Slowly Changing Dimensions, SCD)。如何处理这些变化,既要保持数据的准确性,又要保留历史的痕迹,是数据仓库设计中的一大挑战。

除了变化的属性,维度表里的信息还可能有层次关系,比如时间可以分成年、月、日,地址可以分成国家、省份、城市。怎么组织这些层次关系,也是个关键问题。这篇文章将用简单易懂的语言,结合《数据仓库工具箱》第三版第二章的内容,详细讲解什么是缓慢变化维度,怎么处理它的属性变化,以及如何处理维度层次关系,最后通过一个零售案例把这些概念讲透彻。


1. 什么是缓慢变化维度(SCD)?

1.1 维度和维度属性

先来说说维度表是什么。想象你在超市买东西,结账时收银员会记录你的购买信息:买了什么、什么时候买的、你是哪位顾客。这些信息里,“买了什么”是产品维度,“什么时候”是时间维度,“你是哪位”是客户维度。每个维度表就像一个档案夹,里面装满了描述性的信息,比如客户维度表可能有你的姓名、地址、电话号码等,这些就是“维度属性”。

1.2 缓慢变化维度的定义

但生活不是静止的,你的地址可能会因为搬家而变,电话号码可能会因为换号而改。这种变化不常发生,但一旦发生,就需要数据仓库有所反应。这种“慢慢变动的维度属性”,就被称为缓慢变化维度(SCD)。SCD的核心问题是:当这些属性变了,我们是直接覆盖掉旧信息,还是保留历史记录?不同的处理方式,会影响到数据仓库的功能和使用。


2. 缓慢变化维度的类型及处理方法

处理缓慢变化维度时,有好几种方法,每种方法适合不同的场景。下面我们一一来看。

2.1 Type 0:不变

什么是Type 0?
有些属性天生就不会变,比如你的出生日期,一旦录入,就永远是那个值。这种情况我们叫Type 0。

怎么处理?
很简单,不用管它,录进去就完事了,之后不会改动。

适合哪里?
像出生日期、性别(在某些业务场景下)这种固定不变的属性,用Type 0就够了。

2.2 Type 1:覆盖

什么是Type 1?
如果一个属性变了,我们不在乎它的历史记录,直接用新值把旧值盖掉,这就是Type 1。比如你的电话号码变了,我们只关心你现在的号码,之前的号码不重要。

怎么处理?
在维度表里找到对应的记录,把旧值更新成新值。比如客户A的电话从“123-4567”变成“987-6543”,我们直接把表里的电话号码改成“987-6543”,旧号码就没了。

优缺点:

  • 优点:简单粗暴,表里数据量不会增加。
  • 缺点:历史记录丢了,想查以前的号码查不到。

适合哪里?
适合那些历史不重要、只关心当前状态的属性,比如电话号码、邮箱地址。

小案例:
假设有个客户表:

客户ID姓名电话号码
A张三123-4567

张三换了号码变成“987-6543”,用Type 1处理后,表变成:

客户ID姓名电话号码
A张三987-6543
旧号码“123-4567”没了。

2.3 Type 2:添加新行

什么是Type 2?
如果我们既想要最新的信息,又想保留历史记录,就用Type 2。每次属性变了,不改原来的记录,而是加一行新的,把变化后的信息记下来。

怎么处理?

  • 给维度表加一个“代理键”(surrogate key),用来区分不同的记录行。
  • 属性变了,就插一行新记录,写上新值和新的代理键。
  • 为了知道哪行是当前的、哪行是历史的,可以加“生效日期”(effective date)和“失效日期”(expired date),或者加个“当前标志”(current flag)。

举个例子:
还是客户表,假设张三搬家了,地址从“旧地址”变成“新地址”。原始表是:

代理键客户ID姓名地址
1A张三旧地址

用Type 2处理后,地址变了,表变成:

代理键客户ID姓名地址生效日期失效日期当前标志
1A张三旧地址2020-01-012023-01-01N
2A张三新地址2023-01-01NULLY
  • 旧记录的失效日期定为2023-01-01,当前标志改成“N”(不是当前)。
  • 新记录的生效日期是2023-01-01,失效日期暂时为空,当前标志是“Y”(是当前)。

优缺点:

  • 优点:历史记录全保留,想查张三以前住哪都能查到。
  • 缺点:表里的行数会变多,可能拖慢查询速度。

适合哪里?
适合需要跟踪历史变化的属性,比如地址、职位、婚姻状况。

2.4 Type 3:添加新列

什么是Type 3?
如果历史记录不用全保留,只想记最近的几次变化,可以用Type 3。属性变了,不加新行,而是在表里加一列,把旧值挪过去。

怎么处理?

  • 在维度表里为这个属性多加一列,比如“前一次值”。
  • 属性变了,把当前值移到“前一次值”列,新值写到当前列。

举个例子:
客户表有婚姻状况,张三从“单身”变成“已婚”。原始表:

客户ID姓名婚姻状况
A张三单身

改成Type 3结构后:

客户ID姓名当前婚姻状况前一次婚姻状况
A张三已婚单身

优缺点:

  • 优点:能保留有限历史,表行数不会增加。
  • 缺点:只能记固定次数的变化(看你加了几列),多了就记不下了。

适合哪里?
适合只关心最近几次变化的属性,比如会员等级、婚姻状况。

2.5 混合方法

现实中,一个维度表里可能有好几种属性,有的用Type 1,有的用Type 2,有的用Type 3。比如客户表里,电话号码用Type 1覆盖,地址用Type 2加新行,会员等级用Type 3加新列。这样可以根据业务需求灵活搭配。


3. 维度层次关系

维度表里的属性有时候不是平铺的,而是有层次关系。比如时间维度有年、季度、月、日,地理维度有国家、省份、城市。怎么组织这些层次,有两种常见方法:星型模式和雪花模式。

3.1 星型模式(Star Schema)

什么是星型模式?
把所有层次的属性都塞到一个表里,不管它们有没有关系。比如时间维度表里,直接放年、季度、月、日。

举个例子:
时间维度表:

时间ID季度
12023Q11月1日

优缺点:

  • 优点:查起来快,因为不用连很多表。
  • 缺点:数据可能会重复,比如“2023”在每行都出现。

适合哪里?
大部分数据仓库都爱用星型模式,尤其是需要快速查询的时候。

3.2 雪花模式(Snowflake Schema)

什么是雪花模式?
把层次拆开,分别存到不同的表里,表之间用键连起来,像雪花一样。比如地理维度分成国家表、省份表、城市表。

举个例子:
国家表:

国家ID国家名称
1中国

省份表:

省份ID省份名称国家ID
1广东1

城市表:

城市ID城市名称省份ID
1广州1

优缺点:

  • 优点:数据不重复,规范化强。
  • 缺点:查的时候要连好几个表,速度慢。

适合哪里?
适合特别在意数据冗余,或者层次关系很复杂的场景。

3.3 选哪个模式?

星型模式因为查得快,用得最多,尤其是在分析型数据库里。但如果数据量巨大,或者业务要求严格规范化,雪花模式可能更好。具体选哪个,得看你的需求。


4. 具体案例分析:零售业务的数据仓库

为了把这些概念讲明白,我们来看一个零售公司的例子,设计它的客户维度和产品维度。

4.1 业务背景

假设我们为一家卖日用品的公司建数据仓库,公司想分析销售情况、客户行为。数据仓库里有客户维度、产品维度和销售事实表。

4.2 维度设计

客户维度:

  • 属性:客户ID、姓名、地址、电话号码、会员等级
  • 变化情况:
    • 姓名:基本不变(Type 0)
    • 地址:搬家会变,需保留历史(Type 2)
    • 电话号码:换号会变,历史不重要(Type 1)
    • 会员等级:消费多会升级,保留前一次等级(Type 3)

产品维度:

  • 属性:产品ID、产品名称、类别、子类别、供应商
  • 变化情况:
    • 产品名称:品牌重塑会变,需保留历史(Type 2)
    • 类别和子类别:业务调整会变,需保留历史(Type 2)
    • 供应商:合同变了会换,需保留历史(Type 2)

4.3 处理缓慢变化维度

客户维度表:

代理键客户ID姓名地址电话号码当前会员等级前会员等级生效日期失效日期当前标志
1A张三旧地址123-4567银卡2020-01-012023-01-01N
2A张三新地址987-6543金卡银卡2023-01-01NULLY
  • 姓名:Type 0,不变。
  • 地址:Type 2,搬家后加新行。
  • 电话号码:Type 1,直接覆盖。
  • 会员等级:Type 3,加列记前一次等级。

产品维度表:

代理键产品ID产品名称类别子类别供应商生效日期失效日期当前标志
1P1旧牙膏日化牙膏厂商A2020-01-012023-01-01N
2P1新牙膏日化牙膏厂商B2023-01-01NULLY
  • 产品名称、类别、子类别、供应商:全用Type 2,变化时加新行。

4.4 处理维度层次关系

客户维度:
地址有国家、省份、城市层次。为查得快,用星型模式,全放一个表:

代理键客户ID姓名国家省份城市电话号码当前会员等级前会员等级生效日期失效日期当前标志
1A张三中国广东广州123-4567银卡2020-01-012023-01-01N

产品维度:
类别和子类别有层次,也用星型模式:

代理键产品ID产品名称类别子类别供应商生效日期失效日期当前标志
1P1旧牙膏日化牙膏厂商A2020-01-012023-01-01N

4.5 事实表设计

销售事实表用代理键连维度表,支持Type 2的历史记录:

销售ID客户代理键产品代理键销售日期销售额
1112022-06-01100
2222023-06-01150

这样就能查到张三搬家前后的购买记录,和牙膏改名后的销售情况。


5. 总结

缓慢变化维度是数据仓库里处理变化的“法宝”。Type 1简单覆盖,适合历史不重要的场景;Type 2加新行,适合需要历史追踪;Type 3加新列,适合记有限变化。实际中可以混用,灵活应对。

维度层次关系上,星型模式查得快,用得广;雪花模式更规范,但查得慢。零售案例里,我们用混合SCD和星型模式,既保留了历史,又保证了效率。希望这篇文章让你对SCD和维度层次关系有个清晰的认识!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

野老杂谈

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值