拉链表需求:

  1.数据量比较大

  2.变化的比例和频率比较小,例如客户的住址信息,联系方式等,比如有1千万的用户数据,每天全量存储会存储很多不变的信息,对存储也是浪费,因此可以使用拉链表的算法来节省存储空间

3.拉链历史表,既能反映每个客户不同时间的不同状态,也可查看某个时间点的全量快照信息

拉链表设计

设计的拉链历史表:

反映A客户的状态信息

  1. select * from ods_account where cst_id='A';

反映20190601历史数据:

  1. select * from ods_account where eff_date<='' and end_date>'';

反映20190602历史全量数据:

  1. select * from ods_account where eff_date<='' and end_date>'';

建表:

  1. use edw;
  2.  
  3. drop table if exists src_account;
  4. create table if not exists src_account(
  5. cst_id varchar(64) comment '客户唯一编号',
  6. bal float comment '余额',
  7. date_id varchar(16) comment '日期'
  8. )ENGINE=InnoDB DEFAULT CHARSET=utf8;
  9. alter table src_account add primary key(cst_id,date_id);
  10.  
  11. drop table if exists delta_account;
  12. create table if not exists delta_account(
  13. cst_id varchar(64) comment '客户唯一编号',
  14. bal float comment '余额',
  15. etl_flag varchar(16) comment 'ETL标记'
  16. )ENGINE=InnoDB DEFAULT CHARSET=utf8;
  17. alter table delta_account add primary key(cst_id,etl_flag);
  18.  
  19. drop table if exists odshis_account;
  20. create table if not exists odshis_account(
  21. cst_id varchar(64) comment '客户唯一编号',
  22. bal float comment '余额',
  23. eff_date varchar(16) comment '生效日期',
  24. end_date varchar(16) comment '失效日期',
  25. job_seq_id varchar(16) comment '批次号',
  26. new_job_seq_id varchar(16) comment '最新批次号'
  27. )ENGINE=InnoDB DEFAULT CHARSET=utf8;
  28. alter table odshis_account add primary key(cst_id,new_job_seq_id);
  29.  
  30. drop table if exists ods_account;
  31. create table if not exists ods_account(
  32. cst_id varchar(64) comment '客户唯一编号',
  33. bal float comment '余额',
  34. eff_date varchar(16) comment '生效日期',
  35. end_date varchar(16) comment '失效日期',
  36. job_seq_id varchar(16) comment '批次号'
  37. )ENGINE=InnoDB DEFAULT CHARSET=utf8;
  38. alter table ods_account add primary key(cst_id,eff_date,end_date);

加载原始数据:

  1. delete from src_account;
  2. insert into src_account values('A','','');
  3. insert into src_account values('B','','');
  4. insert into src_account values('C','','');
  5. insert into src_account values('D','','');
  6.  
  7. insert into src_account values('A','','');
  8. insert into src_account values('B','','');
  9. insert into src_account values('D','','');
  10. insert into src_account values('E','','');
  11.  
  12. insert into src_account values('A','','');
  13. insert into src_account values('B','','');
  14. insert into src_account values('C','','');
  15. insert into src_account values('D','','');
  16.  
  17. insert into src_account values('A','','');
  18. insert into src_account values('B','','');
  19. insert into src_account values('C','','');
  20. insert into src_account values('D','','');
  21. insert into src_account values('E','','');
  22. insert into src_account values('F','','');
  23. insert into src_account values('G','','');

