当前位置:   article > 正文

Hive---拉链表设计与实现_拉链表的原理和简单实现

拉链表的原理和简单实现

1 数据同步问题

Hive在实际工作中主要用于构建离线数据仓库,定期的从各种数据源中同步采集数据到Hive中,经过分层转换提供数据应用。比如每天需要从MySQL中同步最新的订单信息、用户信息、店铺信息等到数据仓库中,进行订单分析、用户分析。

 

 例如:MySQL中有一张用户表:tb_user,每个用户注册完成以后,就会在用户表中新增该用户的信息.

 

由于每天都会有用户注册,产生新的用户信息,那么每天都需要将MySQL中的用户数据同步到Hive数据仓库中.

假如在1号已经在hive中创建了表并拉取了数据,但是在2号时MySQL中新增2条用户注册数据,并且有1条用户数据发生更新.

 

 那么我们需要对2号的数据进行同步到hive中,新增的数据会直接加载到Hive表中,但是更新的数据如何存储在Hive表中?

 方案一:直接覆盖

使用2号的数据 直接将1号的数据覆盖掉
优点:实现最简单,使用起来最方便
缺点:没有历史状态 想查询008之前的数据查看不到

 方案二:根据日期构建一份全量的快照表

 1号创建一张表拉取所有数据
2号再创建一张表拉取所有数据 
... 每天都创建一张表
优点:记录了所有数据在不同时间的状态
缺点:冗余存储了很多没有发生变化的数据,导致存储的数据量过大

 方案三:构建拉链表,通过时间标记发生变化的数据的每种状态的时间周期

 

 拉链表的设计是将更新的数据进行状态记录,没有发生更新的数据不进行状态存储,用于存储所有数据在不同时间上的所有状态,通过时间进行标记每个状态的生命周期,查询时,根据需求可以获取指定时间范围状态的数据,默认用9999-12-31等最大值来表示最新状态。

2 拉链表实现原理

 

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

 

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

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

3 拉链表实现演示

 创建拉链表

-- 数据准备
vi 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

  1. --创建拉链表
  2. create table dw_zipper
  3. (
  4. userid string,
  5. phone string,
  6. nick string,
  7. gender int,
  8. addr string,
  9. starttime string,
  10. endtime string
  11. ) row format delimited fields terminated by '\t';
  12. load data local inpath '/root/zipper.txt' into table dw_zipper;
  13. select * from dw_zipper;

 创建增量表

vi 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

 

  1. create table ods_update
  2. (
  3. userid string,
  4. phone string,
  5. nick string,
  6. gender int,
  7. addr string,
  8. starttime string,
  9. endtime string
  10. ) row format delimited fields terminated by '\t';
  11. load data local inpath '/root/update.txt' overwrite into table ods_update;
  12. select * from ods_update;

创建临时表

  1. create table tmp_zipper
  2. (
  3. userid string,
  4. phone string,
  5. nick string,
  6. gender int,
  7. addr string,
  8. starttime string,
  9. endtime string
  10. ) row format delimited fields terminated by '\t';

 合并数据到临时表

  1. insert overwrite table tmp_zipper
  2. select
  3. userid,
  4. phone,
  5. nick,
  6. gender,
  7. addr,
  8. starttime,
  9. endtime
  10. from ods_update
  11. union all
  12. --查询原来拉链表的所有数据,并将这次需要更新的数据的endTime更改为更新值的startTime
  13. select
  14. a.userid,
  15. a.phone,
  16. a.nick,
  17. a.gender,
  18. a.addr,
  19. a.starttime,
  20. --如果这条数据没有更新或者这条数据不是要更改的数据,就保留原来的值,否则就改为新数据的开始时间-1
  21. if(b.userid is null or a.endtime < '9999-12-31', a.endtime , date_sub(b.starttime,1)) as endtime
  22. from dw_zipper a left join ods_update b
  23. on a.userid = b.userid ;

覆盖拉链表数据

  1. insert overwrite table dw_zipper
  2. select * from tmp_zipper;

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/255226
推荐阅读
相关标签
  

闽ICP备14008679号