Hive 拉链表的两种实现方式

news2024/12/29 9:05:10

目录

1.什么是拉链表

2.拉链表的产生背景

2.1数据同步

2.1.1全量同步

2.1.2增量同步

2.2增量同步和拉链表

3.拉链表的实现方式

3.1数据准备

3.2思路1

3.3思路2


1.什么是拉链表

我们首先要知道,拉链表是一个逻辑上的概念。

拉链表记录的是增量数据,它通过不断的同步增量数据来构成,不断进行数据清洗。

拉链表有数据的开始日期和结束日期,记录着数据的生命周期。(有开始有结束,也因此被称为拉链)

总而言之,拉链表通过增量表进行不断的更新


2.拉链表的产生背景

Hive在实际工作中主要用于构建离线数据仓库。而说到拉链表的产生背景,我们就不得不提到离线数仓中的数据同步问题

2.1数据同步

我们知道,数据同步分为增量同步全量同步

2.1.1全量同步

全量同步,就是每天都将业务数据库中的全部数据同步一份到数据仓库,这是保证两侧数据同步的最简单的方式。

2.1.2增量同步

增量同步,就是每天只将业务数据中的新增及变化数据同步到数据仓库。采用每日增量同步的表,通常需要在首日先进行一次全量同步。

2.2增量同步和拉链表

全量同步逻辑简单也容易使用,但在有些情况下效率较低:例如某张表数据量较大,但是每天数据的变化比例很低,若对其采用每日全量同步,则会重复同步和存储大量相同的数据。

此时增量同步应运而生:构建拉链表,插入增量数据,通过时间标记发生变化的数据的每种状态的时间周期


3.拉链表的实现方式

3.1数据准备

1.构建模拟数据:

拉链表数据:

vim /export/data/zipper.txt

001  186xxxx1234  laoda     0     sh   2021-01-01    9999-12-31

002 186xxxx1235  laoer      1      bj    2021-01-01    9999-12-31

003 186xxxx1236  laosan   0     sz    2021-01-01    9999-12-31

004 186xxxx1237  laosi       1      gz   2021-01-01    9999-12-31

005 186xxxx1238  laowu    0     sh   2021-01-01    9999-12-31

006 186xxxx1239  laoliu     1      bj    2021-01-01    9999-12-31

007 186xxxx1240  laoqi      0     sz    2021-01-01    9999-12-31

008 186xxxx1241  laoba     1      gz   2021-01-01    9999-12-31

009 186xxxx1242  laojiu     0     sh   2021-01-01    9999-12-31

010  186xxxx1243  laoshi     1      bj    2021-01-01    9999-12-31

增量表数据:

vim /export/data/update.txt 

008 186xxxx1241  laoba     1      sh   2021-01-02   9999-12-31

011  186xxxx1244  laoshi     1      jx     2021-01-02   9999-12-31

012  186xxxx1245  laoshi     0     zj    2021-01-02   9999-12-31 

-- 拉链表
create temporary table dw_zipper
(
    userid    string,
    phone     string,
    nick      string,
    gender    int,
    addr      string,
    starttime string,
    endtime   string
) row format delimited fields terminated by '\t';

load data local inpath '/export/data/zipper.txt' into table dw_zipper;



-- 增量表
create temporary table ods_zipper_update
(
    userid    string,
    phone     string,
    nick      string,
    gender    int,
    addr      string,
    starttime string,
    endtime   string
) row format delimited fields terminated by '\t';

load data local inpath '/export/data/update.txt' into table ods_zipper_update;

3.2思路1

通过左连接 left join

先上代码:

-- step1 创建临时表,插入查询结果
drop table if exists tmp_zipper2;
create table if not exists tmp_zipper2(
                            userid string,
                            phone string,
                            nick string,
                            gender int,
                            addr string,
                            starttime string
)partitioned by (endtime string)
    row format delimited fields terminated by '\t';

-- step2 合并拉链表和增量表并插入到临时表
-- left join 则是为了修改旧拉链表中(update数据)的endtime 
-- union all 是为了合并增量表和修改了endtime的旧拉链表 
-- 从而合成临时表,再把临时表插入旧拉链表中作为新的拉链表

insert overwrite table tmp_zipper

        select userid, phone, nick, gender, addr, starttime, endtime 
        from ods_zipper_update

    union all   --union all是拼接两个表,join是交集之类的?
    
    --查询原来拉链表的所有数据,并将这次需要更新的数据的endTime更改为更新值的startTime
        select a.userid, a.phone, a.nick, a.gender, a.addr, a.starttime, if(b.userid is null or a.endtime < '9999-12-31', a.endtime , date_sub(b.starttime,1)) as endtime 
        from dw_zipper a
            left join
        ods_zipper_update b on a.userid = b.userid ;
 

 通过 拉链表左连接增量表 修改拉链表endtime字段:若拉链表和增量表中存在相同的userid,则修改拉链表中的endtime字段为增量表中starttime字段的前一天

