阅读OLAP中缓慢变化的维度。(SCD)处理办法

04-20 23:38

本文介绍了缓慢变化的维度,也称为缓慢变化。SCD。这是不同的方法来处理不断变化的数据。但是它有更多的细微差别,还有很多方法可供选择。假如您对此感兴趣,并且使用了大量的可视化,请坚持下去!


本文将介绍以下内容:


关键定义


SCD是什么?


为什么SCD非常重要


类型的SCD


结论


关键定义


请务必在开始之前了解一些关键概念:


数据仓库


对数据存储进行分析和改进。它的结构通常由事实表和维度表组成。


事实表


这种表格包含了事件发生的关键维度。


例如,在社交媒体网站/应用程序中,一个名字叫做“post"事实表可以用来捕捉与任何帖子活动相关的数据及其所有关键层面。


这包括user_id时间戳、device_id等:


维度表


“我们在事实表上”post“这里有很多特征。如果我们想要这个表中的某个特征(例如user_id)更详细的资料,该怎么办?


它就是维度表的立足之地。维度表是一种包含事实数据表中更多信息的表,例如事实数据。里的user_id列。


这个表格将包含相关用户的辅助数据,例如他们的名字、姓氏、出生日期、他们建立帐户的时间戳、他们的手机号码等。


这一表结构的优点是,事实表永远不会因为太多而膨胀,但是如果需要更详细的数据,则不需要连接!


注:上述结构捕获了所谓的结构星形架构。对于雪花结构,我们也有子维度表。


OLAP


正如其名称所示,在线分析处理是一种用于大规模分析的数据方法。


假如你熟悉上面的定义,你可能已经注意到它们都是特定于OLAP的概念。因为SCD只适用于OLAP。非OLTP。为什么呢?



在有机发光二极管(在线事务管理)中,我们优先考虑1。无数据冗余和2。容纳最新版本的数据。没有灵活的空间,所以我们只覆盖数据。


所以,本文将以OLAP为核心。


使用有机发光二极管,您可以选择冗余和历史数据。当新数据传输时,这为我们提供了更多的战略选择,我们将在下面的例子中看到这一点。


SCD是什么?


从这个角度来看,你现在想知道什么是维度表。


请记住,在文章开头,我们所说的SCD在高层次上有:对数据进行不同的处理方法。


如今我们有了前后的文字,更具体地说,变化缓慢的层次。(SCD)是专门处理维度表数据在不断变化的数据的不同方法


假定你有以下内容user_id维度表:


注:为了简单考虑,我们已经从前面的user_id示例中删除了一些字段。


例如,主键(行唯一值)是user_id。接着,我们的数据管道将处理包含以下数据的新数据:


有些新数据和现有数据有相同的主键键,我们注意到(user_id)。尼古拉斯·凯奇(NicholasCage)和杰克·佩拉尔塔(JakePeralta)所有手机号码都是新的。


这是数据的不断变化。


你可能会有一些最初的问题:


为什麽会“慢”地发生?为何不是事实表?为何尼古拉斯凯奇在这里?


咱们一个个解决这个问题。


为什么它“缓慢”发生?


修饰词“慢”可能来自于对这些层次更新不太频繁的期望。但是这并不是一个严格的规则。


为何不是事实表?


“键定义“以上部分,事实数据表是由事件驱动的。一旦发生事情,除非时间过程可能,否则是不可逆的!因此,这里的变化不适合。


比如有人发布微博故事的时候,现在已经发生了,无法更改。如果用户删除了微博故事,那么这是一个独立的事件,也就是事实表中的另一条线。


为什么尼古拉斯凯奇在这里?


他是个伟大的演员!在《无法承受的重量》中,我喜欢他的表演。


为什么SCD非常重要


如今你可能会想:为什么改变数据很重要?


让我们参考前面的例子。你有一个包含一些当前数据的数据库,并且有一组新的数据进入。正如我们在NicholasCage的手机号码中看到的,其中一些与您现有的数据相冲突:


