hive上一种通用的拉链记历史方法

数据仓库中针对历史数据的记录方法一般有3种方法
1.保存最新记录,用最新数据计算历史数据
2.快照,针对每天保留全量数据
3.拉链记历史,每天针对变化的数据记录其生命周期
上面3种各有优势,主要体现的存储空间占用、下游任务使用成本、是否能回溯历史,整体上是不同应用场景下要有不同选择。
针对拉链记历史一种通用的方法是对每条数据记录下生命周期begin_date,end_date;这咱在日常工作中最常用。在这种情况下
就要考虑两个点。一是数据由于同一条记录在整个生命周期有可能存在多条,如何存储能保证下游的使用方便和利用成本最低;
二是当这种需求多时,如何利用统一的代码来把这种需求归一;不是重复性的代码。
针对上面这两点考虑,我们在生产环境中设计思路如下
1.采用生命周期来分区,这样能有效利用数据库的分区裁剪功能,提高下游利用效率;这是就要考虑分区字段的选择,一般情况
是按天(end_date,begin_date)这样二级分区,这样利用效率最高。这里注意一定要把end_date放前面,原因是你使用时,一般
是取某一天的记录,就是end_date>某天。这里考虑到按天分区,虽然效率高,但是造成子分区过多,整个的数据碎片化严重,而且
在ODPS上导致的子目录过多,这里分区字段归化到月
2.考虑代码通用性,这里把源表名、delta表名、日期作为参数,然后读取元数据,来拼接SQL;再调用接口执行。保持了代码的封装。

一个ODPS的事例代码.注意顺序不可改
1.取有变更的记录,把end_date 换成当天,分区字段归一到当月

insert into table wcq_lc_wjs_claim_reserve_dev partition(pt1_end_month,pt2_begin_month)
select
 a.id                    
,a.reserve_type          
,a.outstanding_amount    
,a.settled_amount        
,a.remark                
,a.operator              
,a.op_date               
,a.claim_id              
,a.policy_id             
,a.is_deleted            
,a.gmt_created           
,a.creator               
,a.gmt_modified          
,a.modifier              
,a.begin_date         
,a.end_date
,TO_CHAR(DATETRUNC(DATEADD(TO_DATE('${bizdate}','yyyymmdd'),-1,'dd'),'MM'),'yyyymmdd000000')  pt1_end_month
,TO_CHAR(DATETRUNC(a.begin_date,'MM'),'yyyymmdd000000')          pt2_begin_month
from (
select 
 ,b.id                         
 ,b.reserve_type                 
 ,b.outstanding_amount           
 ,b.settled_amount               
 ,b.remark                       
 ,b.operator                     
 ,b.op_date                      
 ,b.claim_id                     
 ,b.policy_id                    
 ,b.is_deleted                   
 ,b.gmt_created                  
 ,b.creator                      
 ,b.gmt_modified                 
 ,b.modifier                     
 ,b.begin_date                   
 ,DATEADD(TO_DATE('${bizdate}','yyyymmdd'),-1,'dd')  end_date                     
from (select * from wcq_ods_wjs_claim_reserve_delta where pt='${bizdate}000000') a 
join (select * from wcq_lc_wjs_claim_reserve where pt1_end_month='30001201000000' ) b on (a.id=b.id)
)a
left outer join  (select * from wcq_lc_wjs_claim_reserve where pt1_end_month=TO_CHAR(DATETRUNC(DATEADD(TO_DATE('${bizdate}','yyyymmdd'),-1,'dd'),'MM'),'yyyymmdd000000')) b on (a.id=b.id)
where b.id is null;

2.把新增、变化的数据begin_date,改成当天。别的不改

