拉链表和流水表

拉链表流水表都是为了记录数据的历史信息。

只是数据粒度的不同。

流水表精确到每天的每一条变化都记录其历史。而拉链表的粒度可控,一般选择每天为粒度,即每天的最终变化才记录。

所以理解了拉链表,自然就知道流水表了。

下面通过一个例子理解一下拉链表

2019-9-10

用户id 金额 时间
001 500 2019-9-10 12:00:00
002 600 2019-9-10 7:00:00
003 700 2019-9-10 16:00:00

此时的拉链表

用户id 金额 时间 到期时间
001 500 2019-9-10 12:00:00 9999-99-99 99:99:99
002 600 2019-9-10 7:00:00 9999-99-99 99:99:99
003 700 2019-9-10 16:00:00 9999-99-99 99:99:99
这里的到期日期只是一个标志,用来标记这个数据是当前的数据还是历史数据。
9999-99-99 99:99:99 这个时间是可以自定义的。甚至不用时间用任意自定义的标识符都行。

2019-9-11

用户id 金额 时间
001 500 2019-9-11 12:00:00
002 200 2019-9-11 17:00:00
003 800 2019-9-11 10:00:00

变更记录

用户id 金额 时间 备注
002 400 2019-9-11 10:00:00 取款200
003 800 2019-9-11 10:00:00 存款100
002 200 2019-9-11 17:00:00 取款200

此时的拉链表

用户id 金额 时间 到期时间
001 500 2019-9-10 12:00:00 9999-99-99 99:99:99
002 600 2019-9-10 7:00:00 2019-9-11 17:00:00
002 200 2019-9-11 17:00:00 9999-99-99 99:99:99
003 700 2019-9-10 16:00:00 2019-9-11 10:00:00
003 800 2019-9-11 10:00:00 9999-99-99 99:99:99

可以看到,9-11号这天,002号用户有两条交易记录,最后也只记录了当天最终的变化一条记录。这就是以天为粒度的拉链表。如果有很多天都变化,拉链表中就会有多条记录。

如何得到拉链表?

我们可以通过Cannl监听mysql的数据变化,然后每天做一个合并,再同步到hdfs上。

提一下,变更记录一般是在mysql端处理(合并)的。所以到了ods层,每个用户的变更记录已经只有一条了。

表结构

-- 用户账户表
create table if not exists zzy.account_info(
    id string,
    money int,
    in_time string  -- 进账时间
)
row format delimited fields terminated by ' ';

-- 账户变更表
create table if not exists zzy.account_change_detail(
    id string,
    money int,
    in_time string, -- 交易时间
    `comment` string -- 交易细节
)
row format delimited fields terminated by ' ';

-- 账户拉链表
create table if not exists zzy.account_zipper(
    id string,
    money int,
    in_time string, -- 进账时间
    out_time string -- 这条记录过期时间
)
row format delimited fields terminated by ' ';

更新拉链表

insert overwrite table zzy.account_zipper
select -- 更新这才变更的记录
a.id,
a.money,
a.in_time,
(
case 
  when out_time="9999-99-99 99:99:99" and b.id is not null
  then b.in_time
  else out_time --如果没匹配上说明是历史记录 原样保留就行
end
) out_time
from zzy.account_zipper a
left join zzy.account_change_detail b
on a.id=b.id
union
select -- 追加新记录
id,
money,
in_time,
'9999-99-99 99:99:99' out_time
from zzy.account_change_detail

你可能感兴趣的:(hive,大数据)