当前位置: 首页 > news >正文

如何在数仓中处理缓慢变化维度(SCD)

在数据仓库中,处理缓慢变化维度(SCD,Slowly Changing Dimension)是一个非常常见且重要的问题。为了保证数据的完整性和准确性,我们通常会采取不同的策略来处理维度表中的数据变化。SCD的核心解决方案是通过不同类型的历史记录策略来管理数据变化,以确保系统能够追踪和保留数据变化的历史。

如何在数仓中处理缓慢变化维度

    • 什么是缓慢变化维度(SCD)?
    • 解决缓慢变化维度的三种主要策略
      • SCD 类型 1:直接覆盖
      • SCD 类型 2:新增记录
      • SCD 类型 3:新增字段
    • 示例案例
    • 结论

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

缓慢变化维度是指在数据仓库中,维度表中的某些数据属性会随着时间缓慢变化,但这种变化并不频繁。比如客户的地址、联系信息等。这些信息通常不会频繁更改,但在数仓设计中,我们仍然需要保存这些变化的历史,以便进行报表分析或审计。
image.png

解决缓慢变化维度的三种主要策略

在数仓中,我们主要使用三种策略来处理缓慢变化维度:
image.png

SCD 类型 1:直接覆盖

这种方法最为简单,直接用新的数据覆盖旧的数据。这种策略适用于对历史数据的追踪不重要的情况,只需保存最新状态。例如,当客户的邮编发生变化时,旧的邮编将被新邮编直接覆盖。

示例代码:

-- 更新客户的邮编信息,直接覆盖旧的记录
UPDATE CustomerDimension
SET PostalCode = '84102'
WHERE CustomerKey = 7;

image.png

SCD 类型 2:新增记录

第二种策略是当维度属性发生变化时,插入一个新记录,同时保留旧的历史记录。这种方法可以保留每一次数据变化的记录,并且可以在查询时指定某个时间段的数据。例如,如果客户的地址发生了变化,我们将创建一个新的行来保存这个变化,同时将老的记录结束日期设为当前日期。

示例代码:

-- 更新客户地址信息,保留历史记录
UPDATE CustomerDimension
SET EndDate = GETDATE()  -- 结束旧记录
WHERE CustomerKey = 7 AND EndDate IS NULL;-- 插入新记录
INSERT INTO CustomerDimension (CustomerKey, PostalCode, StartDate, EndDate)
VALUES (7, '84102', GETDATE(), NULL);

image.png

SCD 类型 3:新增字段

第三种策略是通过增加一个或多个字段来记录数据的历史变化,而不是新增记录。通常用新字段记录旧数据的值,同时保留当前字段记录新数据。这样我们可以在一行记录中同时看到变化前后的值。

示例代码:

-- 更新客户信息,新增字段保存旧邮编
ALTER TABLE CustomerDimension
ADD PreviousPostalCode VARCHAR(10);-- 更新记录,保留旧邮编
UPDATE CustomerDimension
SET PreviousPostalCode = PostalCode, PostalCode = '84102'
WHERE CustomerKey = 7;

image.png

示例案例

例如,我们有一个客户 Matt Housley(CustomerKey = 7),其初始邮编为 84101。随着时间的推移,他的邮编更改为 84102。根据不同的策略,我们可以选择直接覆盖旧记录、插入新记录,或通过增加字段保留历史数据。

SCD 类型 1:
直接覆盖旧数据,保存最新邮编为 84102。

SCD 类型 2:
在记录历史时,我们会将旧邮编的记录结束日期设置为更改日期,并插入一个新记录,保存 Matt Housley 的新邮编及开始日期。

SCD 类型 3:
通过新增字段保存 Matt Housley 旧邮编为 84101,当前邮编字段则保存最新的 84102。

结论

不同的缓慢变化维度处理策略各有优劣。选择哪种策略取决于业务场景对历史数据的追踪需求。如果仅关心当前状态,直接覆盖(SCD 类型 1)是最简单的;如果需要完整的历史记录,新增记录(SCD 类型 2)是最佳选择;而对于少量变化且只需追踪前后变化的情况,新增字段(SCD 类型 3)是一种折中方案。
image.png

通过合理选择缓慢变化维度策略,数据仓库可以在保证性能的同时,有效地保存历史数据,满足数据分析的需求。


http://www.mrgr.cn/news/49236.html

相关文章:

  • 3.计算机网络_端口号
  • 浏览器中使用模型
  • 网络编程(19)——C++使用asio协程实现并发服务器
  • 轻松掌握TCP与UDP核心机制
  • C++初始化内置类型变量的方式(至少6种)
  • 在 Ubuntu 中使用 Gitee(码云)创建仓库、上传代码和下载
  • 进程 vs 线程:你需要知道的关键区别
  • Linux Ubuntu dbus CAPI ---- #include<dbus.h>出现“无法打开源文件dbus/xxx.h“的问题
  • 弘景光电IPO:多赛道布局展现稳健经营与可持续增长
  • github.com port 443 问题
  • Android Studio开发Kotlin项目中遇到的问题解决集
  • 软件供应链十年:探索开源的增长、风险和未来
  • 【风力发电】基于模糊逻辑控制的风电系统MPPT
  • vue开发环境、生产环境配置与nginx配置后端代理转发跨域
  • SRAM和DRAM在性能指标上具体有哪些差异
  • 基于STM32的智能电能表设计
  • C++ STL 六大组件
  • STM32 | MQTT+esp8266(第十四天)
  • 尚硅谷rabbitmq2024介绍和工作模式 第4-9节 答疑
  • 【云原生】Helm资源清单管理工具