拉链表(一)
拉链表(二)

一、前言

在上一节简单介绍了拉链表,本节主要讲解如何通过binlog采集MySQL的数据并且按月分区的方式实现拉链表。

这里以上节介绍的用户表(user) 举例

二、涉及到的表

1. 原始表(user)

原始表指的是MySQL中的表,表结构如下:

其中name为主键,如果没有主键则无法做拉链表。

2. binlog流水表(user_binlog)

操作类型字段枚举值为:insert、update、delete。

设置binlog时间 的目的是防止业务方没有设置modify_time导致获取不到最新的更新时间,所以增加binlog时间。

日期分区字段是从binlog_time计算得来,作为分区字段

3. 拉链表(user_link)

这里包含的字段除去原始表的字段增加了生效日期失效日期具体作用已经在上一节介绍过,这里就不再赘述。

4. 临时表(user_link_tmp)

这张表的用途是: 在数据从user_binlog写入user_link时,临时表起到中转的作用。并且临时表没有分区。

三、计算流程

1. 整体数据流向

2. user到user_binlog

数据从user表到user_binlog表可以采用开源的采集binlog工具实时写入。具体的实施方案和选择的开源工具有关,这里不详细介绍。

3. user_binlog到user_link

(1) 常规流程

把数据从binlog表同步到拉链表中主要分两步:

  • 删除拉链表中失效的数据: 这里包括update和delete类型的数据,都涉及到删除原始拉链表的数据。在这一步骤中有两个子步骤

    • 将拉链表中失效的失效日期字段改为批次日期
    • 从拉链表原有分区中删除失效的数据
  • 插入新的数据:这一步骤涉及到的操作类型包含insert和update

接下来会以7月11日执行的SQL举例,详细介绍如何把binlog表的数据同步到拉链表中。其中的SQL涉及到先把binlog表中的数据同步到临时表,并把临时表写入到拉链表。

-- 先清空临时表的数据。
-- 理论上这张表已经是清空的。
-- 这里清空主要是防止异常清空,导致上一批次没有清空临时表
truncate table user_link_tmp;-- 将拉链表中需要改为失效的数据的失效时间改为'2019-07-10',并把数据写入到临时表中
-- 其中start_date>='2019-07-01'是因为7月1日之前未失效的数据会写入到开始时间为7月1日的分区中,
-- 所以查开始分区只要查当月的即可
-- 结束分区用end_date>'2019-07-09'而不用end_date='9999-12-31'是防止历史数据重跑时前一中写法不会有问题,而第二种写法只有在正常逻辑中没有问题。
insert into table user_link_tmp
select name,phone,sing_up_date,modify_time,start_date,'2019-07-10' as end_date
from user_link
where start_date<='2019-07-09'
and start_date>='2019-07-01'
and end_date>'2019-07-09'
and name in
(select name from user_binlog where day_num='2019-07-10' and type in ('update','delete') group by name
);-- 将原始拉链表中未失效的数据原样写入到临时表中
-- 此步骤的目的是从原有分区中删除失效的数据
-- 即在把临时表的数据覆盖到拉链表中时会把失效的数据从原有未失效分区中删除。
insert into table user_link_tmp
select name,phone,sing_up_date,modify_time,start_date,end_date
from user_link
where start_date<='2019-07-09'
and start_date>='2019-07-01'
and end_date>'2019-07-09'
and name not in
(select name from user_binlog where day_num='2019-07-10' and type in ('update','delete') group by name
);-- 将新增的数据写入到临时表中。
-- 并且开始时间为当前批次日期,结束日期为最大日期
insert into table user_link_tmp
select a.name,a.phone,a.sing_up_date,a.modify_time,'2019-07-10' as start_date,'9999-12-31' as end_date
from
(select name,phone,sing_up_date,modify_time,binlog_timefrom user_binlogwhere day_num='2019-07-10'
) a
right join
(select name,max(binlog_time)from user_binlogwhere day_num='2019-07-10'and type in ('insert','update') group by name
) b
on a.name=b.name
and a.binlog_time=b.binlog_time
;-- 将临时表中的数据覆盖到拉链表中。
insert overwrite table user_link partition(start_date)
select name,phone,sing_up_date,modify_time,start_date,end_date
from user_link_tmp;-- 删除临时表中的数据
truncate table user_link_tmp;

(2) 月初流程

在每个月月初会涉及到把上月还未失效的数据写入到开始时间为当月1日失效日期为9999-12-31的分区中,并把原始数据的失效日期改为上月末的逻辑。

接下来会以7月2日执行的SQL为例,来展示7月1日的数据是如何同步的。

truncate table user_link_tmp;-- 把拉链表所有6月30日未失效的数据失效日期改为7月1日
insert into table user_link_tmp;
select name,phone,sing_up_date,modify_time,start_date,'2019-07-01' as end_dat
from user_link
where start_date<='2019-06-30'
and start_date>='2019-06-01'
and end_date>'2019-06-30'-- 把7月1日依然为失效的数据的开始日期改为7月1日失效日期改为9999-12-31
insert into table user_link_tmp
select name,phone,sing_up_date,modify_time,'2019-07-01' as start_date,'9999-12-31' as end_date
from user_link
where start_date<='2019-06-30'
and start_date>='2019-06-01'
and end_date>'2019-06-30'
and name not in
(select name from user_binlog where day_num='2019-07-01' and type in ('update','delete') group by name
);-- 把7月1日新的数据写入到临时表中
insert into table user_link_tmp
select a.name,a.phone,a.sing_up_date,a.modify_time,'2019-07-01' as start_date,'9999-12-31' as end_date
from
(select name,phone,sing_up_date,modify_time,binlog_timefrom user_binlogwhere day_num='2019-07-01'
) a
right join
(select name,max(binlog_time)from user_binlogwhere day_num='2019-07-10'and type in ('insert','update') group by name
) b
on a.name=b.name
and a.binlog_time=b.binlog_time-- 将临时表中的数据覆盖到拉链表中。
insert overwrite table user_link partition(start_date)
select name,phone,sing_up_date,modify_time,start_date,end_date
from user_link_tmp;-- 删除临时表中的数据
truncate table user_link_tmp;-- 删除6月份所有结束时间为9999-12-31分区的数据
alter table user_link_tmp drop if exists partition(stat_date>='2019-06-01' , start_date<'2019-07-01', end_date='9999-12-31' );

