【一篇文章带你搞懂--拉链表!!!拉链表的原理是什么!】

news2024/11/18 6:44:09

前言:
💞💞大家好,我是书生♡,今天主要和大家分享一下拉链表的原理以及使用,希望对大家有所帮助。 大家可以关注我下方的链接更多优质文章供学习参考。
💞💞代码是你的画笔,创新是你的画布,用它们绘出属于你的精彩世界,不断挑战,无限可能!

个人主页⭐: 书生♡
gitee主页🙋‍♂:闲客
专栏主页💞:大数据开发
博客领域💥:大数据开发,java编程,前端,算法,Python
写作风格💞:超前知识点,干货,思路讲解,通俗易懂
支持博主💖:关注⭐,点赞、收藏⭐、留言💬

目录

  • 1. 引言
  • 2. 什么是拉链表
  • 3. 拉链表的基本原理
    • 3.1 基本原理描述
    • 3.2 拉链表原理详解
      • 3.2.1 全量导入
      • 3.2.2 增量导入
  • 4 . 拉链表的应用场景
  • 5. 拉链表的优化策略
  • 6. 实现方式

1. 引言

  在大数据和数据库领域,拉链表(Slowly Changing Dimension, SCD)是一种常用的数据处理技术,用于处理维度表中缓慢变化的数据。拉链表通过记录数据的历史状态,实现了对数据变化的高效追踪和查询。本文将详细介绍拉链表的基本原理、应用场景以及优化策略。
在这里插入图片描述

2. 什么是拉链表

  拉链表是针对数据仓库设计中表存储数据的方式而定义的一种数据模型,主要用于记录数据变更历史。

  • 定义:

拉链表是一种用于记录数据变更历史的表结构,它记录了事物从开始到当前状态的所有变化信息。
通过记录数据的创建时间、更新时间等字段,可以方便地查询数据变更历史。

  • 结构特点:

拉链表中的每个记录通常包含字段如创建时间(create_time)、更新时间(update_time)、数据本身(如order_id、user_id等)以及可能的操作者信息等。
为了更好地跟踪数据变化,有些拉链表设计会包含起始时间(start_time)和结束时间(end_time)字段,用于标识数据的有效期。

案例:
1 . 假设有一个订单表,每天都会有新的订单产生或已有订单的状态发生变化。
2. 通过监听订单表的变化(如使用Canal等工具),可以捕获每天的订单变更数据。
3. 将这些变更数据合并到拉链表中,形成订单的历史记录。
4. 通过查询拉链表,可以方便地获取某个订单从创建到当前的所有状态变化信息。

3. 拉链表的基本原理

3.1 基本原理描述

  拉链表的核心思想是将数据表中的每一行记录都视为一个版本,通过添加额外的字段(如有效开始日期和有效结束日期)来标识该版本数据的有效期。当数据发生变化时,不是直接修改原数据,而是插入一条新的记录,并将原记录的有效结束日期设置为当前时间戳,新记录的有效开始日期也设置为当前时间戳
这样,通过查询有效开始日期和有效结束日期在指定范围内的记录,就可以获取到指定时间点的数据状态。

拉链表操作步骤一般分为两部分:

  • 全量导入(仅限于第一次)
  • 增量导入(对于被修改以及新增的数据)

3.2 拉链表原理详解

原理详解假设第一次导入,之前数仓中没有人任何数据的,因此我们的原理详解包括 全量导入 和 增量导入。

注意:

我们一般导入都是导入前一天的数据

原始输入表:
在这里插入图片描述
我们要的结果表:大家对比一下有什么不一样?

  1. 我们新增了两条数据,一个是修改的一个是我们新增的数据
  2. 我们原本被修改数据的失效日期变为了失效当天的日期

在这里插入图片描述

3.2.1 全量导入

  假设我们现在有这么一个mysql数据。我们第一次导入需要全部导入到我们的数仓的ods层。

原始表创建语句:

-- 在mysql中创建库和表
DROP DATABASE IF EXISTS db_1_mysql;

CREATE DATABASE db_1_mysql
    DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

USE db_1_mysql;