开始拉链过程:

  1. #清空增量数据
  2. truncate delta_account;
  3. #加载增量数据(新增)
  4. insert into delta_account
  5. select t1.cst_id,t1.bal,'I' as etl_flag from
  6. (select * from src_account where date_id = '${job_date_id}') t1
  7. left join
  8. (select * from src_account where date_id = '${before_job_date_id}') t2
  9. on t1.cst_id = t2.cst_id where t2.cst_id is null;
  10.  
  11. #加载增量数据(删除)
  12. insert into delta_account
  13. select t1.cst_id,t1.bal,'D' as etl_flag from
  14. (select * from src_account where date_id = '${before_job_date_id}') t1
  15. left join
  16. (select * from src_account where date_id = '${job_date_id}') t2
  17. on t1.cst_id = t2.cst_id where t2.cst_id is null;
  18.  
  19. #加载增量数据(变更前)
  20. insert into delta_account
  21. select t1.cst_id,t1.bal,'A' as etl_flag from
  22. (select * from src_account where date_id = '${job_date_id}') t1
  23. left join
  24. (select * from src_account where date_id = '${before_job_date_id}') t2
  25. on t1.cst_id = t2.cst_id where t2.cst_id is not null
  26. and t1.bal <> t2.bal;
  27.  
  28. #加载增量数据(变更后)
  29. insert into delta_account
  30. select t1.cst_id,t2.bal,'B' as etl_flag from
  31. (select * from src_account where date_id = '${job_date_id}') t1
  32. left join
  33. (select * from src_account where date_id = '${before_job_date_id}') t2
  34. on t1.cst_id = t2.cst_id where t2.cst_id is not null
  35. and t1.bal <> t2.bal;
  36.  
  37. #1.重跑:删除已跑入数据
  38. delete from ods_account where job_seq_id = '${job_date_id}';
  39.  
  40. #2.重跑:从历史表恢复数据
  41. insert into ods_account(cst_id,bal,eff_date,end_date,job_seq_id)
  42. select cst_id,bal,eff_date,end_date,job_seq_id from odshis_account
  43. where new_job_seq_id = '${job_date_id}';
  44.  
  45. #3.重跑:删除已跑入历史数据
  46. delete from odshis_account where new_job_seq_id = '${job_date_id}';
  47.  
  48. #4.备份数据到历史表
  49. insert into odshis_account(cst_id,bal,eff_date,end_date,job_seq_id,new_job_seq_id)
  50. select cst_id,bal,eff_date,end_date,job_seq_id,'${job_date_id}'
  51. from ods_account t
  52. where t.end_date='' and exists ( select 1 from delta_account s
  53. where t.cst_id=s.cst_id );
  54.  
  55. #5.断链
  56. update ods_account t set end_date='${job_date_id}',job_seq_id = '${job_date_id}' where t.end_date='' and exists ( select 1 from delta_account s where etl_flag in ('I','D','A') and t.cst_id=s.cst_id );
  57.  
  58. #6.加链
  59. insert into ods_account(cst_id,bal,eff_date,end_date,job_seq_id)
  60. select cst_id,bal,'${job_date_id}' as eff_date,'' as end_date,'${job_date_id}' as job_seq_id from delta_account where etl_flag in ('A','I');
  61.  
  62. #7.保持数据完整性
  63. insert into ods_account (cst_id,bal,eff_date,end_date,job_seq_id)
  64. select t.cst_id,t.bal,'${job_date_id}','${job_date_id}' as end_date,'${job_date_id}' as job_seq_id from delta_account t where etl_flag = 'D' and not exists (select 1 from ods_account s
  65. where t.cst_id=s.cst_id)
  1.  
  1.  