(3) 数据重跑

如果某个日期同步的数据出现问题需要重跑数据,则需要重跑从当日的同步SQL到当前日期所有的SQL才能保证数据准确。

三、总结

至此,拉链表的同步过程就结束了。总体将拉链表的同步对资源消耗还是蛮多的。

注意:本文的实现还有需要考虑不周的地方,在应用的时候需要根据自己的需求进行优化。

update 两个表关联_拉链表(二)相关推荐

  1. update 两个表关联_你真的了解全量表,增量表及拉链表吗?

    1 Mysql数据准备 第一天 9月10号数据 1,待支付,2020-09-10 12:20:11,2020-09-10 12:20:112,待支付,2020-09-10 14:20:11,2020- ...

  2. mysql 两张大表关联_详解mysql生产环境如何快速有效的删除大表,附实验说明

    概述 我们很多时候都会去drop一些大表,特别是生产环境做操作时,这里主要提一些注意事项,仅供参考. 01 相关语法 1.删表 DROP TABLE SyntaxDROP [TEMPORARY] TA ...

  3. 2清空所有表_拉链表(二)

    拉链表(一) 拉链表(二) 一.前言 在上一节简单介绍了拉链表,本节主要讲解如何通过binlog采集MySQL的数据并且按月分区的方式实现拉链表. 这里以上节介绍的用户表(user) 举例 二.涉及到 ...

  4. MySQL 两张表关联更新(用一个表的数据更新另一个表的数据)两个表使用条件从另外一个表获取数据更新本表

    MySQL 两张表关联更新(用一个表的数据更新另一个表的数据)两个表使用条件从另外一个表获取数据更新本表 有两张表,info1, info2 . info1: info2: 方式一:要用info2中的 ...

  5. excel 查询 表关联_从Excel查询表获取里程

    excel 查询 表关联 There is a new sample file on my website, in response to a lookup question that someone ...

  6. mysql两张表关联修改

    mysql两张表关联修改 两张表的字段code是相同的,然后code作为关联参数来关联两表,将user2 中的name写入到user1 的name中,三表,四表,多表都是一个道理 UPDATE use ...

  7. 如何两张表关联查询?

    如何两张表关联查询select * from table1 a,table2 b where a.id = b.lid === select a.anme, b.bname, c.value from ...

  8. sql怎么两个表关联查询

    在 SQL 中,我们可以使用 JOIN 关键字来两个表关联查询.例如,假设有两个表:table1 和 table2,并且它们之间有一个关联字段 field1.你可以使用如下的语句来两个表关联查询: S ...

  9. 单张表超过30个字段_拉链表

    为什么要做拉链表 拉链表适合于:数据会发生新增和变化,但是大部分是不变的,且是缓慢变化的(如电商中用户信息表中的手机号不可能每天都变化),如果是快速变化的(如每天一变),则每天做全量更新(事务型事实表 ...

最新文章

  1. tensorflow 添加官方代码--以leaky_relu为例
  2. 机器学习-数据科学库(第二天)
  3. 实战SSM_O2O商铺_04自下而上逐步整合SSM
  4. 【Dynamics AX 6】axmodel新特性
  5. fc-ae-1553_什么是AE-L,AF-L和*按钮,它们的作用是什么?
  6. (JAVA)Object类之toString()和equals()
  7. 计算机文本专业,15计算机专业2文字录入期中考试卷
  8. Atitit 登录模块常见的安全措施条例与攻击行为表 目录 1. 安全目标 1 2. 常见安全措施 2 2.1. 修改密码需要验证员密码 2 2.2. 密码Salt加盐机制 2 2.3. Sql防注
  9. ArcGIS+Fragstats软件进行景观格局指数分析(附练习数据下载)
  10. 科技爱好者周刊(第 124 期):华为如何考核员工
  11. 虚拟机游戏服务器更新物品,【青云志】虚拟机镜像一键服务端+全物品ID配套客户端+图文架设教程+GM工具...
  12. sendto()函数
  13. Windows10输入法变成繁体怎么办?
  14. 35岁逃离北上广,40岁失业送外卖,中年人的“体面”在于投资自己
  15. 基于NanoPi3(三星S5P6818)的u-boot移植(一)
  16. 为什么科技互联网公司越来越重视数学?
  17. tic tac toe php,Python函数找出tic tac toe获胜者
  18. 半桥llc 增益 matlab程序,半桥LLC谐振设计多路输出辅助电源
  19. 已有一个排好序的数组,由键盘输入一个数,要求按原来的排序规律将其插入到数组中.
  20. 数据可视化UI设计素材资源文件sketch大屏可视化数据展示

热门文章

  1. SD-WAN如何安装在企业WAN中?—Vecloud
  2. Princess Principal(思维题)
  3. Excel获得焦点变色
  4. .net平台的rabbitmq使用封装
  5. NSTimer循环引用的问题
  6. spring mvc 文件上传 form表单
  7. C语言 03-第一个C程序代码分析
  8. Java 学习 swing 应该学习到什么程度?
  9. 超级简单的权限类[结合CI和DWZ]
  10. Windows系统C语言获取文件夹来的所有文件名的方法