大数据-245 离线数仓 - 电商分析 缓慢变化维 与 拉链表 SCD Slowly Changing Dimensions

点一下关注吧!!!非常感谢!!持续更新!!!

Java篇开始了!

目前开始更新 MyBatis,一起深入浅出!

目前已经更新到了:

  • Hadoop(已更完)
  • HDFS(已更完)
  • MapReduce(已更完)
  • Hive(已更完)
  • Flume(已更完)
  • Sqoop(已更完)
  • Zookeeper(已更完)
  • HBase(已更完)
  • Redis (已更完)
  • Kafka(已更完)
  • Spark(已更完)
  • Flink(已更完)
  • ClickHouse(已更完)
  • Kudu(已更完)
  • Druid(已更完)
  • Kylin(已更完)
  • Elasticsearch(已更完)
  • DataX(已更完)
  • Tez(已更完)
  • 数据挖掘(已更完)
  • Prometheus(已更完)
  • Grafana(已更完)
  • 离线数仓(正在更新…)

章节内容

上节我们完成了如下的内容:

  • 电商核心交易 ODS层
  • 数据库结构 数据加载 DataX

在这里插入图片描述

缓慢变化维

缓慢变化维(SCD,Slowly Changing Dimensions),在现实世界中,维度的属性随着时间的流失发生缓慢的变化(缓慢是相对事实表而言,事实表数据变化的速度比维度表快)。
处理维度表的历史变化信息的问题称为处理缓慢变化维的问题,简称SCD问题,处理缓慢变化维的方法有以下几种常见方式:

  • 保留原值
  • 直接覆盖
  • 增加新属性列
  • 快照表
  • 拉链表

缓慢变化维(slowly varying dimension)是数据仓库领域中维度数据的一种特性,用于描述随着时间推移,某些属性会发生变化的维度。然而,这些变化通常是相对缓慢和不频繁的,因此称之为“缓慢变化维”(SCD, Slowly Changing Dimensions)。处理缓慢变化维是数据仓库设计中的一个重要部分,因为它直接影响数据的历史记录保存和版本控制。

缓慢变化维主要用于记录维度的属性随时间变化的情况,例如客户的地址、雇员的职位或产品的价格等。在实际应用中,为了满足业务需求,通常会根据变化记录需求的不同,采用不同的技术实现。

缓慢变化维的类型

缓慢变化维常被分为以下几种类型:

SCD 类型 0:不处理变化

  • 特点:属性变化时,不记录变化,只保留最新值。
  • 适用场景:维度的属性对历史分析无影响。
  • 优点:实现简单。
  • 缺点:无法保存历史信息。

SCD 类型 1:覆盖变化

  • 特点:属性变化时,直接覆盖旧值。
  • 适用场景:只需要保留最新的维度信息,历史数据无关紧要。
  • 优点:占用存储空间小,查询效率高。
  • 缺点:无法追溯历史信息,丢失数据变更记录。
  • 示例:客户地址发生变化,仅更新地址字段。

SCD 类型 2:保留历史记录

  • 特点:为每一次变化创建一条新记录,同时可以通过标识字段或时间戳区分当前数据和历史数据。

实现方式:

  • 增加版本号:新增一个版本号字段表示记录版本。

  • 增加有效时间区间:新增开始和结束时间字段表示记录的有效期。

  • 适用场景:需要保留所有历史信息,支持基于时间的回溯查询。

  • 优点:完整记录历史变化。

  • 缺点:数据量增加,查询复杂度可能提高。

  • 示例:客户地址发生变化,保留旧地址记录,新建一条记录保存新地址。

SCD 类型 3:有限的历史记录

  • 特点:为变化的属性设置额外的字段,仅保留有限的历史信息(如最近一次变化)。
  • 适用场景:只需要保存一部分历史信息,对存储空间要求较低。
  • 优点:减少数据量,存储需求低。
  • 缺点:历史记录有限,无法满足更复杂的回溯分析。
  • 示例:添加“旧地址”和“当前地址”两个字段。

