数据仓库构建拉链表之 Hive 操作

1.  什么是拉链表

        拉链表,记录每条信息的生命周期,一旦记录的生命周期结束,就重新开始一条新的记录,并把当前日期放入生效开始日期。

        如果当前信息至今有效,在生效结束日期中填入一个极大值(如9999-99-99

           

2.  为什么要做拉链表

      拉链表适合于:数据会发生变化,但是大部分是不变的

      比如:订单信息未支付支付、未发货、已完成状态经历了一周,大部分时间是不变化的如果数据量有一定规模,无法按照每日全量的方式保存。 比如:1亿用户*365天,每天一份用户信息。(无法做每日全)

                  

                  

3.如何使用拉链表

          通过生效开始日期<=某个日期  生效结束日期>=某个日期 ,能够得到某个时间点的数据全量切片。

          1)拉链表数据

                    

     2)例如获取2019-01-01的历史切片select * from order_info where start_date<=’2019-01-01’ and end_date>='2019-01-01'

                   

     3)例如获取2019-01-02的历史切片 select * from order_info where start_date<=’2019-01-02’ and end_date>='2019-01-02'

                   

 4. 拉链表形成过程

       

5. 拉链表制作过程 Hive 操作

       1)打开hadoop 集群 (hive依赖Hadoop集群运行)

             在hive路径下执行      bin/hive       进入hive命令窗口

             创建 test 数据库

               use test

      2)   创建订单表 和 并添加测试数据

             创建订单表 

hive (test)> drop table if exists dwd_order_info;

     create external table dwd_order_info (

    `id` string COMMENT '',

    `total_amount` decimal(10,2) COMMENT '',

    `order_status` string COMMENT ' 1 2 3 4 5',

    `user_id` string COMMENT 'id',

    `payment_way` string COMMENT '',

    `out_trade_no` string COMMENT '',

    `create_time` string COMMENT '',

    `operate_time` string COMMENT ''

)

PARTITIONED BY (`dt` string)
stored as parquet

location '/warehouse/gmall/dwd/dwd_order_info/'

tblproperties ("parquet.compression"="snappy");

添加 2 天的测试数据  

insert into table dwd_order_info partition (dt = "2019-05-01")
 values 
 ("1",2300,"待支付","001",null ,null ,"2019-05-01",null),
 ("2",300,"待支付","005",null ,null,"2019-05-01",null),
 ("3",500,"已支付","005","zhifubao","16552313","2019-05-01",null);
 
 
insert into table dwd_order_info partition (dt = "2019-05-02")
values 
("2",300,"已支付","005","weixin","56534","null","2019-05-02"),
("4",234,"待支付","005",null,null,"2019-05-02",null),
("5",234,"已支付","005","zhifu","12325346","2019-05-02",null);

 

 3) 初始化拉链表

      创建

hive (test)>
drop table if exists dwd_order_info_his;
create table dwd_order_info_his(
    `id` string COMMENT '订单编号',
    `total_amount` decimal(10,2) COMMENT '订单金额',
    `order_status` string COMMENT '订单状态',
    `user_id` string COMMENT '用户id' ,
    `payment_way` string COMMENT '支付方式',
    `out_trade_no` string COMMENT '支付流水号',
    `create_time` string COMMENT '创建时间',
    `operate_time` string COMMENT '操作时间',
    `start_date`  string COMMENT '有效开始日期',
    `end_date`  string COMMENT '有效结束日期'
) COMMENT '订单拉链表'
stored as parquet
location '/warehouse/gmall/dwd/dwd_order_info_his/'
tblproperties ("parquet.compression"="snappy");

      初始化第一天的数据

hive (test)>
insert overwrite table dwd_order_info_his
select
    id,
    total_amount,
    order_status,
    user_id,
    payment_way,
    out_trade_no,
    create_time,
    operate_time,
    '2019-05-01',
    '9999-99-99'
from dwd_order_info oi
where oi.dt='2019-05-01';

         查询 

           ***** 尖叫提示 本文章为测试Demo   数据较少  查询未加 limit , 实际业务操作 查询语句请加 limit

          hive (test)> select * from dwd_order_info_his

 

   4)追加第二天的订单数据到拉链表

           

// 过程中要用到 一个临时的拉链表   先创建

hive (test)>
drop table if exists dwd_order_info_his_tmp;
create external table dwd_order_info_his_tmp( 
    `id` string COMMENT '订单编号',
    `total_amount` decimal(10,2) COMMENT '订单金额', 
    `order_status` string COMMENT '订单状态', 
    `user_id` string COMMENT '用户id' ,
    `payment_way` string COMMENT '支付方式',  
    `out_trade_no` string COMMENT '支付流水号',  
    `create_time` string COMMENT '创建时间',  
    `operate_time` string COMMENT '操作时间',
    `start_date`  string COMMENT '有效开始日期',
    `end_date`  string COMMENT '有效结束日期'
) COMMENT '订单拉链临时表'
stored as parquet
location '/warehouse/gmall/dwd/dwd_order_info_his_tmp/'
tblproperties ("parquet.compression"="snappy");
// 追加数据


hive (test)>
insert overwrite table dwd_order_info_his_tmp
select *
from 
   (select 
        id,
        total_amount,
        order_status,
        user_id,
        payment_way,
        out_trade_no,
        create_time,
        operate_time,
        '2019-05-02' start_date,
        '9999-99-99'  end_date
    from 
       dwd_order_info
    where 
       dt = '2019-05-02'
union all 
    select
        oh.id,  
        oh.total_amount,
        oh.order_status,
        oh.user_id,
        oh.payment_way,
        oh.out_trade_no,
        oh.create_time,
        oh.operate_time,
        oh.start_date,
     // 左连接时 原先拉链表中的数据都保留,第二天的订单id如果是null 即新订单 结束日期9999-99-99
       // 如果第二天的订单id如果不是null, 订单修改了状态 ,结束日期修改为前一天
        if (oi.id is null , oh.end_date, date_add(oi.dt,-1)) end_date
    from 
        dwd_order_info_his oh
    left join
        (select *
         from
           dwd_order_info
         where 
           dt = '2019-05-02') oi
    on oh.id = oi.id ) his 
    order by his.id, start_date;

 

// 用临时拉链表 覆盖之前的 拉链表
hive (test)> insert overwrite table dwd_order_info_his 
select * from dwd_order_info_his_tmp;

 

 

// 查询结果

hive (test)> select * from dwd_order_info_his ;

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值