insert overwrite table wcq_lc_wjs_claim_reserve_dev partition(pt1_end_month='30001201000000',pt2_begin_month='19000101000000')
select 
  case when  a.id  is not null then a.id                 else b.id                 end as id                            
 ,case when  a.id  is not null then a.reserve_type       else b.reserve_type       end as reserve_type                  
 ,case when  a.id  is not null then a.outstanding_amount else b.outstanding_amount end as outstanding_amount            
 ,case when  a.id  is not null then a.settled_amount     else b.settled_amount     end as settled_amount                
 ,case when  a.id  is not null then a.remark             else b.remark             end as remark                        
 ,case when  a.id  is not null then a.operator           else b.operator           end as operator                      
 ,case when  a.id  is not null then a.op_date            else b.op_date            end as op_date                     
 ,case when  a.id  is not null then a.claim_id           else b.claim_id           end as claim_id                      
 ,case when  a.id  is not null then a.policy_id          else b.policy_id          end as policy_id                     
 ,case when  a.id  is not null then a.is_deleted         else b.is_deleted         end as is_deleted                    
 ,case when  a.id  is not null then a.gmt_created        else b.gmt_created        end as gmt_created                 
 ,case when  a.id  is not null then a.creator            else b.creator            end as creator                       
 ,case when  a.id  is not null then a.gmt_modified       else b.gmt_modified       end as gmt_modified                
 ,case when  a.id  is not null then a.modifier           else b.modifier           end as modifier 
 ,case when  a.id  is not null then to_date('${bizdate}','yyyymmdd')  else b.begin_date    end as begin_date  
 ,case when  a.id  is not null then to_date('30001231','yyyymmdd')    else b.end_date      end as end_date

from (select * from wcq_ods_wjs_claim_reserve_delta where pt='${bizdate}000000') a 
full outer join (select * from wcq_lc_wjs_claim_reserve where pt1_end_month='30001201000000' and end_date>='${bizdate}' and begin_date<='${bizdate}') b on (a.id=b.id)
;

最后,如何使用

select * from wcq_lc_wjs_claim_reserve_dev 
   where pt1_end_month>=to_char(to_date('${bizdate}','yyyymmdd'),'yyyymm01000000') 
     and pt2_begin_month<=to_char(to_date('${bizdate}','yyyymmdd'),'yyyymm01000000') 
     and begin_date<=to_date('${bizdate}','yyyymmdd')
     and end_date>=to_date('${bizdate}','yyyymmdd')
     ;
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Hive是一个基于Hadoop的数据仓库架构​​,可以用于处理大数据量的结构化和半结构化数据。拉链表是一种常用于历史数据关联分析的技术。下面我将简要介绍如何在Hive中使用拉链表来关联历史数据拉链表是一种用于处理数据随时间变动的关联关系的表设计方法。它通常包含两个重要的字段:生效日期和失效日期。生效日期表示了某个数据的开始日期,失效日期表示了该数据的结束日期。 在Hive中,我们可以使用窗口函数和联接操作来实现拉链表的历史数据关联。首先,我们需要在数据表中添加生效日期和失效日期字段,并将历史数据按照日期排序。然后,我们可以使用窗口函数来为每一行数据分配一个唯一的行号,并根据行号对历史数据进行版本化。接下来,我们可以使用联接操作将历史数据和当前数据关联起来,以便进行历史数据的查询和分析。 例如,我们有一个学生表student,其中包含学生的信息,还有一个历史变动表student_history,用于录学生信息的变动。我们可以使用拉链表的方式将学生表和学生历史变动表进行关联。 首先,我们可以在student表和student_history表中添加生效日期和失效日期字段,并将数据按照日期排序。然后,我们使用窗口函数为每一行数据分配一个唯一的行号,并对学生历史变动表进行版本化。 接下来,我们可以使用联接操作将学生表和学生历史变动表进行关联,以便查询某个时间点学生的信息以及变动情况。例如,我们可以查询某个日期范围内学生的姓名、年龄以及变动情况。 在Hive中,使用拉链表来关联历史数据可以提供更加全面和准确的历史数据分析。通过使用窗口函数和联接操作,我们可以轻松地实现拉链表的历史数据关联。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值