hive 模拟update 操作

来源:互联网 发布:西安网络推广外包 编辑:程序博客网 时间:2024/06/17 11:52

在使用hive构建数据仓库的时候,经常会遇到从mysql或者oracle数据导入到hive中。

一般情况下,每天导一次数据,有些数据需要更新操作,最典型的例子就是订单数据,比如:

订单创建时间订单导入hive时间订单更新时间2015-07-01 12:09:112015-07-02 00:30:002015-07-02 20:07:12

这个例子就很明显,如果按照订单生成时间导数据的话,订单状态更新后的数据就无法同步到hive 的数据仓库。

因为hive 不支持update操作,那么如何合并订单历史和更新数据呢?

那就使用hive模拟update操作。

hortonworks有一篇文章:http://zh.hortonworks.com/blog/four-step-strategy-incremental-updates-hive/

这篇文章就是说如何使用hive现有的操作来达到update数据的效果。

按照这么文章的操作,也会遇到一些问题:

1、join容易产生多条记录

2、jion操作比较耗时

这里我们推荐一种更轻快的解决办法,使用rank函数

以下面代码为例:

create view order_view as select t2.* from (      select t1.*,rank() over (partition by order_id order by update_time desc,coalesce(update_time,0),rand()) as order_rank       from (select * from order_his             union all            select * from order_daily) t1) t2  where order_rank=1;drop table order_all;create table order_all as select * from order_view;insert overwrite table order_his select * from order_all; 
order_his: 订单历史表

order_dail:每天新导入的订单数据,这里不仅要考虑创建时间是前一天的订单,还有将update_time 是前一天的订单导出来

对同一个order_id 的数据按照更新时间排序,取最晚的一条,也就是最新的数据。

这种方式即简单又安全,因为在实际应用中,经常遇到jion数据出现重复数据问题


如果遇到 hive group by中只想针对一部分字段进行group by ,我们可以使用collect_set(column_name)[0] 这种方式

比如,test_table 有a b c 三列,但是我只想对a进行group by , 其他两列随机取出一个值就可以

sql:

select a,collect_set(b)[0] as b,collect_set(c)[0] as c from test_table group by a;



0 0