然后再合并(修改了endtime字段的拉链表)和 (增量表)

 

3.3思路2

使用窗口函数 lag() 和 row_number()

先上代码:

drop table if exists tmp_zipper3;
create table if not exists tmp_zipper3(
                            userid string,
                            phone string,
                            nick string,
                            gender int,
                            addr string,
                            starttime string
)partitioned by (endtime string)
    row format delimited fields terminated by '\t';


set hive.exec.dynamic.partition.mode = nonstrict;
with tmp1 as ( select * from ods_zipper_update union all select * from dw_zipper ),
     tmp2 as ( select *, lag(starttime,1,0) over (partition by userid order by starttime desc )as lasttime, row_number() over (partition by userid order by starttime desc ) as rk from tmp1),
     tmp3 as ( select userid, phone, nick, gender, addr, starttime, `if`(rk=2,date_sub(lasttime,1),tmp2.endtime) as endtime from tmp2)
insert overwrite table tmp_zipper3 partition(endtime) select userid, phone, nick, gender, addr, starttime, endtime from tmp3 ;

使用窗口函数 lag() 和 row_number():

首先合并拉链表和增量表;

使用row_number() 函数对合并表中对userid进行分区排序,

使用lag()函数获取userid分区中的上一行数据的endtime字段

使row_number()字段为2的数据修改endtime字段为lag()函数获取的上一行数据的endtime字段-1

 有不理解的地方对上面各子查询进行select查看结果即可。

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

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

相关文章

(链表专题) 328. 奇偶链表 ——【Leetcode每日一题】

328. 奇偶链表 给定单链表的头节点 head &#xff0c;将所有索引为奇数的节点和索引为偶数的节点分别组合在一起&#xff0c;然后返回重新排序的列表。 第一个 节点的索引被认为是 奇数 &#xff0c; 第二个 节点的索引为 偶数 &#xff0c;以此类推。 请注意&#xff0c;偶…

在 RISC-V Linux 内核中添加模块

在 RISC-V Linux 内核中添加模块 flyfish 本例以添加helloworld字符设备为例 一 源码配置 1 源码 源码文件helloworld.c拷贝到 drivers/char 目录中 源码主要是输出Hello world init 2 Kconfig 打开drivers/char 目录下的Kconfig文件 在endmenu之前加上 config HELLO…

统信UOS专业版系统安装教程 - 全盘安装UOS系统

全文导读&#xff1a;本文介绍了UOS系统安装&#xff08;全盘安装&#xff09;的过程&#xff0c;如果没有特殊要求&#xff0c;推荐安装UOS系统都采用全盘安装。 准备环境 制作好统信UOS专业版启动U盘 一台CPU频率≥2GHz、内存≥4GB、硬盘≥64GB的电脑 安装步骤 一、制作…

MySQL复合查询

文章目录一、多表查询二、自连接三、子查询1.单行子查询2.多行子查询3.多列子查询4.在 from 子句中使用子查询5.合并查询一、多表查询 在实际开发中&#xff0c;数据往往来自不同的表&#xff0c;所以需要多表查询。 对多张表做笛卡尔积&#xff0c;实际上就是多张表的所有记…

js 特殊对象 - 数组

1.概述 数组也是对象的一种&#xff0c;数组是一种用于表达有顺序关系的值的集合的语言结构&#xff0c;也就是同类数据元素的有序集合。 数组的存储性能比普通对象要好&#xff0c;在开发中我们经常使用数组来存储一些数据。但是在JavaScript中是支持数组可以是不同的元素&…

使用CH9102F平替ESP32系列下载电路中的CP2102

乐鑫官方ESP32开发板的外围电路主要包含&#xff1a; USB-UART电路自动下载电路RC延迟电路重启按键下载按键电源降压芯片LDO下面简单介绍一下这些电路的功能。 ESP32的USB-UART电路部分&#xff0c;核心芯片CP2102。其作用是将USB接口传入的D、D-信号转换为串口信号RX、TX以及…

如何与 MACOM 建立 EDI 连接?

项目背景 MACOM提供高性能射频&#xff0c;微波和毫米波器件&#xff0c;其产品广泛应用于通信&#xff0c;航空航天&#xff0c;国防和工业市场。近年来MACOM在中国地区的业务一直高速增长。 为了提高其供应链的效率和准确性&#xff0c;MACOM使用EDI&#xff08;电子数据交…

数据挖掘(4.1)--分类和预测

目录 前言 一、分类和预测 分类 预测 二、关于分类和预测的问题 准备分类和预测的数据 评价分类和预测方法 混淆矩阵 评估准确率 参考资料 前言 分类&#xff1a;离散型、分类新数据 预测&#xff1a;连续型、预测未知值 描述属性&#xff1a;连续、离散 类别属性&am…

扬尘天气在家如何防护措施 家里空气中的沙尘怎么处理

