目录
数据增量类型介绍
三种增量类型的具体介绍
流水新增数据
常规业务变化数据
优化的业务变化数据
总结
数仓中增量数据的方法探讨
先做个数据例子
1月份
2月份
3月份
4月份
数仓分层
生产数据同步到ODS层
1月份ODS层表
2月份ODS层表
3月份ODS层表
4月份ODS层表
ODS→STD→DWD
方案一
方案二
方案三
业务生产库中的数据增量情况有如下几种:
无修改删除(类似日志流水数据)
流水新增数据,只有insert。所以历史数据是不会修改的,数据只会增加。
譬如:
1月底,统计的今年(全年)商品销售情况:
ID |
商品 |
销量 |
---|---|---|
1 | 上衣 | 100 |
2 | 裤子 | 100 |
2月底,统计的今年(全年)商品销售情况:
ID |
商品 |
销量 |
---|---|---|
1 | 上衣 | 100 |
2 | 裤子 | 100 |
3 | 裤子 | 50 |
2月底,统计的今年(全年)商品销售情况:
ID |
商品 |
销量 |
---|---|---|
1 | 上衣 | 100 |
2 | 裤子 | 100 |
3 | 裤子 | 50 |
4 | 裤子 | 30 |
只有新增数据,没有修改或者删除的数据。
含增删改(类似商品库存信息),譬如:
我们拿个公司职员工资单的例子,体会下增量数据的变化。
1月公司的职员工资单如下:
唯一ID |
姓名 |
收入 |
---|---|---|
1 | 张三 | 300 |
2 | 李四 | 350 |
2月公司的职员工资单如下(insert,新聘用1名员工):
唯一ID |
姓名 |
收入 |
---|---|---|
1 | 张三 | 300 |
2 | 李四 | 350 |
3 | 王五 | 360 |
3月公司的职员工资单如下(update,2名员工涨薪):
唯一ID |
姓名 |
收入 |
---|---|---|
1 | 张三 | 400 |
2 | 李四 | 450 |
3 | 王五 | 360 |
4月公司的职员工资单如下(delete,1名员工离职):
唯一ID |
姓名 |
收入 |
---|---|---|
1 | 张三 | 400 |
3 | 王五 | 360 |
数据变化,直接在原数据上变化,只能通过捕获数据变化日志,或者通过触发器等方法感知数据变化情况。
含增删改动作,以流水记账方式体现,我们仍然用上面公司职员工资单的例子。
1月公司的职员工资单如下:
唯一ID |
姓名 |
收入 |
动作 |
时间 |
---|---|---|---|---|
1 | 张三 | 300 | insert | 1月 |
2 | 李四 | 350 | insert | 1月 |
2月公司的职员工资单如下(insert,新聘用1名员工):
唯一ID |
姓名 |
收入 |
动作 |
时间 |
---|---|---|---|---|
1 | 张三 | 300 | insert | 1月 |
2 | 李四 | 350 | insert | 1月 |
3 | 王五 | 360 | insert | 2月 |
3月公司的职员工资单如下(update,2名员工涨薪):
唯一ID |
姓名 |
收入 |
动作 |
时间 |
---|---|---|---|---|
1 | 张三 | 300 | insert | 1月 |
2 | 李四 | 350 | insert | 1月 |
3 | 王五 | 360 | insert | 2月 |
4 | 张三 | 400 | update | 3月 |
5 | 李四 | 450 | update | 3月 |
4月公司的职员工资单如下(delete,1名员工离职):
唯一ID |
姓名 |
收入 |
动作 |
时间 |
---|---|---|---|---|
1 | 张三 | 300 | insert | 1月 |
2 | 李四 | 350 | insert | 1月 |
3 | 王五 | 360 | insert | 2月 |
4 | 张三 | 400 | update | 3月 |
5 | 李四 | 450 | update | 3月 |
6 | 李四 | 450 | delete | 4月 |
其实生产环境中,见到的最多的是第二种情况。生产库正常使用,该删就删,该改就改。
为了方便后面讨论,我们先做一个数据例子。
生产库中有下面2张表:
职员信息表:
工号 |
姓名 |
手机号 |
---|---|---|
E01 | 张三 | 123 |
E02 | 李四 | 124 |
职员工资表:
工号 |
姓名 |
工资 |
---|---|---|
E01 | 张三 | 300 |
E02 | 李四 | 350 |
新聘用员工王五,工资360
职员信息表:
工号 |
姓名 |
手机号 |
---|---|---|
E01 | 张三 | 123 |
E02 | 李四 | 124 |
E03 | 王五 | 125 |
职员工资表:
工号 |
姓名 |
工资 |
---|---|---|
E01 | 张三 | 300 |
E02 | 李四 | 350 |
E03 | 王五 | 360 |
张三、李四涨工资,各涨100块;张三手机号码修改为223
职员信息表:
工号 |
姓名 |
手机号 |
---|---|---|
E01 | 张三 | 223 |
E02 | 李四 | 124 |
E03 | 王五 | 125 |
职员工资表:
工号 |
姓名 |
工资 |
---|---|---|
E01 | 张三 | 400 |
E02 | 李四 | 450 |
E03 | 王五 | 360 |
李四离职
职员信息表:
工号 |
姓名 |
手机号 |
---|---|---|
E01 | 张三 | 223 |
E03 | 王五 | 125 |
职员工资表:
工号 |
姓名 |
工资 |
---|---|---|
E01 | 张三 | 400 |
E03 | 王五 | 360 |
数仓前几层一般包括:ODS、STD、DWD
ODS是原始数据汇集层,一般把生产库的数据同步过来即可(当然要有增量数据,增量方式后面有讨论)
STD是数据标准层,针对ODS的原始数据做些基础的清洗、标准化
DWD常做为数据描述层,通常对STD层的数据按照主题、或者大的业务分类,进行数据整合,常包括数据合并拆分(表合并、分类)、数据计算(简单的计算逻辑生成需要的数据)
数仓建设完成后,通过DWD层,对使用人员提供服务。使用人员可以通过DWD层进行业务专题库建设或者数据建模,进行数据轻度汇总再对外使用等等。
这里要声明下,这里使用的大数据底层平台是类似hadoop这种不支持update/delete的离线计算平台。如果是类似greenplum等支持修改操作的大数据平台,这一步就没什么讨论的了。
增量数据从生产库到大数据仓库ODS层,会面临一个问题:修改/删除的数据,如何处理?
最直接的做法:ETL工具在感知生产库数据变化后,将数据的动作(insert/update/delete)新增一列,显示地存储进离线计算平台。
用上面的例子,我们看下在离线计算平台上,各个月份数据会长什么样子(会比生产库多2列:操作类型、操作时间):
职员信息表:
工号 |
姓名 |
手机号 |
操作类型 |
操作时间 |
---|---|---|---|---|
E01 | 张三 | 123 | insert | 2018年1月15日 |
E02 | 李四 | 124 | insert | 2018年1月15日 |
职员工资表:
工号 |
姓名 |
工资 |
操作类型 |
操作时间 |
---|---|---|---|---|
E01 | 张三 | 300 | insert | 2018年1月15日 |
E02 | 李四 | 350 | insert | 2018年1月15日 |
新聘用员工王五,工资360
职员信息表:
工号 |
姓名 |
手机号 |
操作类型 |
操作时间 |
---|---|---|---|---|
E01 | 张三 | 123 | insert | 2018年1月15日 |
E02 | 李四 | 124 | insert | 2018年1月15日 |
E03 | 王五 | 125 | insert | 2018年2月15日 |
职员工资表:
工号 |
姓名 |
工资 |
操作类型 |
操作时间 |
---|---|---|---|---|
E01 | 张三 | 300 | insert | 2018年1月15日 |
E02 | 李四 | 350 | insert | 2018年1月15日 |
E03 | 王五 | 360 | insert | 2018年2月15日 |
张三、李四涨工资,各涨100块;张三手机号码修改为223
职员信息表:
工号 |
姓名 |
手机号 |
操作类型 |
操作时间 |
---|---|---|---|---|
E01 | 张三 | 123 | insert | 2018年1月15日 |
E02 | 李四 | 124 | insert | 2018年1月15日 |
E03 | 王五 | 125 | insert | 2018年2月15日 |
E01 | 张三 | 223 | update | 2018年3月15日 |
职员工资表:
工号 |
姓名 |
工资 |
操作类型 |
操作时间 |
---|---|---|---|---|
E01 | 张三 | 300 | insert | 2018年1月15日 |
E02 | 李四 | 350 | insert | 2018年1月15日 |
E03 | 王五 | 360 | insert | 2018年2月15日 |
E01 | 张三 | 400 | update | 2018年3月15日 |
E02 | 李四 | 450 | update | 2018年3月15日 |
李四离职
职员信息表:
工号 |
姓名 |
手机号 |
操作类型 |
操作时间 |
---|---|---|---|---|
E01 | 张三 | 123 | insert | 2018年1月15日 |
E02 | 李四 | 124 | insert | 2018年1月15日 |
E03 | 王五 | 125 | insert | 2018年2月15日 |
E01 | 张三 | 223 | update | 2018年3月15日 |
E02 | 李四 | 124 | delete | 2018年4月15日 |
职员工资表:
工号 |
姓名 |
工资 |
操作类型 |
操作时间 |
---|---|---|---|---|
E01 | 张三 | 300 | insert | 2018年1月15日 |
E02 | 李四 | 350 | insert | 2018年1月15日 |
E03 | 王五 | 360 | insert | 2018年2月15日 |
E01 | 张三 | 400 | update | 2018年3月15日 |
E02 | 李四 | 450 | update | 2018年3月15日 |
E02 | 李四 | 450 | delete | 2018年4月15日 |
我习惯将ods的第一层叫历史数据表,包含数据历史上各次变化情况。
结果数据表,是对相同数据历史上多次变化信息进行合并,得到一个最新值,存储得到的表。
对于生产库有增量数据且ETL能够感知这些增量动作的,ODS层的历史数据表就是“生产数据同步到ODS层”里面展示的表的样子。对于生产库只有“流水新增数据”,或者ETL工具不强(无法感知增量,每日把生产库全量数据同步一次)的情况,ODS层的历史数据表其实就是结果数据表。
数据应用的时候,结果数据表是最常用的,历史数据表只有在用到“数据变化信息”的时候才有价值。
历史数据表,会再造成“流水表”、“拉链表”等形式,展示数据变化信息的价值。
目前ODS层的数据,保留了所有生产库的数据变化信息,但同时,这个表也是无法直接使用的。
对于增量数据的合并动作(把1、2、3月的变化数据合并),在哪一层做,是有歧义的。这里有2种做法:
由于是DWD层对外提供服务,所以上述方案都不影响使用者。
在ODS层合并好。
到STD层合并好。
到DWD层合并好。