CREATE TABLE db_1_mysql.tb_user
(
    id          int,
    name        varchar(32),
    address     varchar(32),
    create_date date,
    update_date date
);

INSERT INTO tb_user VALUE (1003, '张三', '北京', '2022-05-30', '2022-05-30');
INSERT INTO tb_user VALUE (1004, '李四', '上海', '2022-05-01', '2022-05-15');
INSERT INTO tb_user VALUE (1005, '王五', '广州', '2022-04-01', '2022-04-26');
INSERT INTO tb_user VALUE (1006, '赵六', '深圳', '2022-06-01', '2022-06-01');

SELECT *
FROM tb_user;

数仓 ods层和dwd层建表

-- 在hive中创建库和表
drop database if exists db_ods cascade;
create database db_ods;

use db_ods;

drop table tb_user_ods;

-- truncate table db_ods.tb_user_ods;


create table db_ods.tb_user_ods
(
    id          int,
    name        string,
    address     string,
    create_date string,
    update_date string
)
    partitioned by (dt string)
    row format delimited fields terminated by '\t';

desc formatted tb_user_ods;

drop database if exists db_dwd cascade;
create database db_dwd;

create table db_dwd.tb_user_dwd
(
    id          int,
    name        string,
    address     string,
    create_date string,
    update_date string,
    end_date    string
)
    partitioned by (start_date string)
    row format delimited fields terminated by '\t'
;

create table db_dwd.tb_user_dwd_temp
(
    id          int,
    name        string,
    address     string,
    create_date string,
    update_date string,
    end_date    string
)
    partitioned by (start_date string)
    row format delimited fields terminated by '\t'
;

注意:

我们将dwd层的表成为拉链表,也就是说我们要将数据通过吗,mysql导入到ods中在插入到dwd的拉链表中。

我们的全量导入是不包括今天的数据的,因此我们导入的时候要筛选一下(我们假设今天是2022-06-01)因此我们要选出今天之前的数据导入
我们导入到ods层是通过Datax导入的,具体的导入方法,大家可以看我的关于Datax使用的博客。

筛选的条件

SELECT *
FROM tb_user
WHERE coalesce(update_date, create_date) < '2022-06-01';

原始输入表:
在这里插入图片描述

将数据从mysql通过Data X导入到ods层中(分区为处理的前一天)
WHERE coalesce(update_date, create_date) < '2022-06-01'

导入到ods层的数据
在这里插入图片描述
我们第一次的全量导入,导入到ods层之后就可以全部导入到我们的dwd层的拉链表了。

注意:
我们在插入的时候要指定我们的开始时间和失效时间,因为是第一次导入就说我们现在的数据都是有效的,因此有效日期就是我们的分区日期,至于结束日期,我们的数据都没有结束因此我们设置为‘9999-99-99’

-- 全量数据插入拉链表
insert overwrite table db_dwd.tb_user_dwd partition (start_date)
select id,
       name,
       address,
       create_date,
       update_date,
       '9999-99-99' as end_date,
       dt           as start_date
from db_ods.tb_user_ods;

在这里插入图片描述

3.2.2 增量导入

前提:假设今天时间是6月2号,处理6月1号的数据(被修改和新增的数据)

