hive中拉链表
在有些情况下,为了保持历史的一些状态,需要用拉链表来做,这样做目的在可以保留所有状态的情况下可以节省空间。
拉链表适用于以下几种情况吧
数据量有点大,表中某些字段有变化,但是呢变化的频率也不是很高,业务需求呢又需要统计这种变化状态,每天全量一份呢,有点不太现实,
不仅浪费了存储空间,有时可能业务统计也有点麻烦,这时,拉链表的作用就提现出来了,既节省空间,又满足了需求。
一般在数仓中通过增加begin_date,en_date来表示,如下例,后两列是start_date和end_date.
1 2016-08-20 2016-08-20 创建 2016-08-20 2016-08-20
1 2016-08-20 2016-08-21 支付 2016-08-21 2016-08-21
1 2016-08-20 2016-08-22 完成 2016-08-22 9999-12-31
2 2016-08-20 2016-08-20 创建 2016-08-20 2016-08-20
2 2016-08-20 2016-08-21 完成 2016-08-21 9999-12-31
3 2016-08-20 2016-08-20 创建 2016-08-20 2016-08-21
3 2016-08-20 2016-08-22 支付 2016-08-22 9999-12-31
4 2016-08-21 2016-08-21 创建 2016-08-21 2016-08-21
4 2016-08-21 2016-08-22 支付 2016-08-22 9999-12-31
5 2016-08-22 2016-08-22 创建 2016-08-22 9999-12-31
begin_date表示该条记录的生命周期开始时间,end_date表示该条记录的生命周期结束时间;
end_date = ‘9999-12-31’表示该条记录目前处于有效状态;
如果查询当前所有有效的记录,则select * from order_his where dw_end_date = ‘9999-12-31′
如果查询2016-08-21的历史快照,则select * from order_his where begin_date <= ‘2016-08-21′ and end_date >= ‘2016-08-21’
再简单介绍一下拉链表的更新:
假设以天为维度,以每天的最后一个状态为当天的最终状态。
以一张订单表为例,如下是原始数据,每天的订单状态明细
1 2016-08-20 2016-08-20 创建
2 2016-08-20 2016-08-20 创建
3 2016-08-20 2016-08-20 创建
1 2016-08-20 2016-08-21 支付
2 2016-08-20 2016-08-21 完成
4 2016-08-21 2016-08-21 创建
1 2016-08-20 2016-08-22 完成
3 2016-08-20 2016-08-22 支付
4 2016-08-21 2016-08-22 支付
5 2016-08-22 2016-08-22 创建
根据拉链表我们希望得到的是
1 2016-08-20 2016-08-20 创建 2016-08-20 2016-08-20
1 2016-08-20 2016-08-21 支付 2016-08-21 2016-08-21
1 2016-08-20 2016-08-22 完成 2016-08-22 9999-12-31
2 2016-08-20 2016-08-20 创建 2016-08-20 2016-08-20
2 2016-08-20 2016-08-21 完成 2016-08-21 9999-12-31
3 2016-08-20 2016-08-20 创建 2016-08-20 2016-08-21
3 2016-08-20 2016-08-22 支付 2016-08-22 9999-12-31
4 2016-08-21 2016-08-21 创建 2016-08-21 2016-08-21
4 2016-08-21 2016-08-22 支付 2016-08-22 9999-12-31
5 2016-08-22 2016-08-22 创建 2016-08-22 9999-12-31
可以看出 1,2,3,4每个订单的状态都有,并且也能统计到当前的有效状态。
本例以hive为例,只考虑到实现,与性能无关
首先创建表
CREATE TABLE orders (
orderid INT,
createtime STRING,
modifiedtime STRING,
status STRING
) row format delimited fields terminated by '\t' CREATE TABLE ods_orders_inc (
orderid INT,
createtime STRING,
modifiedtime STRING,
status STRING
) PARTITIONED BY (day STRING)
row format delimited fields terminated by '\t' CREATE TABLE dw_orders_his (
orderid INT,
createtime STRING,
modifiedtime STRING,
status STRING,
dw_start_date STRING,
dw_end_date STRING
) row format delimited fields terminated by '\t' ;
首先全量更新,我们先到2016-08-20为止的数据。
初始化,先把2016-08-20的数据初始化进去
INSERT overwrite TABLE ods_orders_inc PARTITION (day = '2016-08-20')
SELECT orderid,createtime,modifiedtime,status
FROM orders
WHERE createtime < '2016-08-21' and modifiedtime <'2016-08-21';
刷到dw中
INSERT overwrite TABLE dw_orders_his
SELECT orderid,createtime,modifiedtime,status,
createtime AS dw_start_date,
'9999-12-31' AS dw_end_date
FROM ods_orders_inc
WHERE day = '2016-08-20';
如下结果
select * from dw_orders_his;
OK
1 2016-08-20 2016-08-20 创建 2016-08-20 9999-12-31
2 2016-08-20 2016-08-20 创建 2016-08-20 9999-12-31
3 2016-08-20 2016-08-20 创建 2016-08-20 9999-12-31
剩余需要进行增量更新
INSERT overwrite TABLE ods_orders_inc PARTITION (day = '2016-08-21')
SELECT orderid,createtime,modifiedtime,status
FROM orders
WHERE (createtime = '2016-08-21' and modifiedtime = '2016-08-21') OR modifiedtime = '2016-08-21'; select * from ods_orders_inc where day='2016-08-21';
OK
1 2016-08-20 2016-08-21 支付 2016-08-21
2 2016-08-20 2016-08-21 完成 2016-08-21
4 2016-08-21 2016-08-21 创建 2016-08-21
先放到增量表中,然后进行关联到一张临时表中,在插入到新表中
DROP TABLE IF EXISTS dw_orders_his_tmp;
CREATE TABLE dw_orders_his_tmp AS
SELECT orderid,
createtime,
modifiedtime,
status,
dw_start_date,
dw_end_date
FROM (
SELECT a.orderid,
a.createtime,
a.modifiedtime,
a.status,
a.dw_start_date,
CASE WHEN b.orderid IS NOT NULL AND a.dw_end_date > '2016-08-21' THEN '2016-08-21' ELSE a.dw_end_date END AS dw_end_date
FROM dw_orders_his a
left outer join (SELECT * FROM ods_orders_inc WHERE day = '2016-08-21') b
ON (a.orderid = b.orderid)
UNION ALL
SELECT orderid,
createtime,
modifiedtime,
status,
modifiedtime AS dw_start_date,
'9999-12-31' AS dw_end_date
FROM ods_orders_inc
WHERE day = '2016-08-21'
) x
ORDER BY orderid,dw_start_date; INSERT overwrite TABLE dw_orders_his
SELECT * FROM dw_orders_his_tmp;
在根据上面步骤把2016-08-22号的数据更新进去,最后结果如下
select * from dw_orders_his;
OK
1 2016-08-20 2016-08-20 创建 2016-08-20 2016-08-20
1 2016-08-20 2016-08-21 支付 2016-08-21 2016-08-21
1 2016-08-20 2016-08-22 完成 2016-08-22 9999-12-31
2 2016-08-20 2016-08-20 创建 2016-08-20 2016-08-20
2 2016-08-20 2016-08-21 完成 2016-08-21 9999-12-31
3 2016-08-20 2016-08-20 创建 2016-08-20 2016-08-21
3 2016-08-20 2016-08-22 支付 2016-08-22 9999-12-31
4 2016-08-21 2016-08-21 创建 2016-08-21 2016-08-21
4 2016-08-21 2016-08-22 支付 2016-08-22 9999-12-31
5 2016-08-22 2016-08-22 创建 2016-08-22 9999-12-31
至此,就得到了我们想要的数据。
hive中拉链表的更多相关文章
- hive拉链表
前言 本文将会谈一谈在数据仓库中拉链表相关的内容,包括它的原理.设计.以及在我们大数据场景下的实现方式. 全文由下面几个部分组成:先分享一下拉链表的用途.什么是拉链表.通过一些小的使用场景来对拉链表做 ...
- hive拉链表取数
例如,一个借款用户在hive上的拉链表.(end_dt存放逻辑与普通介绍的拉链表不一致) 需要拉去它在2019-05-01日的状态, 取数逻辑是: select * from tb where sta ...
- Hive 建外链表到 Hbase(分内部表、外部表两种方式)
一. Hive 建内部表,链到hbase :特点:Hive drop表后,Hbase 表同步删除 drop table if exists hbase_kimbo_test1;CREATE TABLE ...
- hive拉链表以及退链例子笔记
拉链表设计: 在企业中,由于有些流水表每日有几千万条记录,数据仓库保存5年数据的话很容易不堪重负,因此可以使用拉链表的算法来节省存储空间. 例子: -- 用户信息表; 采集当日全量数据存储到 (当日 ...
- 漫谈数据仓库之拉链表(原理、设计以及在Hive中的实现)
本文将会谈一谈在数据仓库中拉链表相关的内容,包括它的原理.设计.以及在我们大数据场景下的实现方式. 全文由下面几个部分组成: 先分享一下拉链表的用途.什么是拉链表. 通过一些小的使用场景来对拉链表做近 ...
- Hive-拉链表
一.问答介绍 1.什么是拉链表? 维护历史状态,以及最新状态数据的一种表,拉链表根据拉链粒度的不同,实际上相当于快照,只不过做了优化,去除了一部分不变的记录,通过拉链表可以很方便的还原出拉链时点的客户 ...
- SparkStreaming+Kafka 处理实时WIFI数据
业务背景 技术选型 Kafka Producer SparkStreaming 接收Kafka数据流 基于Receiver接收数据 直连方式读取kafka数据 Direct连接示例 使用Zookeep ...
- hive 汇率拉链表转日连续流水表
1.什么是拉链表 拉链表是针对数据仓库设计中表存储数据的方式而定义的,顾名思义,所谓拉链,就是记录历史.记录一个事物从开始,一直到当前状态的所有变化的信息. 我们先看一个示例,这就是一张拉链表,存储的 ...
- hive 历史拉链表的处理
1. CREATE TABLE lalian_test(id int,col1 string,col2 string,dt string)--测试表COMMENT 'this is a test2' ...
随机推荐
- setTimeout()与setInterval()
一.setTimeout与setInterval的用法(http://www.css88.com/archives/5804) setTimeout是超时调用,javascript是一个单线程的解析器 ...
- day26、面向对象进阶:多态、封装、反射
一.多态 什么是多态: 类的继承有两层意义:1.改变 2.扩展 多态就是类的这两层意义的一个具体的实现机. 即:调用不同类实例化的对象,下的相同的方法,实现的过程不一样 python中的标准类型就是多 ...
- ruby生成随机成绩
生成16个86到99范围内的值,并且每个成绩打印一行,这样就可以复制粘贴到Excel中! 16.times {|x| puts (86..99).to_a.sample}
- .pyc是个什么鬼?
1. Python是一门解释型语言? 我初学Python时,听到的关于Python的第一句话就是,Python是一门解释性语言,我就这样一直相信下去,直到发现了*.pyc文件的存在.如果是解释型语言, ...
- phpmyadmin的root密码忘记了怎么办?
管理mysql数据库的工具有网页版的phpmyadmin(开源),也有诸如客户端Navicat for MySQL(商业). 好多环境集成包,比如XAMPP.WampServer等集成了phpmyad ...
- 摘记 史上最强大的40多个纯CSS绘制的图形(一)
今天在国外的网站上看到了很多看似简单却又非常强大的纯CSS绘制的图形,里面有最简单的矩形.圆形和三角形,也有各种常见的多边形,甚至是阴阳太极和网站小图标,真的非常强大,分享给大家. Square(正方 ...
- dubbo工作原理
part -- 外挂1.dubbo借助spring的schema启动和初始化 1.1 spring扫描所有jar下META-INF的spring.handlers和spring.schemas. 1. ...
- 微信小程序上传文件
wx.chooseImage({ count: 1, // 默认9 sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有 sourc ...
- Unity3D图片的下载及保存
Unity3D图片的下载及保存 分类: Unity3D 2013-06-24 15:03 3609人阅读 评论(2) 收藏 举报 Unity3D图片URL 代码如下: [csharp] view pl ...
- [转载]反无人机企业DroneShield利用声音识别侦测无人机
原文:http://www.cnbeta.com/articles/495071.htm 无人机产业正在蓬勃发展,受益的不仅仅是那些生产小型飞行设备的企业.专家估计仅在澳大利亚就有5万架商用无人机以及 ...