SCD 类型 4:历史表

  • 特点:将历史记录存储在单独的历史表中,主表中只保留当前数据。
  • 适用场景:需要完整保存历史信息,同时希望主表保持精简。
  • 优点:主表数据简单,查询当前值效率高。
  • 缺点:需要额外的历史表,查询历史信息时复杂度增加。
  • 示例:主表存储客户的最新地址,历史表存储地址变更记录。

SCD 类型 6:混合型

  • 特点:结合类型 1、2 和 3,既保留最新值,又保留有限的历史信息,还可以保存完整的历史记录。
  • 适用场景:需要兼顾历史记录和当前值查询效率。
  • 优点:兼具多种类型的优点。
  • 缺点:实现较为复杂。
  • 示例:主表记录最新信息,同时增加版本号和时间戳以追溯历史。

保留原始值

维度属性值不做更改,保留原始值。
如商品上架售卖时间:一个商品上架售卖后由于其他原因下架,后来又再次上架,此种情况产生了多个商品上架售卖时间,如果业务重点关注的是商品首次商家售卖时间,则采用该方式。

直接覆盖

修改维度属性为最新值,直接覆盖,不保留历史信息。
如商品属于哪个品类:当商品品类发生变化时,直接重写为商品类。

增加新属性列

在维度表中新增加新的一列,原先属性列存放上一版本的属性值,当前属性列存放当前版本属性值,还可以增加一列记录变化的事件。
缺点:只能记录最后一次变化的信息。

在这里插入图片描述

快照表

每天保留一份全量数据,简单高效。
缺点是信息重复,浪费磁盘空间。
适用的维表不能太大,但是使用场景多,范围广,一般而言维表都不会很大。

拉链表

拉链表适用于:表的数据量大,而且数据会发生新增和变化,但是大部分是不变的(数据发生变化的百分比不大),且是缓慢变化的(如电商用户信息表中的某些用户属性不可能每天都变化),主要目的是为了节省空间。

适用的场景:

  • 表的数据量大
  • 表中部分字段会被更新
  • 表中记录变量的比例不高
  • 需要保留历史信息

维表拉链表应用案例

在这里插入图片描述

创建表

注意:这里的操作是在Hive中
对应的SQL内容如下:

CREATE DATABASE test;
-- 用户信息
DROP TABLE IF EXISTS test.userinfo;
CREATE TABLE test.userinfo(userid STRING COMMENT '用户编号',mobile STRING COMMENT '手机号码',regdate STRING COMMENT '注册日期')
COMMENT '用户信息'
PARTITIONED BY (dt string)
row format delimited fields terminated by ',';-- 拉链表(存放用户历史信息)
-- 拉链表不是分区表;多了两个字段start_date、end_date
DROP TABLE IF EXISTS test.userhis;
CREATE TABLE test.userhis(userid STRING COMMENT '用户编号',mobile STRING COMMENT '手机号码',regdate STRING COMMENT '注册日期',start_date STRING,end_date STRING)
COMMENT '用户信息拉链表'
row format delimited fields terminated by ',';

执行结果如下所示:
在这里插入图片描述

数据文件

vim /opt/wzk/userinfo.dat

写入的内容如下所示:

001,13551111111,2020-03-01,2020-06-20
002,13561111111,2020-04-01,2020-06-20
003,13571111111,2020-05-01,2020-06-20
004,13581111111,2020-06-01,2020-06-20
002,13562222222,2020-04-01,2020-06-21
004,13582222222,2020-06-01,2020-06-21
005,13552222222,2020-06-21,2020-06-21
004,13333333333,2020-06-01,2020-06-22
005,13533333333,2020-06-21,2020-06-22
006,13733333333,2020-06-22,2020-06-22
001,13554444444,2020-03-01,2020-06-23
003,13574444444,2020-05-01,2020-06-23
005,13555554444,2020-06-21,2020-06-23
007,18600744444,2020-06-23,2020-06-23
008,18600844444,2020-06-23,2020-06-23

写入的内容如下所示:
在这里插入图片描述

加载数据

