拉链表需求:

  1.数据量比较大

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

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

拉链表设计

设计的拉链历史表:

反映A客户的状态信息

select * from ods_account where cst_id='A';

反映20190601历史数据:

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

反映20190602历史全量数据:

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

建表:

use edw;

drop table if exists src_account;
create table if not exists src_account(
cst_id varchar(64) comment '客户唯一编号',
bal float comment '余额',
date_id varchar(16) comment '日期'
)ENGINE=InnoDB DEFAULT CHARSET=utf8;
alter table src_account add primary key(cst_id,date_id); drop table if exists delta_account;
create table if not exists delta_account(
cst_id varchar(64) comment '客户唯一编号',
bal float comment '余额',
etl_flag varchar(16) comment 'ETL标记'
)ENGINE=InnoDB DEFAULT CHARSET=utf8;
alter table delta_account add primary key(cst_id,etl_flag); drop table if exists odshis_account;
create table if not exists odshis_account(
cst_id varchar(64) comment '客户唯一编号',
bal float comment '余额',
eff_date varchar(16) comment '生效日期',
end_date varchar(16) comment '失效日期',
job_seq_id varchar(16) comment '批次号',
new_job_seq_id varchar(16) comment '最新批次号'
)ENGINE=InnoDB DEFAULT CHARSET=utf8;
alter table odshis_account add primary key(cst_id,new_job_seq_id); drop table if exists ods_account;
create table if not exists ods_account(
cst_id varchar(64) comment '客户唯一编号',
bal float comment '余额',
eff_date varchar(16) comment '生效日期',
end_date varchar(16) comment '失效日期',
job_seq_id varchar(16) comment '批次号'
)ENGINE=InnoDB DEFAULT CHARSET=utf8;
alter table ods_account add primary key(cst_id,eff_date,end_date);

加载原始数据:

delete from src_account;
insert into src_account values('A','','');
insert into src_account values('B','','');
insert into src_account values('C','','');
insert into src_account values('D','',''); insert into src_account values('A','','');
insert into src_account values('B','','');
insert into src_account values('D','','');
insert into src_account values('E','',''); insert into src_account values('A','','');
insert into src_account values('B','','');
insert into src_account values('C','','');
insert into src_account values('D','',''); insert into src_account values('A','','');
insert into src_account values('B','','');
insert into src_account values('C','','');
insert into src_account values('D','','');
insert into src_account values('E','','');
insert into src_account values('F','','');
insert into src_account values('G','','');

开始拉链过程:

 #清空增量数据
truncate delta_account;
#加载增量数据(新增)
insert into delta_account
select t1.cst_id,t1.bal,'I' as etl_flag from
(select * from src_account where date_id = '${job_date_id}') t1
left join
(select * from src_account where date_id = '${before_job_date_id}') t2
on t1.cst_id = t2.cst_id where t2.cst_id is null; #加载增量数据(删除)
insert into delta_account
select t1.cst_id,t1.bal,'D' as etl_flag from
(select * from src_account where date_id = '${before_job_date_id}') t1
left join
(select * from src_account where date_id = '${job_date_id}') t2
on t1.cst_id = t2.cst_id where t2.cst_id is null; #加载增量数据(变更前)
insert into delta_account
select t1.cst_id,t1.bal,'A' as etl_flag from
(select * from src_account where date_id = '${job_date_id}') t1
left join
(select * from src_account where date_id = '${before_job_date_id}') t2
on t1.cst_id = t2.cst_id where t2.cst_id is not null
and t1.bal <> t2.bal; #加载增量数据(变更后)
insert into delta_account
select t1.cst_id,t2.bal,'B' as etl_flag from
(select * from src_account where date_id = '${job_date_id}') t1
left join
(select * from src_account where date_id = '${before_job_date_id}') t2
on t1.cst_id = t2.cst_id where t2.cst_id is not null
and t1.bal <> t2.bal; #1.重跑:删除已跑入数据
delete from ods_account where job_seq_id = '${job_date_id}'; #2.重跑:从历史表恢复数据
insert into ods_account(cst_id,bal,eff_date,end_date,job_seq_id)
select cst_id,bal,eff_date,end_date,job_seq_id from odshis_account
where new_job_seq_id = '${job_date_id}'; #3.重跑:删除已跑入历史数据
delete from odshis_account where new_job_seq_id = '${job_date_id}'; #4.备份数据到历史表
insert into odshis_account(cst_id,bal,eff_date,end_date,job_seq_id,new_job_seq_id)
select cst_id,bal,eff_date,end_date,job_seq_id,'${job_date_id}'
from ods_account t
where t.end_date='' and exists ( select 1 from delta_account s
where t.cst_id=s.cst_id ); #5.断链
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 ); #6.加链
insert into ods_account(cst_id,bal,eff_date,end_date,job_seq_id)
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'); #7.保持数据完整性
insert into ods_account (cst_id,bal,eff_date,end_date,job_seq_id)
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
where t.cst_id=s.cst_id)


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实现无限极分类的两种方式

    无限极分类说简单点就是一个类可以分成一个分子类,然后一个子类又可以分另一个子类这样无限分下去,就是好象windows可以新建一个文件夹,然后在这个文件夹里又可以建一个文件夹,PHP要实现无限极分类有两 ...

  2. 现身说法:面对DDoS攻击时该如何防御?

    上周,我们的网站遭到了一次DDoS攻击.虽然我对DDoS的防御还是比较了解,但是真正遇到时依然打了我个措手不及.DDoS防御是一件比较繁琐的事,面对各种不同类型的攻击,防御方式也不尽相同.对于攻击来的 ...

  3. Laravel 中 Controller访问Model函数/常量

    <?php // User.php class User extends Model { ; //进行中 const USER_TYPE_TEST = 'test'; //测试用户 // 需要在 ...

  4. horizon服务

    一.horizon 介绍: 理解 horizon Horizon 为 Openstack 提供一个 WEB 前端的管理界面 (UI 服务 )通过 Horizone 所提供的 DashBoard 服务 ...

  5. 020-zabbix修改主机名为中文名

    我这边zabbix版本有2.4和3的都有. 要让zabbix主机名支持中文,,需要修改zabbix的php代码文件,如下图修改完中文主机名是不支持的: 实现步骤: 进到zabbix web目录,一般在 ...

  6. iotop发现jdb2/sdb1-8 io使用过高解决办法

    一.现象 [root@push-- ~]# iotop otal DISK READ: 0.00 B/s | Total DISK WRITE: 6.26 M/s TID PRIO USER DISK ...

  7. EFCore, 输出执行的Sql语句到控制台或者调试窗口

    .net core 已经集成的各种日志功能,使用efcore时,只需要按情况引入相应的包即可,如果你用的是.net core调试,那么可以引入 Microsoft.Extensions.Logging ...

  8. zencart批量表上传后 标题显示为网址 批量修改标题状态 SEO三要素

    zencart批量表上传后 标题显示为网址,原因是导入批量表时,产品标题对应状态被重置为0导致的 批量修改标题状态 ', metatags_products_name_status ', metata ...

  9. RSA前端加密

    昨天做了登陆模块,接触了md5&RSA加密.有点意思,talk is cheap,show me the code! 前端加密 为什么要加密 前端加密的方式 后台如何解密 1 为什么要加密? ...

  10. P5018 对称二叉树题解

    题目内容链接: 那么根据题意,上图不是对称二叉树,只有节点7的子树是: 通俗来说,对称二叉树就是已一个节点x为根的子树有穿过x点的对称轴并且对称轴两边的对称点的大小也必须相等,那么这棵树就是对称二叉树 ...