第四章:同步策略/存储方式
4.1 数据存储方式概述
首先弄清楚,增量同步,快照同步,增量表,全量表,拉链表之间的关系。
4.2 全量
全量表无分区,每天凌晨流程执行完后,表中的数据是截至到前一天的全部MySQL数据。全量表可能会update数据,即对某条历史数据进行更新,保存最新的那条数据,一般只包含一个文件。如果需要追溯历史数据,需要存快照表进行操作。当然对于某些业务流水数据库只会新增,不会删改,或者我们不太关注历史数据信息,存全量表也没有问题。
4.3 快照表
按天分区,分区字段为partition_date == yyyy-mm-dd.每一天的数据都是截至到那一天的MySQL的全量数据。
快照表对比全量表来说,快照表会有许多重复的数据,优点在于可以利用日期分区追溯历史数据动作。快照表如果根据日期分区创建一个文件,那么文件将会非常之多。
4.4 增量表
按天分区,分区字段为partition_date = yyyy-mm-dd.每一天的分区都会存放MySQL那一天新产生的增量数据(insert,update的数据),注意增量表的同步方式不会包含历史数据,即只存放增量数据。增量表多用于统计流量数据,因为流量数据每天就会产生千亿级别的数据。
4.5 拉链表
4.5.1 拉链表定义
拉链表按天分区,当数据量非常大的时候,表中有部分字段会更新,但更新频率不会很高,如果使用快照表,其每个分区都存储了许多重复信息,非常浪费内存空间,于是拉链表出来了,拉链表是一种保存历史状态信息不变,只更新最新消息。有些不变的数据或者已经达到状态终点的数据就会把它放在分区里面。分区字段一般为开始时间start_date和结束时间:end_date.一般在该天有效的数据,它的end_date是大于等于该天日期的。获取某一天全量的数据,可以通过表中的start_date和end_date来做筛选,选出固定某一天的数据。例如我想取截至到20190813的全量数据,其where过滤条件就是where start_date <=’20190813’ and end_date >= ‘20190813’.也就是说拉链表不会像快照表将每天不变的数据全部复制一遍到最新的分区中,而占据巨大的存储资源。
4.5.2 适用范围
用户信息表每日可能有新增,也可能发生变化,但是修改频率不高,属于缓慢变化维,所以适合拉链表.
拉链表缺点:
- 现有拉链表仅保留维表最新状态和拉链最新状态,如果拉链表出现错误,无法修复拉链生成的错误数据。
- 现有拉链操作中在插入拉链表数据的时候,会先删除最新分区数据,如果这个时候流程跑失败,没有办法恢复相关数据。
- 现有拉链表流程如果当天多次执行会生成错误数据,比如断链情况。
4.5.3 拉链表创建过程
- 初始化和新增数据
- 数据回滚:
在end_date < rollback_date 的数据要保留,对于处理end_date ≥ rollback_date ≥ start_date 设置end_date 为9999-12-31 ,对于回滚的结果,一般为了保持数据的完整性,可以将回滚的数据放在一个新的拉链临时表中
4.6 各同步方式比较
- 增量表不约束分区与全量表区别?
查询结果可能不一样,增量表只对应新增的数据,对于修改或者删除的没有记录。而全量或者快照表是有修改删除记录的。所以历史记录不一样。
- 三种表数据和分区的区别
全量 | 快照 | 增量 | |
数据 | 包含到前一天的全量数据 | 包含到前一天的全量数据 | 前一天的增量数据 |
分区 | 不分区 | 按照每一天进行分区 | 按照每一天分区 |
历史 | 历史数据可能被覆盖,无法适用 | 去历史的快照表可以找到历史数据 | 按照分区 |
- 经典样例
对于商品收获地址,我们不使用拉链表,这个时候建议采用快照表,得到用户当前的收获状态。
小汽车的状态,是骑行还是静止我们使用拉链表比较合适,对于处理缓慢变化维中新增维度行我们一般也使用拉链表解决。