历史拉链表是一种数据模型,主要是针对数据仓库设计中表存储数据的方式而定义的;顾名思义,所谓历史拉链表,就是记录一个事务从开始一直到当前状态的所有变化的信息,拉链表可以避免按每一天存储所有记录造成的海量存储问题,同事也是处理缓慢变化数据的一种常见方式。

一、概念

在拉链表中,每一条数据都有一个生效日期(sdate) 和 失效日期(edate)。假设在一个用户表中,在 2019年10月8日 新增了两个用户,则这两条记录的生效时间为当天,由于到 2019年10月8日 为止,这两条记录还没有被修改过,所以失效时间为无穷大,这里设置为数据库中的最大值(2999-12-31),如图所示:

第二天(2019-10-09),用户 1001 被删除,用户 1002 的电话号码被修改成 16500000006。为了保留历史状态,用户 1001 的失效时间被修改成 2019-10-09,用户 1002 则变成两条记录,如图所示:

第三天(2019-10-10),又新增了用户 1003,则用户表数据如图:

如果要查询最新的数据,那么只要查询失效时间为 2999-12-31 的数据即可,如果要查询 10月8号 的历史数据,则筛选生效时间 <= 2019-10-08 并且失效时间 > 2019-10-08 的数据即可;如果查询的是 10月9日的数据,那么筛选条件则是生效时间 <= 2019-10-09 并且失效时间 > 2019-10-09;以此类推。

二、表的创建

临时源表 T_FIN_ACCTION_SRC,接收其它数据库(如 oracle)表推送过来的数据 ,表结构和源数据库的表结构一致。

--源表
create table T_FIN_ACCTION_SRC(eNo varchar(6),eName varchar(10),ePhone varchar(11),eData_date date
);

目标表 ( 即拉链表 ) T_FIN_ACCTION_TAR,这里注意的是:拉链表把源表的时间字段改成了生效时间失效时间

--拉链表
create table T_FIN_ACCTION_TAR(eNo varchar(6),eName varchar(10),ePhone varchar(11),sdate date,edate date
);

三、存储过程的创建

在这里为了方便阅读以及代码的编写,先写出整体的存储过程架构,然后我们在一步一步添加代码:

-- 将当前时间传入 (也可以传入昨天的时间哦,随机应变,如果传入的时间是今天则使用中要将时间减一,因为我们要处理的是昨天的数据)
create or replace function My_FIN_GL_SUBJECT_PRO(IN P_TODAY VARCHAR)returns void
as $$
declarebegin   --1.目标表中没有此主键的则确定为新增  -  新增--2.源表中没有该ID则进行关链  -  删除--3.修改--3.1 闭链:目标表中有此主键的记录,状态值不同,更新结束日期为当天--3.2 开链:目标表中新增一条修改的数据,更新结束日期为无穷大end;
$$
language plpgsql;

四、拉链的过程实现

1.目标表中没有此主键的则确定为新增 - 新增

insert into gplcydb.public.T_FIN_ACCTION_TAR(eNo,eName,ePhone,sdate,edate)  select s.eNo,s.eName,s.ePhone,s.eData_date,to_date('2999-12-31','yyyy-mm-dd')   from gplcydb.public.T_FIN_ACCTION_SRC s where s.eData_date=(to_date(P_TODAY,'yyyy-mm-dd') - 1) and not exists(select 1 from gplcydb.public.T_FIN_ACCTION_TAR t where s.eNo=t.eNo and s.eName=t.eNameand s.ePhone=t.ePhone);

2.源表中没有该ID则进行关链 - 删除

update gplcydb.public.T_FIN_ACCTION_TAR a set edate=(to_date(P_TODAY,'yyyy-mm-dd')-1) where not exists(select 1 from gplcydb.public.T_FIN_ACCTION_SRC s where s.eNo=a.eNo and a.edate=to_date('2999-12-31', 'yyyy-mm-dd') );

3.修改

3.1 闭链:目标表中有此主键的记录,状态值不同,更新结束日期为当天

