增量表拉链表全量表实现方式

现在hive数仓的存储数据的方式无非就三种增量,拉链,全量,这三种方式中最简单的就是全量的存储方式,我将从我自己工作单位的模式来分别说一下这三种的存储方式

全量抽取很简单,比如我们是20190801这一天的凌晨的两点开始抽数的,我们抽数这张表假设是是一个表,这个表记录的字段假设是会发生修改的,比如有个字段就是待还本金吧!用户如果发生还款以后,这个字段里面的金额就会发生变化,并且这一行对应的update的时间也是会发生变化的,咱们全量抽数是直接select * from mysql_table 然后把全量的这些数据直接同过sqoop传到hive表的一个分区dt='20190731'这样就完成了抽数,但是这里有一个问题,就是用户假设是在20190801这一天的凌晨一点的时候用户发生了一次还款,再这次还款之前,这个单子的待还本金,假设是100块钱,但是在凌晨一点的时候用户还款了50块钱,这样咱们的待还本金就变成了50块钱,后面如果想知道这个单子在20190731的时候待还本金是多少的时候,咱们就通过sql查询select * from hive_table 就会看到这个单子的待还本金是50块钱了,这样是不对的,因为咱们是在0801的时候还的钱,按照咱们说的流程来说的话理论上应该是100块钱,为啥我要说这个问题呢,因为咱们再做数据核对的时候,不光是一张表有这个待还金额的记录,或许其他表也会有待还本金这个字段的记录,理论上这个这两个表的金额应该是一样的,但是不一样就是可能因为两张表抽数完成时间不一致造成的,所以要注意的

增量的存储也很简单,直接就是根据创建时间和修改时间来抽取的,比如咱们是20190801号这一天抽数的,抽数sql如下        select * from mysql_table where createdate='20190731' or update='20190731' 直接就把数据抽上来了就可以了,这个同样会有上面全量的问题,有人可能会说这里不是卡了update='20190731'了吗,但是还是不行,举个例子啊,比如这个单子是在20190731这一天创建的,刚创建的时候用户贷款是100块钱,那么同样待还本金也是100,但是这个调皮的用户在20190801的凌晨一点左右的时候还了50块钱,这样咱们抽上来的增量里面的待还本金就变成了50块钱了,注意啊,也是坑啊,咱们怎么使用这个增量呢,增量的时候就稍微有点小麻烦了,比如咱们要看的20190731这一天的数据状态,咱们是 select * from (select *,row_number(partiton by id order by update desc) rn from hive_table where dt<='20190731') a where rn=1 这样来查出咱们需要的20190731这一天的数据的状态情况

拉链表是在增量表的基础上加工出来的,在我们的拉链表我会在原来的mysql_table 表中增加两个日期的字段start_dt和end_dt,这两个字段就是表示了这条数据再这段时间内的状态,比如一个单子从他创建20170518这一天创建之后一直到20180614这段时间没有任何变化我们会有一条记录是是start_dt=20170518 end_dt=20180614 这个单子从20180614这一天修改以后一直到现在为止再也没有发生过变化,我们会将这条数据的start_dt=20180614然后end_dt=99991231(我们是定义的最新的数据都保存在end_dt='99991231'这个分区里面),好了知道有了这两个字段,并且明白这两个字段的含义之后,我们以20190801这一天开始做拉链,我们在20190801先抽数一个增量表假设是hive_table1,直接代码吧  from (select * ,row_number() over(partition by id order by update) rn from (select * from hive_table1 where dt='20190801' union all select * from hive_table start_dt<='20190730' and end_dt>'20190730') insert overwrite table hive_table partition(end_dt='99991231') where rn=1 insert overwrite table hive_table partition(end_dt='20190731') 这样就完成了拉链,但是这样同样也会存在数据不准确的时候,因为咱们抽取的增量不准确,那么做出来的拉链肯定也不准确的,怎么解决呢?

我之前说的那些全量,增量,拉链都是通过离线来抽数的。

我现在说一下实时抽数,我们实时抽数的逻辑就是通过maxwell抽取mysql的binlog日志,然后留到kafka,kafka 通过消费者模式将数据保存在hbase这样的宽表中,这样宽表里面就是有row_key,这里面会保存这条数据这一天的数据变化的所有记录,等过了夜里12点,从这个hbase里面通过row_key排序取最新的一条数据,然后把最新的一条数据load到hive的对应分区中,这个就是增量的抽取的方法,后面可以通过增量的数据再做成拉链的方式。从上面的整个过程来看是实时表最准确,技术难度要高点。怕会有丢版本的情况,为了避免丢版本的情况,咱们还可以通过和离线融合来避免,大致的思路是先把离线和实时的表都放在一个临时的增量表,在放的时候,咱们一般的方法是增加一个在离线和实时的增量的表中都增加一个字段src,当咱们增量表的update的时间等于咱们抽数的这一天的时候离线表的src设置为1,实时表的src设置为2,如果update不等于今天,我会将离线的设置src设置为3,实时的为4.然后根据我设置的src排序取最新的插入到我临时表中 SQL是insert overwrite table hive_table3 parttiion(dt='20190731') from (select *,row_number() over(partition by id order by src) from ( select if(update='20190731') 1,3 as src,* from hive_table1(离线的增量表) where dt='20190731' union all select if(update='20190731') 2,4 as src,* from hive_table2(实时增量表)where dt='20190731') where rn =1;这个sql猛一看是以离线表为主,实时表为次的,其实不然,这个是因为离线表是在0801这一天通过select * from mysql_table where createdate='20190731' or update='20190731' 所以取的肯定是最新的数据。不会说丢版本,我说的丢版本是因为实时表会在hbase中有这一天的多次修改的记录,就怕咱们从hbase取数的时候一不小心没有排好序取到最新的数据

  • 1
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值