原始记录和新记录之间存在矛盾。我们应该优先选择哪一个?是只保留一个记录,还是同时保留两个记录?


这个定义SCD很重要。你最终会选择一种策略来处理这种情况,根据团队中的业务需求和/或者最佳的数据工程实践。


注:为了简单考虑,我们已经从例子中删除了user_id列。但它是帮助数据管道确定哪些层次正在发生变化的关键列。


类型的SCD


有哪些不同的策略,我们如何决定哪些策略?


有许多策略-7种类型。但是,由于脱离实际,有些策略从来没有使用过,所以我们只关注本文中的几个关键策略。


本论文将提供一些帮助理解的例子,并对何时使用哪一种策略提供一些指导。


SCD-0:无更新


表明:更新的数据已经进入,但是我们忽略了它,没有做任何改变。


推理:我们有一些维度是我们预期永远不会改变的,因此这一新数据很可能是重复的,或只是有缺陷的数据。


示例:假设顾客第一次正确输入,我们绝不希望他们的出生日期发生变化。这是不合理的,除非你伪造出生证明。


所以,如果提出任何改变,例如:


具有新生日期值的行


我们选择忽略这些变化,保持数据不变。


SCD-0如何处理更新?


思考:


由于很少有字段永远不会改变,我发现这种SCD的适用性有限。


即便对于像date_of_birth这类字段,客户也可能在第一次出错,所以我们需要我们的数据管道来处理这些边缘情况。


SCD-1:覆盖


解释:进入更新的数据行,然后我们完全覆盖当前的行程。


推理:我们的维度只关心当前的状态,所以我们删除了任何过时的行,然后使用更新的行。


例:尼古拉斯·凯奇(NicholasCage)和杰克·佩拉尔塔(JakePeralta)他们的数据再次更新。这次,他们更改了手机号码。


有新手机号码值的行行


由于我们只关心他们的手机号码,所以我们不再需要联系他们,user_id他们的旧联系电话在表中使用。


SCD-如何处理更新?


思考:


这一SCD策略可以证明它是有用的,尤其是当你试图防止表格膨胀时。


然而,丢失数据总是有风险的,因为扭转这个决定并恢复数据并不总是那么容易。未来需求总会发生变化,所以我会谨慎使用。


SCD-2:全部保留(基于行)


解释:会有更新的数据线,所以我们会把新的线添加到表格中。我们不会删除任何数据。为了区分两者,我们最多有三个新列:


开始日期列-本条目的数据管道处理时间


结束日期列-这个内容什么时候结束(如果还没有结束,你可以选择31-12-99999,以显示它永远不会在我们有生之年结束)


版本号列-1表示第一个版本,然后在每次更新时增加1。


所以,维度表的结构将按照下列策略进行改变:


表结构含有SCD-2。


推理:虽然我们有更新的维度,但是我们不希望在这个过程中丢失历史数据。


示例:2024年2月2日,NicholasCage和JakePeralta(01年2024月2024日)<>日本)更新了他们的地址。


有新邮编值的行


虽然我们希望更新表格,但是我们希望保留旧的数据,防止我们进行一些历史分析。


例如,我们可能想观察客户多年来的位置分布。2020年把尼古拉斯·凯奇放在他的新地址是没有意义的,因为他当时没有住在那里。因此,我们保留了新旧数据和新旧数据版本start_dateend_date列,以帮助区分两者。


SCD-如何处理更新?


思考:


SCD-二是我首选的维度数据变更方法之一。


你用易于阅读和解释的方法来维护所有的数据。


即便你最后只使用最新版本或者第一个版本,也可以选择版本end_date轻松实现。


这个策略也是可以扩展的,因为你可以很容易地处理未来同一个字段的变化:为每一个新版本添加新行。


SCD-3:全部保留(基于列)


解释:进入更新的数据行,然后我们使用新列进行跟踪。我们将其分为两列——“当前”列和“最后一列”,而不仅仅是为了一个层次:


表结构含有SCD-3。


类似于SCD-2,我们不会删除任何数据。


推理:虽然我们有更新的维度,但是我们不希望在这个过程中丢失历史数据。