-- 动态分区数据加载:分区的值由输入数据确定
-- 创建中间表(非分区表)
DROP TABLE IF EXISTS test.tmp1;
CREATE TABLE test.tmp1 AS
SELECT * FROM test.userinfo;-- 设置 tmp1 非分区表的字段分隔符为 ','(原始默认分隔符为 '\001')
ALTER TABLE test.tmp1 SET SERDEPROPERTIES('field.delim' = ',');-- 向中间表加载数据
LOAD DATA LOCAL INPATH '/opt/wzk/userinfo.dat' INTO TABLE test.tmp1;-- 启用非严格模式的动态分区
SET hive.exec.dynamic.partition.mode = nonstrict;-- 从中间表向分区表加载数据
INSERT INTO TABLE test.userinfo
PARTITION (dt)
SELECT * FROM test.tmp1;

执行结果如下图所示:
在这里插入图片描述

如果我们查询所有数据,可以看到对应的内容:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/487300.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【LeetCode: 160. 相交链表 + 链表】

🚀 算法题 🚀 🌲 算法刷题专栏 | 面试必备算法 | 面试高频算法 🍀 🌲 越难的东西,越要努力坚持,因为它具有很高的价值,算法就是这样✨ 🌲 作者简介:硕风和炜,…

从爱尔兰歌曲到莎士比亚:LSTM文本生成模型的优化之旅

上一篇:《再用RNN神经网络架构设计生成式语言模型》 序言:本文探讨了如何通过多种方法改进模型的输出,包括扩展数据集、调整模型架构、优化训练数据的窗口设置,以及采用字符级编码。这些方法旨在提高生成文本的准确性和合理性&am…

51c大模型~合集86

我自己的原文哦~ https://blog.51cto.com/whaosoft/12772867 #MILP-StuDio 拆解高复杂运筹问题的砖石,打破数据稀缺的瓶颈,中科大提出高质量运筹数据生成方法 论文作者刘昊洋是中国科学技术大学 2023 级硕士生,师从王杰教授,…

从零用java实现 小红书 springboot vue uniapp (1)

前言 偶尔会用小红书发一些笔记 闲来无事 想自己实现一个小红书 正好可以学习一下 帖子 留言 im 好友 推送 等功能 下面我们就从零 开发一个小红书 后台依旧用我们的会员系统的脚手架 演示 http://120.26.95.195:8889/ 客户端我们使用uniapp 我们首先对主页进行一个分解 顶部我…

pyside6学习专栏(一)常用控件的使用(非QML方式)

前段业余时间在用pythonpyqt5边学边作一些小程序,总算作到了一个相对复杂的基本VTK三维显示地形图并计算挖填方工程量,作完后,又发现pyqt又是要收费的,就又看了下对应的替代库pyside6,对用此库的一些基本技能分享到此专栏中&#…

活动|华院计算董事长宣晓华应邀出席2024科创大会并作圆桌嘉宾

2024科创大会在上海举行,由中央广播电视总台和上海市人民政府共同主办。本次大会以“创新驱动 新质未来”为主题,来自知名院校、科研机构的专家学者以及科技企业、金融机构的相关负责人共聚一堂,探讨人工智能、生物医药等产业应用前景&#x…

计算机网络-IPSec VPN工作原理

一、IPSec VPN工作原理 昨天我们大致了解了IPSec是什么,今天来学习下它的工作原理。 IPsec的基本工作流程如下: 通过IKE协商第一阶段协商出IKE SA。 使用IKE SA加密IKE协商第二阶段的报文,即IPsec SA。 使用IPsec SA加密数据。 IPsec基本工作…

leetcode 3001. 捕获黑皇后需要的最少移动次数 中等

现有一个下标从 1 开始的 8 x 8 棋盘,上面有 3 枚棋子。 给你 6 个整数 a 、b 、c 、d 、e 和 f ,其中: (a, b) 表示白色车的位置。(c, d) 表示白色象的位置。(e, f) 表示黑皇后的位置。 假定你只能移动白色棋子,返回捕获黑皇后…

linux 系统常用指令

1、查看内核版本 uname -r 2、列出占用空间最大的 10 个文件或目录 du -ah / | sort -rh | head -n 10 终于找到我虚拟机硬盘空间越来越少的原因了,类目......

【OpenDRIVE_Python】使用python脚本更新OpenDRIVE数据中路口Junction名称