mysql执行拉链表操作的更多相关文章

  1. 利用sqoop对mysql执行DML操作

    业务背景 利用Sqoop对MySQL进行查询.添加.删除等操作. 业务实现 select操作: sqoop eval \ --connect jdbc:mysql://127.0.0.1:3306/m ...

  2. Shell脚本中执行sql语句操作mysql的5种方法【转】

    对于自动化运维,诸如备份恢复之类的,DBA经常需要将SQL语句封装到shell脚本.本文描述了在Linux环境下mysql数据库中,shell脚本下调用sql语句的几种方法,供大家参考.对于脚本输出的 ...

  3. 在myeclipse中配置DB Driver(数据库用MySql),并在myeclipse执行sql语句操作

    在myeclipse中配置DB Driver(数据库用MySql),并在myeclipse执行sql语句操作 MyEclipse6.5    ,  mysq驱动jar包为mysql-connector ...

  4. 闯祸了,生成环境执行了DDL操作《死磕MySQL系列 十四》

    由于业务随着时间不停的改变,起初的表结构设计已经满足不了如今的需求,这时你是不是想那就加字段呗!加字段也是个艺术活,接下来由本文的主人咔咔给你吹. 试想一下这个场景 事务A在执行一个非常大的查询 事务 ...

  5. 数仓1.4 |业务数仓搭建| 拉链表| Presto

    电商业务及数据结构 SKU库存量,剩余多少SPU商品聚集的最小单位,,,这类商品的抽象,提取公共的内容 订单表:周期性状态变化(order_info) id 订单编号 total_amount 订单金 ...

  6. linux下MySQL安装登录及操作

    linux下MySQL安装登录及操作 二.安装Mysql 1.下载MySQL的安装文件 安装MySQL需要下面两个文件: MySQL-server-4.0.16-0.i386.rpm MySQL-cl ...

  7. hive拉链表

    前言 本文将会谈一谈在数据仓库中拉链表相关的内容,包括它的原理.设计.以及在我们大数据场景下的实现方式. 全文由下面几个部分组成:先分享一下拉链表的用途.什么是拉链表.通过一些小的使用场景来对拉链表做 ...

  8. 漫谈数据仓库之拉链表(原理、设计以及在Hive中的实现)

    本文将会谈一谈在数据仓库中拉链表相关的内容,包括它的原理.设计.以及在我们大数据场景下的实现方式. 全文由下面几个部分组成: 先分享一下拉链表的用途.什么是拉链表. 通过一些小的使用场景来对拉链表做近 ...

  9. hive拉链表以及退链例子笔记

    拉链表设计: 在企业中,由于有些流水表每日有几千万条记录,数据仓库保存5年数据的话很容易不堪重负,因此可以使用拉链表的算法来节省存储空间.  例子: -- 用户信息表; 采集当日全量数据存储到 (当日 ...

随机推荐

  1. php框架之laravel

    常见问题: 1. 访问网站500错误 这是因为laravel的缓存路径没有找到 laravel缓存文件路径是在 config/cache.php中设置,默认存在storage文件夹中 解决:需要保证s ...

  2. 85. Maximal Rectangle (JAVA)

    Given n non-negative integers representing the histogram's bar height where the width of each bar is ...

  3. Java 判断是否为回文字符串

    回文字符串有两种:abcba,abccba. 代码: static boolean func(String str) { int len = str.length(); for (int i = 0; ...

  4. 一键安装cobbler脚本

    #!/bin/bash # # Install Cobbler(Kickstart) Tools / # Created by OceanHo(gzhehai@foxmail.com) AT -- # ...

  5. kickstart一键装机部署

    1.第一步安装DHCP yum -y install dhcp 1.1配置修改文件 cat >> /etc/dhcp/dhcpd.conf <<END subnet 172.1 ...

  6. PyCharm专业版下载安装

    目录 1. 推荐阅读 2. PyCharm专业版 (目录) 1. 推荐阅读 Python基础入门一文通 | Python2 与Python3及VSCode下载和安装.PyCharm安装.Python在 ...

  7. 一、Vue CLI

    一.Vue CLI https://cli.vuejs.org/zh/guide/installation.html 介绍: 二.安装 # 安装 Vue Cli npm install -g @vue ...

  8. web部署命令简单记录

    非 root 用户设置环境变量:在< .bash_profile >中设置 后台运行:nohup dosomething >> log.out & nginx 启动ng ...

  9. open函数的打开标志所在文件

    /usr/include/x86_64-linux-gnu/bits/fcntl-linux.h

  10. 十二、S3C2440 裸机 — SDRAM

    12.1 SDRAM 介绍 12.1.1 SDRAM 定义 SDRAM(Synchronous Dynamic Random Access Memory):同步动态随机存储器-内存条 同步是指内存工作 ...