扬尘天气在家如何防护措施 家里空气中的沙尘怎么处理 大风起兮尘飞扬 风越强来&#xff0c;天越黄…… 随沙尘而来的还有呼呼呼的大风 刚刚过了一周 “阳光正好&#xff0c;微风不燥”的日子 还没好好感受春花绽放的温柔 沙尘天气就又杀回塔大了 除了吃土 “防护指南…

展心展力 metaapp:基于 DeepRec 的稀疏模型训练实践

作者 metaapp-推荐广告研发部&#xff1a;臧若舟&#xff0c;朱越&#xff0c;司灵通 1 背景 推荐场景大模型在国内的使用很早&#xff0c;早在 10 年前甚至更早&#xff0c;百度已经用上了自研的大规模分布式的 parameter server 系统结合上游自研的 worker 来实现 TB 级别…

【LeetCode】剑指 Offer(27)

目录 题目&#xff1a;剑指 Offer 53 - I. 在排序数组中查找数字 I - 力扣&#xff08;Leetcode&#xff09; 题目的接口&#xff1a; 解题思路&#xff1a; 代码&#xff1a; 过啦&#xff01;&#xff01;&#xff01; 写在最后&#xff1a; 题目&#xff1a;剑指 Offe…

【机器学习 P19】【实战 P1】 MINST 手写数字识别

MINST 手写数字识别引入数据模型训练模型创建程序模型编译程序模型训练程序模型预测程序完整代码引入数据 MINST数据集是一个经典的手写数字识别数据集&#xff0c;由Yann LeCun等人创建。它包含了来自真实手写数字图片的70000个灰度图像&#xff0c;这些图像是由250个不同的人…

三行Python代码,让数据处理速度提高2到6倍

本文可以教你仅使用 3 行代码&#xff0c;大大加快数据预处理的速度。 Python 是机器学习领域内的首选编程语言&#xff0c;它易于使用&#xff0c;也有很多出色的库来帮助你更快处理数据。但当我们面临大量数据时&#xff0c;一些问题就会显现…… 在默认情况下&#xff0c;…

OpenShift 4 - 使用 virtctl 远程访问 OpenShift Virtualization 的虚拟机

《OpenShift / RHEL / DevSecOps 汇总目录》 说明&#xff1a;本文已经在支持 OpenShift 4.12 的 OpenShift 环境中验证 在《OpenShift 4 - 用 OpenShift Virtualization 运行容器化虚拟机 &#xff08;视频&#xff09;》一文中使用了 OpenShift 控制台直接访问运行在 OpenSh…

SQL中去除重复数据的几种方法,我一次性都告诉你​

使用SQL对数据进行提取和分析时&#xff0c;我们经常会遇到数据重复的场景&#xff0c;需要我们对数据进行去重后分析。以某电商公司的销售报表为例&#xff0c;常见的去重方法我们用到distinct 或者group by 语句&#xff0c; 今天介绍一种新的方法&#xff0c;利用窗口函数对…

MIT 6.S965 韩松课程 05

Lecture 05: Quantization (Part 1) 文章目录Lecture 05: Quantization (Part 1)动机数字的数据类型整数定点数浮点数量化基于 K-Means 的量化 [[Han et al., ICLR 2016]](https://arxiv.org/pdf/1510.00149v5.pdf)线性量化 [[Jacob et al. CVPR 2018]](https://arxiv.org/pdf/…

Makefile项目管理-----在Linux下编译c/c++程序

这里写目录标题起因makefile项目管理一、用途&#xff1a;二、 makefile的基础规则1.多文件联合编译2. makefile检测原理3. ALL来指定终极目标三、 makefile的两个函数和clean四、 makefile中的三个自动变量五、模式规则六、 静态模式规则七、 扩展1. 扩展1 伪目标2. 扩展2 可添…

在 Python 中检查字符串是否为 ASCII

使用 str.isascii() 方法检查字符串是否为 ASCII&#xff0c;例如 if my_str.isascii():。 如果字符串为空或字符串中的所有字符都是 ASCII&#xff0c;则 str.isascii() 方法返回 True&#xff0c;否则返回 False。 my_str www.jiyik.comif my_str.isascii():# &#x1f447…

网络安全工程师做什么?

​ 网络安全很复杂。数字化转型、远程工作和不断变化的威胁形势需要不同的工具和不同的技能组合。 系统必须到位以保护端点、身份和无边界网络边界。负责处理这种复杂安全基础设施的工作角色是网络安全工程师。 简而言之&#xff0c;网络安全工程师是负责设计和实施组织安全系…

基于TF-IDF+KMeans聚类算法构建中文文本分类模型(附案例实战)

&#x1f935;‍♂️ 个人主页&#xff1a;艾派森的个人主页 ✍&#x1f3fb;作者简介&#xff1a;Python学习者 &#x1f40b; 希望大家多多支持&#xff0c;我们一起进步&#xff01;&#x1f604; 如果文章对你有帮助的话&#xff0c; 欢迎评论 &#x1f4ac;点赞&#x1f4…