update gplcydb.public.T_FIN_ACCTION_TAR b set edate=(to_date(P_TODAY,'yyyy-mm-dd')-1)    where b.edate=to_date('2999-12-31','yyyy-mm-dd')   and exists(select 1 from gplcydb.public.T_FIN_ACCTION_SRC s where s.eNo = b.eNo and b.sdate < (to_date(P_TODAY,'yyyy-mm-dd')-1) and (s.eName <> b.eName or s.ePhone <> b.ePhone ) );

3.2 开链:目标表中新增一条修改的数据,更新结束日期为无穷大

insert into gplcydb.public.T_FIN_ACCTION_TAR(eNo,eName,ePhone,sdate,edate)  select s.eNo,s.eName,s.ePhone,(to_date(P_TODAY,'yyyy-mm-dd') - 1),to_date('2999-12-31','yyyy-mm-dd')   from gplcydb.public.T_FIN_ACCTION_SRC s where s.eData_date=(to_date(P_TODAY,'yyyy-mm-dd') - 1) and exists( --处理数据断链新增的情况select 1 from (select eNo,sdate,max(edate) end_date from gplcydb.public.T_FIN_ACCTION_TAR group by eNo,sdate) t where t.eNo=s.eNo and s.eData_date = t.sdate and t.end_date <= to_date(P_TODAY,'yyyy-mm-dd') );

五、测试

要测试拉链函数,首先我们必须要在原表中插入数据(模拟一天全量的数据):

insert into T_FIN_ACCTION_SRC values('1001','feiniu','18500000001','2019-10-10');
insert into T_FIN_ACCTION_SRC values('1002','beibei','18400000005','2019-10-10');
insert into T_FIN_ACCTION_SRC values('1003','yuyu','13800000005','2019-10-10');

调用函数进行拉链测试:

select My_FIN_GL_SUBJECT_PRO('2019-10-11');  --调用函数
select * from T_FIN_ACCTION_TAR;   --查询拉链表

测试结果如下图:

插入第二天全量数据,这些数据中有新增的数据,有源数据被删除,还有源数据被修改,完整的模拟sql语句如下:

delete from T_FIN_ACCTION_SRC where eno='1003';
insert into T_FIN_ACCTION_SRC values('1004','kongkong','13800000666','2019-10-11');
update T_FIN_ACCTION_SRC set ename='xiaofeifei' where eno='1001';
select * from T_FIN_ACCTION_SRC;

原表的效果图如下:

接下来执行拉链函数:

--执行拉链函数
select My_FIN_GL_SUBJECT_PRO('2019-10-12');
select * from T_FIN_ACCTION_TAR;  --查询目标表

效果图如下:

深渊之刃 | Greenplum数据库之拉链表的实现相关推荐

  1. greenplum 历史拉链表

    3.1 历史拉链表 数据仓库定义:是一个面向主题的.集成的.相对稳定的.反映历史变化的数据集合,用于支持管理决策. 历史拉链表:一种数据模型,主要是针对数据仓库设计中表存储数据的方式而定义的.它记录了 ...

  2. oracle窗帘位图索引,Greenplum数据库设计开发规范参考.docx

    Greenplum数据库设计开发规范参考 Greenplum数据库设计开发规范参考文档2016年7月目 录Greenplum数据库设计开发规范1V1.511 前言41.1 文档目的41.2 文档范围4 ...

  3. hive中实现行转列_漫谈数据仓库之拉链表(原理、设计以及在Hive中的实现)

    全文由下面几个部分组成: 先分享一下拉链表的用途.什么是拉链表. 通过一些小的使用场景来对拉链表做近一步的阐释,以及拉链表和常用的切片表的区别. 举一个具体的应用场景,来设计并实现一份拉链表,最后并通 ...

  4. 缓慢变化维解决方案——拉链表实现详解

    缓慢变化维--拉链表实现 1.概述 1 缓慢变化维简介 缓慢变化维,简称SCD(Slowly Changing Dimensions) 一些维度表的数据不是静态的,而是会随着时间而缓慢地变化(这里的缓 ...

  5. 数仓--拉链表实战⭐⭐⭐⭐⭐

    拉链表实战⭐⭐⭐⭐⭐ 需求: 环境准备 在mysql中创建表和加载数据 在Hive中创建数据库和表: 全量导入数据到拉链表 将ODS层数据同步到DW层 增量导入数据到拉链表 在MySQL中添加增加数据 ...

  6. 系列 | 数仓实践第三篇NO.3『拉链表』

    点击上方蓝色字体,置顶/星标哦 目前10000+人已关注加入我们 拉链表是一种数据模型,主要是针对数据仓库设计中表存储数据的方式而定义的:顾名思义,所谓拉链表,就是记录历史,记录一个事务从开始一直到当 ...

  7. [hive]数仓分层|用户纬度拉链表|维度建模

    https://www.modb.pro/404?redirect=%2Fdb%2F241289 一.数仓分层 1.ODS层:原始数据层 ODS(O=original D=data S=store) ...

  8. 拉链表的详细实现过程(好文点赞收藏!!)

    目录 1-什么是拉链表 2-为什么要做拉链表 2.1-如何使用拉链表 3-拉链表的形成过程 4-拉链表的制作过程 4.1-初始化拉链表(首次独立执行) 4.2-制作当日变动数据(包括新增,修改)每日执 ...

  9. 意向客户主题看板 阿善有用 前边有用后面没用 拉链表

    今日内容:1) 分桶表的相关优化 -- 理解2) 建模分层操作 -- 需要操作3) 全量流程的统计分析: -- 需求操作 (尝试自己实现) 数据的采集, 数据的清洗转换, 数据维度退化, 数据的统计分 ...

最新文章

  1. Window7系统 中常见的进程命令分析?
  2. python绘制3d图形-Python基于matplotlib实现绘制三维图形功能示例
  3. springmvc多个视图解析器管理跳转资源
  4. 一个好用的Chrome扩展应用,Neater Bookmarks
  5. 使用uicollectionView时需要注意的问题
  6. gbase 8s oracle,GBase8s 查看数据库表空间信息
  7. 去掉ecshop后台版权
  8. java.nio教程_Java NIO系列教程(三) Buffer
  9. 事务没提交的数据查的出来吗?_品牛栏山,论分布式事务
  10. 单片机ADC采样算法----限幅平均滤波法
  11. 【rsync】工作模式及语法
  12. 常见创建项目编译运行问题汇总
  13. 深度学习经典论文翻译合集Deep Learning Papers Translation(CV)
  14. 苹果笔记本摄像头Linux驱动,苹果发布Macbook摄像头驱动更新 更适配window10
  15. 小失误点,不积跬步无以至千里
  16. 【Google Paper】对比学习用于解决推荐系统长尾问题
  17. 网站的海量数据和高并发的解决方案(二)
  18. window.print() 表格打印 完美实现分页
  19. 1.30.Flink SQL案例将Kafka数据写入hive
  20. 下载windows10.iso

热门文章

  1. 安装 k8s-dashboard 并通过 ingress 暴露访问
  2. 在服务器无限重复的日本动画,回顾动漫中最令人难忘的经典台词,始终在脑海里无限循环!...
  3. 炫舞滑板机器人_qq炫舞时尚永久滑板鞋怎么得 炫舞时尚永久滑板鞋获取方法
  4. 人工智能(PythonWeb)—— JS
  5. 【仪器使用操作笔记】 TDS1012示波器基础原理与使用
  6. 2015下半年苏子语录《我的人生感悟…
  7. 关于php的搞笑段子,笑死人的笑话搞笑段子10个 搞笑笑话笑死人不偿命
  8. 思兰IT传媒发布laoyV2.5静态修改版
  9. 软件工程知识点复习总结
  10. 《被黑暗罪恶辖制和蒙蔽的人啊快来…