例:尼古拉斯·凯奇(NicholasCage)和杰克·佩拉尔塔(JakePeralta)更新他们的地址:



有新邮编值的行


我们所做的是:


将“current_post_code所有值都拷贝到“previous_post_code”


随后更换“current_post_code“所有有新值的值:


SCD-如何处理更新?


思考:


假如我们期望在顾客的生活中只有一次改变,那么SCD-3是合适的。但是,这个很难保证。


一些文章讨论了SCD-3的组合,这些组合包括更多的列表来显示更多的版本。例如,使用“previous_3_post_code“列捕捉第三个最新值。


在我看来,SCD-3不能随着数据的变化而很好地扩展,在这一点上,选择SCD-2策略更有意义。


SCD-4:全部保留(历史记录表)


解释:在一个维度表中,我们没有保存所有变更的数据,而是创建了一个额外的“迷你级别”历史记录表。


通过这种方式,当更新的数据行传输时,我们将做两件事:


覆盖当前表(类似于SCD-1)


跟踪之前的数值(类似于SCD-2)更新历史表


这一“历史表”包含了什么?


主键列-允许您回到当前表格(简单考虑一下,下图省略)


其它列在维度表中-由于你正在捕捉这些列的历史价值(例如post_code)


开始日期列-本条目的数据管道处理时间


结束日期列(可选))-这个内容什么时候结束(如果还没有结束,你可以选择31-12-99999,以表明它永远不会在我们的生命周期中结束)


版本号列(可选)-1表示第一个版本,然后在每次更新时增加1。


历史表


推理:虽然我们有更新的维度,但是我们不想在这个过程中丢失历史数据。同时,我们也希望保持所有当前数据的快照。


例:尼古拉斯·凯奇(NicholasCage)和杰克·佩拉尔塔(JakePeralta)他们的地址再次更新:


行行具有新的帖子代码值


解释以上,我们对当前和历史表格进行了相应的更新:


SCD-如何处理更新(当前表)


SCD-如何处理更新(历史表)


思考:


SCD-四是我最喜欢的另一种方法,当前版本与SCD-2有许多相似之处。


你现在可能会说:那么,我该如何在两者之间做出决定呢?


在SCD-2和SCD-4之间进行选择时,应考虑两个关键问题:


层次更新频率如何?


在整篇文章中,我们的例子只介绍了一个用户更新。我们明确表示,SCD-2比SCD-3更适合超过两次更新。


但是,如果客户的邮政代码更新了多达100次怎么办?甚至更多?如果这种情况发生在数百万客户身上,这在微博这样的大平台上是可能的?


使用SCD-2,我们可以捕捉更改,但是user_id维度表将变得愚蠢,特别是在你一开始只需要当前的数据。


这就是SCD-4的亮点:它为用户提供了灵活性。如果你想实施历史分析,它真的需要连接历史表,所以请记住这一点。


下游分析是否一直依赖于历史数据或当前数据?


假如下游数据用户经常使用历史邮编数据,那么SCD-4就意味着他们必须在当前表格和历史表格之间进行连接。


SCD-二是绕过这一步,减少查询执行时间和集群资源。


但是,如果专门针对当前数据的查询频率相当高,那么SCD-2就意味着客户每次都要对其进行过滤。


SCD-4表示用户只需使用当前表格,绕过此步骤,减少查询执行时间和集群资源。


结论


简而言之,SCD是一种不同的方法来处理维度表中的数据变更。每种方法在不同的方案中都非常有用,最终取决于你的要求。因此,请花时间了解您的数据,然后相应地应用正确的SCD策略。


本文来自微信微信官方账号“数据驱动智能”(ID:Data作者:晓晓,36氪经授权发布,_0101)。


本文仅代表作者观点,版权归原创者所有,如需转载请在文中注明来源及作者名字。

免责声明:本文系转载编辑文章,仅作分享之用。如分享内容、图片侵犯到您的版权或非授权发布,请及时与我们联系进行审核处理或删除,您可以发送材料至邮箱:service@tojoy.com