锦州市广厦电脑维修|上门维修电脑|上门做系统|0416-3905144热诚服务,锦州广厦维修电脑,公司IT外包服务
topFlag1 设为首页
topFlag3 收藏本站
 
maojin003 首 页 公司介绍 服务项目 服务报价 维修流程 IT外包服务 服务器维护 技术文章 常见故障
锦州市广厦电脑维修|上门维修电脑|上门做系统|0416-3905144热诚服务技术文章
hive 拉链表设计与实现

作者: 佚名  日期:2023-07-14 20:43:40   来源: 本站整理

一、前言

做过电商开发的同学对订单的业务应该不陌生,比如对一条订单数据来说,通常会有一个类似于status的字

段来标识这个订单的完整的生命周期,从存储的数据来看,一张表只需要存储这一条数据即可。

 

但是对于数据分析来看,为了跟踪这个订单的全生命周期的完整过程来说,这并不是一个很好的设计,假如说订

单到已支付但未发货,而且在未发货这一步停留的时间很长,对于大数据分析场景来说,这就是一个重要的分析

场景,但对于mysql存储的订单表来说,这就有些冗余了。这也就是说,mysql在设计表的时候,是会充分考虑

冗余数据量带来的性能问题。

 

二、拉链表业务背景

 

我们知道,Hive在实际工作中主要用于构建离线数据仓库,定期的从各种数据源中同步采集数据到Hive中,

经过分层转换提供数据给上层其他应用使用。

 

例如:有一个定时任务每天从MySQL中同步最新的订单信息、用户信息、店铺信息等到数据仓库中,从而进行订单分析、用户分析等。

 

如下图所示,为一个数仓简单的业务流程图;

 

2.1 数据同步引发的问题

 

有下面这样一张用户表tb_user,有过开发经验的同学对类似的订单表应该不陌生,比如每次注册完一个用户后,该表中就会产生一条新

的数据,记录了该用户的id、手机号码、用户名、性别、地址等信息。

 

关于该表在业务中的具体使用场景如下:

  • 每天都会有用户注册,产生新的用户信息;
  • 每天都需要将MySQL中的用户数据同步到Hive数据仓库中;
  • 需要对用户的信息做统计分析,例如统计新增用户的个数、用户性别分布、地区分布、运营商分布等指标;

 

数据同步的过程大概长下面这样

 比如说,在2021-01-01这一天,MySQL中有10条用户信息;

 

然后通过中间程序(或其他方式)同步到下面的Hive表中了;

 

现在,假如在 2021-01-02 这一天,在前一天的基础上,MySQL中新增了2条用户注册数据,并且其中有1条用户数据发生更新,

  • 新增两条用户数据011和012;
  • 008的addr发生了更新,从gz更新为sh;

 

到了2021-01-03这天,Hive需要对2号的数据进行同步更新处理,此时问题来了:

新增的数据会直接加载到Hive表中,但是更新的数据如何存储在Hive表中?

 

2.1.1 解决方案1

在Hive中用新的addr覆盖008的老的addr,直接更新

 这么做的优点是:实现最简单,使用起来最方便,但缺点也是很明显的,没有历史状态,008的地址是1月2号在sh

,但是1月2号之前是在gz的,如果要查询008的1月2号之前的addr就无法查询,也不能使用sh代替;

 

2.1.2 解决方案2

每次数据改变,根据日期构建一份全量的快照表,每天一张表

这样做的优点是:记录了所有数据在不同时间的状态, 缺点:冗余存储了很多没有发生变化的数据,导致存储的数据量过大;

 

2.1.3 解决方案3

 

构建拉链表,通过时间标记发生变化的数据的每种状态的时间周期,如下图表中数据所示,

它大意就是,当一条数据中的关键业务标识字段发送了变化,将新增加一条数据,将这

条数据的过期时间设置的非常大,作为这条数据的边界,同样主键的数据再次过来的时

候,在新增的一条记录中只需要记录变化的字段即可;关于拉链表,下文将做详细的讲述;

 

三、拉链表设计与原理

 

3.1 功能与应用场景

拉链表专门用于解决在数据仓库中数据发生变化如何实现数据存储的问题。