假设我们在6月1号。将id为1004的数据进行修改,城市被修改了,那么修改日期也要变,并且新增了一条数据(我表中标为蓝色的部分
在这里插入图片描述

这里是MySQL的数据修改,我们还要将数据导入到ods中。
并且,我们导入的数据只是我们在6月1号修改的,所以需要筛选一下。

WHERE coalesce(update_date, create_date) = '2022-06-01'

我们通过查看 分区为‘2022-06-01’的数据
在这里插入图片描述

我们怎么将原本数据进行修改呢?hiv SQL是不支持行级修改的。
此时我们就要通过引入一个拉链表的临时表,进行修改数据后的存储。

我们将我们原本的拉链表与我们新增的数据进行左关联

select *
from db_dwd.tb_user_dwd a
         left join (select *
                    from db_ods.tb_user_ods
                    where dt = '2022-06-01') b on a.id = b.id;

在这里插入图片描述

我们关联之后的表就是上面这个图这个样子。

我们怎么修改数据,由图可以看见我们关联上的数据是不为空的,因此我们直接,将失效日期变为修改日期-1
关联的条件是什么?
如果(b.id is null or a.失效日期!=‘9999-12-31’, a.失效日期,上一天日期-1(dt-1))

if(b.id is null or (b.id is not null and a.end_date != '9999-99-99'), a.end_date,
          date_add('2022-06-01', -1)) as end_date,

我们将这个数据插入到我们的拉链表的临时表中

-- 临时表插入数据,拉链表关联筛选出来的
insert overwrite table db_dwd.tb_user_dwd_temp partition (start_date)
select a.id,
       a.name,
       a.address,
       a.create_date,
       a.update_date,
       if(b.id is null or (b.id is not null and a.end_date != '9999-99-99'), a.end_date,
          date_add('2022-06-01', -1)) as end_date,
       a.start_date
from db_dwd.tb_user_dwd a
         left join (select *
                    from db_ods.tb_user_ods
                    where dt = '2022-06-01') b on a.id = b.id;

在这里插入图片描述
此时我们的临时表存储的数据就是我们原始数据被修改之后数据了。

我们只需要将新增的数据也插入到临时表中就可以了。

--- 将新增的直接插入进来
insert into db_dwd.tb_user_dwd_temp partition (start_date)
select id,
       name,
       address,
       create_date,
       update_date,
       '9999-99-99' as end_date,
       dt           as start_date
from tb_user_ods
where dt = '2022-06-01'
;

在这里插入图片描述

最后我们只需要**将临时表的数据覆盖到拉链表**中我们的操作就完成了。

这个地方有两个方法:

  1. 通过将临时表的数据覆盖到拉链表
  2. 先将拉链表数据清空,在insert into插入就可以了,不需要覆盖
    insert overwrite table db_dwd.tb_user_dwd partition (start_date)
select id,
       name,
       address,
       create_date,
       update_date,
       end_date,
       start_date
from db_dwd.tb_user_dwd_temp;

在这里插入图片描述

注意:
我们在将数据插入到拉链表中后,要将临时表情况,因为下一次增量操作我们还要使用临时表

4 . 拉链表的应用场景

  • 数据仓库:在数据仓库中,维度表的数据经常会发生变化,如客户信息的更新、产品属性的修改等。使用拉链表可以方便地追踪这些变化,并生成历史报表。
  • 数据分析:在数据分析中,经常需要比较不同时间点的数据状态,以发现数据的变化趋势。拉链表可以方便地提供这种比较功能。
  • 实时数据监控:在实时数据监控系统中,需要实时反映数据的最新状态。通过定期更新拉链表,可以实时获取数据的最新状态,并进行相应的处理。

5. 拉链表的优化策略

  • 索引优化:为了提高查询效率,可以为拉链表的关键字段(如主键、有效开始日期和有效结束日期)建立索引。这样可以加快查询速度,提高系统的响应能力。
  • 数据压缩:由于拉链表会记录数据的多个版本,因此可能会占用较多的存储空间。为了节省存储空间,可以采用数据压缩技术对拉链表进行压缩。常用的压缩算法包括gzip、snappy等。
  • 分区存储:对于数据量较大的拉链表,可以采用分区存储的方式将数据分散到多个物理存储设备上。这样可以提高数据的读写性能,并降低单点故障的风险。
  • 定期清理:随着时间的推移,拉链表中的历史数据可能会变得不再重要。为了节省存储空间和提高查询效率,可以定期清理这些不再重要的历史数据。清理策略可以根据业务需求和数据保留期限来制定。

6. 实现方式

拉链表的实现通常涉及到数据的增量抽取、转换和加载(ETL)过程。
在数据仓库中,可以通过ETL工具对操作型数据库按照时间字段增量抽取数据,形成每天的增量数据,并合并到拉链表中。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

怎样查看vsphere client 的登录日志

- 问题摘要&#xff1a; 怎样查看vsphere client 的登录日志 - 解决方案/工作方法 1.登录vsphere client > vc > Monitor > Tasks and Events > Events, 查看日志 2. 查看VC 的websso.log日志 /var/log/vmware/sso/websso.log 3. 可以把websso.log文件拿到本地电…

Java进阶学习|Day4.Java多线程,线程池

文章目录 了解多线程CPU进程(Process)线程多线程开发多线程优点 实现方式继承Thread类实现Runnable接口实现Callable接口 线程状态转换线程状态线程调度调整线程优先级线程睡眠线程等待线程让步线程加入线程唤醒 线程同步线程同步方式多线程间通信 线程池了解线程池定义常见接口…

操作系统入门 -- 磁盘管理

操作系统入门 – 磁盘管理 1.磁盘结构 1.1 磁盘 表盘有一些磁性物质组成的盘片&#xff0c;可以利用这些磁性物质存储二进制数据 1.2 磁道 一个盘片上被划分为很多圆环&#xff0c;这些圆环就是磁道 1.3 扇区 上述的圆环又被分为很多部分&#xff0c;这些部分称为扇区。…

Toshiba东芝TB6612FNG电机驱动IC:释放性能与多功能性

在嵌入式系统和机器人技术领域&#xff0c;电机控制是一个关键方面&#xff0c;对项目的性能和可靠性有着显著影响。东芝的TB6612FNG电机驱动IC作为一个稳健且多功能的解决方案&#xff0c;在驱动双直流电机方面脱颖而出&#xff0c;提供了高性能、可靠性和易用性。本文将深入探…

计算机视觉 | 基于 PointNet 网络的飞机零件 3D 点云分割

目录 一、简要介绍二、环境设置2.1 实验配置2.2 必要库安装 三、数据集解析3.1 数据集加载3.2 数据文件夹结构3.3 点云数据可视化3.4 数据获取与预处理3.5 数据集定义 四、模型组网4.1 PointNet 介绍4.2 Paddle模型组网4.3 模型概要 五、模型训练六、模型预测七、总结 Hi&#…

MySQL之高可用性和应用层优化(一)

高可用性 故障转移和故障恢复 在应用中处理故障转移 有时候让应用来处理故障转移会更加简单或者更加灵活。例如&#xff0c;如果应用遇到一个错误&#xff0c;这个错误外部观察者正常情况下是无法察觉的&#xff0c;例如关于数据库损坏的错误日志信息&#xff0c;那么应用可…

硬件开发笔记(二十三):贴片电阻的类别、封装介绍,AD21导入贴片电阻原理图封装库3D模型

若该文为原创文章&#xff0c;转载请注明原文出处 本文章博客地址&#xff1a;https://hpzwl.blog.csdn.net/article/details/140110514 长沙红胖子Qt&#xff08;长沙创微智科&#xff09;博文大全&#xff1a;开发技术集合&#xff08;包含Qt实用技术、树莓派、三维、OpenCV…

一文全概括,建议收藏,那些你不可错过的IC设计书籍合集(可下载)

集成电路设计工程师的角色不仅是推动技术创新的中坚力量&#xff0c;更是实现产品从概念到现实的关键桥梁。随着对高性能、低功耗芯片的需求不断增长&#xff0c;IC设计工程师的专业技能和知识深度成为了衡量其职业价值的重要标准。无论是在数字逻辑设计、功能验证、可测试性设…

【Python机器学习】模型评估与改进——分组交叉验证

分组交叉验证是非常常见的一种交叉验证策略&#xff0c;它适用于数据中的分组高度相关时。比如我们想构建一个从人脸图片中识别情感的系统&#xff0c;并且收集了100个人的照片的数据集&#xff0c;其中每个人都进行了多次拍摄&#xff0c;分别展示了不同的情感。我们的目标是构…

新开发的应用做ASO服务有必要吗

如果您开发了一款应用并希望在竞争激烈的应用市场中获得更多的曝光和下载&#xff0c;那么ASO服务通常是很有必要的。以下是几个关于ASO服务必要性的主要观点&#xff1a; 1、提高应用的可见性 ASO的最主要目标就是提高应用的排名&#xff0c;使应用在众多应用中脱颖而出让用…

Coze搭建《测测你的本命宠物》

前言 本文讲解如何从零开始&#xff0c;使用扣子平台去搭建《测测你的本命宠物》 《测测你的本命宠物》&#xff1a;测测你的本命宠物 - 扣子 AI Bot (coze.cn) 欢迎大家去体验一下&#xff01;&#xff01;&#xff01; 正文 接下来我们开始讲解制作这个bot的流程吧&#…

Perl语言入门指南

一、绪论 1.1 Perl语言概述 1.2 Perl的特色 1.3 Perl面临的问题 1.4 Perl语言的应用领域 二、Perl语言基础 2.1 Perl语言的历史发展 2.2 Perl语言的基本语法 2.3 Perl语言的数据类型 三、Perl语言控制结构 3.1 条件语句 3.2 循环结构 3.3 函数和子程序 四、Perl语…

Gavin大咖亲自授课:将大语言模型与直接偏好优化对齐

Gavin大咖亲自授课&#xff1a;将大语言模型与直接偏好优化对齐 Align LLMs with Direct Preference Optimization 直接偏好优化&#xff08; Direct Preference Optimization&#xff09;这绝对是天才性的算法。你会看到数学的巨大力量和巨大价值&#xff0c;你一定会很兴奋和…

基于X86+FPGA+AI的芯片缺陷检测方案

应用场景 随着半导体技术的发展&#xff0c;对芯片的良率要求越来越高。然而集成电路芯片制造工艺复杂&#xff0c;其制造过程中往往产生很多缺陷&#xff0c;因此缺陷检测是集成电路制造过程中的必备工艺。 客户需求 小体积&#xff0c;低功耗 2 x USB,1 x LAN Core-i平台无…

WhatsApp:连接世界的即时通讯巨头

在数字化浪潮席卷全球的今天&#xff0c;即时通讯工具已成为人们日常生活中不可或缺的一部分。其中&#xff0c;WhatsApp凭借其卓越的功能、出色的用户体验和广泛的用户基础&#xff0c;在全球通讯领域崭露头角&#xff0c;成为连接世界的即时通讯巨头。今天将带您深入了解What…

.NET项目使用Devexpress控件DiagramControl和QuikGraph类库实现最短路径算法可视化

说明&#xff1a; 使用控件&#xff1a;DevExpress V24.1.3&#xff08;链接&#xff1a;https://pan.baidu.com/s/1FosVrpyE7q_XvwhZK7ad3w?pwdtw64提取码&#xff1a;tw64&#xff09;项目地址&#xff1a;https://github.com/VinciYan/Diagram_NET.git可以帮助学习和理解数…

【区块链+基础设施】珠三角征信链 | FISCO BCOS应用案例

“珠三角征信链”是中国人民银行广州分行、中国人民银行深圳市中心支行按照中国人民银行总行工作部署&#xff0c;积 极贯彻珠三角一体化发展、粤港澳大湾区建设等国家战略而建设的跨区域征信一体化数据中心枢纽&#xff0c;以 FISCO BCOS 为底链构建应用平台&#xff0c;并由微…

跨越界限,巴比达带你访问远程桌面【内网穿透技术分享】

在远程工作的时代&#xff0c;远程桌面访问成为了许多职场人士的日常。Windows系统默认的远程桌面服务监听在3389端口&#xff0c;但对于内网环境下的机器来说&#xff0c;直接从外部访问这个端口常常面临重重阻碍。不过&#xff0c;有了巴比达内网穿透&#xff0c;这一切都将不…

填志愿选专业,文科男生如何选专业?

又到了高考分数出炉&#xff0c;无数学子收获喜悦的季节&#xff0c;在分数刚出炉时&#xff0c;很多学生表现的异常兴奋&#xff0c;于他们而言&#xff0c;这么多年的努力终于有了收获&#xff0c;自己该考虑选择什么专业了。而毫不夸张的说&#xff0c;很多人在拿到专业目录…

[leetcode]minimum-absolute-difference-in-bst 二叉搜索树的最小绝对差

. - 力扣&#xff08;LeetCode&#xff09; /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode() : val(0), left(nullptr), right(nullptr) {}* TreeNode(int x) : val(x), left(null…