示例代码说明: 遍历OpenDRIVE数据中每个路口JunctionID,读取需要变更的路口ID和路口名称的TXT文件,若JunctionID与TXT文件中的ID一致,则将TXT对应的点位名称更新到OpenDRIVE数据中Junction name字段。补充:需要保持TXT和OpenDRIVE数据文件编…

PySpark3.4.4_基于StreamingContext实现网络字节流统计分析

网络字节流与嵌套字节流的区别 概念解释 网络嵌套字节流: 在网络编程的情境下,网络嵌套字节流通常是指将字节流(字节序列)以一种分层或者包含的方式进行组织,用于在网络传输过程中更好地处理数据。例如,在一…

【JS】简单CSS简单JS写的上传进度条

纯JS写的&#xff0c;简单的上传进度条&#xff0c;当上传的文件较大&#xff0c;加一个动态画面&#xff0c;就不会让人觉得出错了或网络卡了 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"v…

47 基于单片机的书库环境监测

目录 一、主要功能 二、硬件资源 三、程序编程 四、实现现象 一、主要功能 基于51单片机&#xff0c;采用DHT11湿度传感器检测湿度&#xff0c;DS18B20温度传感器检测温度&#xff0c; 采用滑动变阻器连接数模转换器模拟二氧化碳和氧气浓度检测&#xff0c;各项数值通过lc…

解决:IDEA中@Autowired自动注入MyBatis Mapper报红警告的几种解决方法

文章目录 解决&#xff1a;IDEA中Autowired自动注入MyBatis Mapper报红警告的几种解决方法问题描述&#xff1a;解决办法&#xff1a;1.将Autowired注解改成Resource2.给Autowired(required false)设置属性3.给Mapper层加注解Mapper/Repository4.改变写法,用RequiredArgsConst…

Spring Boot中实现JPA多数据源配置指南

本文还有配套的精品资源&#xff0c;点击获取 简介&#xff1a;本文详细介绍了在Spring Boot项目中配置和使用JPA进行多数据源管理的步骤。从引入依赖开始&#xff0c;到配置数据源、创建DataSource bean、定义实体和Repository&#xff0c;最后到配置事务管理器和使用多数据…

Ubuntu 安装 web 服务器

安装 apach sudo apt install apache2 -y 查看 apach2 版本号 apache2 -v 检查是否启动服务器 sudo service apache2 status 检查可用的 ufw 防火墙应用程序配置 sudo ufw app list 关闭防火墙 sudo ufw disable 更改允许通过端口流量 sudo ufw allow Apache Full 开启…

go语言的成神之路-标准库篇-fmt标准库

目录 一、三种类型的输出 print&#xff1a; println&#xff1a; printf&#xff1a; 总结&#xff1a; 代码展示&#xff1a; 二、格式化占位符 %s&#xff1a;用于格式化字符串。 %d&#xff1a;用于格式化整数。 %f&#xff1a;用于格式化浮点数。 %v&#xff1…

【Linux操作系统】Linux常用一键脚本

Linux网络加速脚本 Linux网络加速脚本可以替换Linux内核和更改TCP拥塞算法的一键脚本&#xff0c;包括安装BBR内核、XANMOD官方内核&#xff0c;开启BBR加速等功能&#xff0c;总之非常强大。 不卸载内核脚本&#xff08;一般用这个&#xff09; wget -O tcpx.sh "http…

【全攻略】React Native与环信UIKit:Expo项目从创建到云打包完整指南

前言 在当今快速发展的移动应用领域&#xff0c;React Native 因其跨平台开发能力和高效的开发周期而受到开发者的青睐。而 Expo&#xff0c;作为一个基于 React Native 的框架&#xff0c;进一步简化了开发流程&#xff0c;提供了一套完整的工具链&#xff0c;使得开发者能够…

乌龟咬人,小意外中的大警示

近日&#xff0c;听闻有朋友被自家乌龟咬了手指&#xff0c;这看似滑稽的小意外&#xff0c;实则蕴含着不少值得我们深思的安全与责任问题。 乌龟&#xff0c;在大众的认知里&#xff0c;向来是行动迟缓、性情温和的宠物代表。它们慢悠悠地爬行&#xff0c;憨态可掬的模样常常…