拉链表的设计是将更新的数据进行状态记录,没有发生更新的数据不进行状态存储,用于存储所有

数据在不同时间上的所有状态,通过时间进行标记每个状态的生命周期,查询时,根据需求可以

获取指定时间范围状态的数据,默认用9999-12-31等最大值来表示最新状态。

如下图所示,记录了某些订单的完整生命周期;

 

3.2 实现步骤

用下面这张图来说明其完整的实现过程

具体来说,操作步骤如下:

 

3.2.1 Step1

增量采集变化数据,放入增量表中。

 

3.2.2  Step2

将Hive中的拉链表与临时表的数据进行合并,合并结果写入临时表。

 

3.2.3 Step3

将临时表的数据覆盖写入拉链表中。

 

3.3 操作演示

 

准备一份原始数据,内容如下

 

3.3.1 创建一张表并加载数据

    ——创建拉链表createtabledw_zipper(useridstring,phonestring,nickstring,genderint,addrstring,starttimestring,endtimestring)rowformatdelimitedfieldsterminatedby'\t';——加载模拟数据loaddatalocalinpath'/usr/local/soft/selectdata/zipper。txt'intotabledw_zipper;

执行过程

 检查数据是否加载进去

 

3.3.2 模拟增量数据变化

下面为两条新增的数据,以及一条变化的数据

创建一张增量表,并加载数据

    createtableods_zipper_update(useridstring,phonestring,nickstring,genderint,addrstring,starttimestring,endtimestring)rowformatdelimitedfieldsterminatedby'\t';loaddatalocalinpath'/usr/local/soft/selectdata/update。txt'intotableods_zipper_update;

 执行过程

检查数据是否加载成功

 

 

3.3.3 合并数据

 

创建一张临时表

    createtabletmp_zipper(useridstring,phonestring,nickstring,genderint,addrstring,starttimestring,endtimestring)rowformatdelimitedfieldsterminatedby'\t';

执行过程

 

合并拉链表与增量表

    insertoverwritetabletmp_zipperselectuserid,phone,nick,gender,addr,starttime,endtimefromods_zipper_updateunionall——查询原来拉链表的所有数据,并将这次需要更新的数据的endTime更改为更新值的startTimeselecta。userid,a。phone,a。nick,a。gender,a。addr,a。starttime,——如果这条数据没有更新或者这条数据不是要更改的数据,就保留原来的值,否则就改为新数据的开始时间-1if(b。useridisnullora。endtime<'9999-12-31',a。endtime,date_sub(b。starttime,1))asendtimefromdw_zipperaleftjoinods_zipper_updatebona。userid=b。userid;

执行上面的sql

 

覆盖拉链表

insert overwrite table dw_zipper select * from tmp_zipper;

执行过程

执行完成后,检查拉链表的数据,可以看到新增了2条数据,同时对于相同的那条数据做了时间上的更新;



热门文章
  • 华硕B75m-A主板维修一例
  • iPad Air 4不充电,不开机(PD芯片...
  • 华硕X55JX时不时不触发(桥待机供电...
  • 戴尔笔记本恢复出厂设置恢复原厂系...
  • 开源计算机视觉库OpenCV详解
  • hive 拉链表设计与实现
  • 条码打印机设置标签纸大小?打印机驱...
  • 怎么判断MySQL中sql语句索引是否生...
  • L1正则化和L2正则化
  • 在Linux系统下,可以使用以下方法和...
  • 主板型号怎么看?小编将给大家介绍...
  • win10在激活界面会提示无法访问激活...
  • 锦州广厦电脑上门维修

    报修电话:13840665804  QQ:174984393 (联系人:毛先生)   
    E-Mail:174984393@qq.com
    维修中心地址:锦州广厦电脑城
    ICP备案/许可证号:辽ICP备2023002984号-1
    上门服务区域: 辽宁锦州市区
    主要业务: 修电脑,电脑修理,电脑维护,上门维修电脑,黑屏蓝屏死机故障排除,无线上网设置,IT服务外包,局域网组建,ADSL共享上网,路由器设置,数据恢复,密码破解,光盘刻录制作等服务

    技术支持:微软等