前言

ETL落地dw层,dw层各表一般是由多个表关联取数得到的大宽表,在ETL需求中的dw设计应该考虑以下内容,目的是确保需求更清晰,开发和测试才能更高效的进行。

业务需求为基础

基于业务需求做足够多的业务分析,来自客户的整体业务需求、来自标签、人群、dashboard等具体的业务需求。

关联逻辑设计

关联设计,即表之间的join关系、join之后的过滤条件和取record的逻辑。

1、明确主表、依赖表;

2、明确表之间的join关系,即inner join、left join、right join,以及关联条件;

  • 需求中不应该出现模糊的join关系,必须说明是left、right or inner join。

3、主表和依赖表也可以是多个表join得到的;

4、明确join之后的过滤条件,如业务隔离、无效数据隔离、重复数据取一条;

3、明确所有关联关系中的取record的逻辑,即关联后全取or分组排序取top 1;

  • 两表关联时容易产生一个业务主键对应多条记录的问题,确认是否关联后全取;
  • 否则关联后分组排序取top1,确认分组和排序的条件;
  • 分析分组排序后取TOP1是否有不稳定的情况,如果有要么增加排序条件,要么接受不稳定的情况。

4、明确和统一常见的处理逻辑:

  • 字符串字段值对比时,明确是否区分大小写,如默认不区分大小写,特殊注明才区分;
  • 两字段值相等判断时,明确是否将NULL和空字符串做相等处理,具体有以下3点:
    • where条件里是否要将null转换成''执行;
    • join条件里是否要将null转换成''执行;
    • 这个逻辑保持跟其它应用一致;
    • 空字符串落地后是否转成null;
  • AB俩数值类型计算(如加减乘除等)、字符串类型关联时A或B为null会有如下结果,明确是否将null设置默认值后处理;
    • null = null,为null
    • 2 > null,为null
    • 2 + null,为null
    • 'abc' = null,为null

转换逻辑设计

转换设计,即每个字段取值逻辑设计。

1、如果有一些通用的取值逻辑,可以定义一些通用的UDF(User Defined Function);

  • 脏数据处理;
  • 业务隔离;
  • 字段类型转换和处理,遵循两个原则,即含脏数据处理逻辑、只能大转小,具体例子如
    • string类型转date和timestamp类型,if (yyyy-MM-dd HH:mm:ss字符串){转date类型或timestamp类型} else {null}
    • String类型转int类型,if (数值字符串&在int类型的取值范围){转int类型} else {null},注INT/INTEGER (4-byte signed integer, from -2,147,483,648 to 2,147,483,647);
    • int类型转bigint类型;
    • varchar类型转char类型;
    • 空字符串落地转null。(评估会有什么影响?)

2、不管是通用的还是非通用的取值逻辑,最优以伪代码的形式说明,如下:

  • if (){} else if (){} else {}
  • isnull(A,B,C)
  • modify columnName date

3、明确和统一常见的处理逻辑:

同关联逻辑设计。

4、其它

  • 明确关键字段的业务说明,如哪个字段是订单生成日期,哪个字段是订单变更日期;
  • 字段类型转换是否合适,如date(yyyy-MM-dd) 、timestamp(yyyy-MM-dd HH:mm:ss),尽量不转String类型;
  • 分析和评估各种数值类型的字段在业务上是否可能超过其范围,如INT/INTEGER (4-byte signed integer, from -2,147,483,648 to 2,147,483,647)。

更新策略设计

更新策略设计,即ETL动作将新生成的数据或者变化的任何数据更新到数据仓库的过程的设计。

1、相关定义和关系

表类型 定义
增量表 数据每次落地此表是其所对应业务的新增或更新的记录,如新增的订单信息和状态变更的订单,对应更新策略为全量更新
全量表 数据每次落地此表是其所对应业务的全部体量记录,如全部会员用户信息
更新策略 定义
增量更新 当目标表的类型为增量表,对应更新策略为增量更新
全量更新 当目标表的类型为全量表,对应更新策略为全量更新;
特殊:增量表在初始化数据或者relaod情况下也是全量更新

2、明确区分字段

明确源表和目标表中分区字段、哪些字段是为了更新策略设计的。

3、明确详细更新策略

结合业务分析确定更新策略,如所选的排序字段是否符合业务需求。

  • 源表类型是全量表还是增量表;
  • 每次更新取源数据的范围;
  • 目标表类型是全量表还是增量表;
  • 如何落地存储,是覆盖、追加还是更新;
更新策略 源表分类 源数据范围(一组数据源) 目标表分类 如何落地 备注
增量更新 增量表 源表新增记录 增量表 全部新分区存储 多用在数仓第一层,即无脑存储
增量更新 增量表 源表新增和变化的记录 增量表 新增主键记录新分区存储+旧分区更新 多用在数仓第二层及往后
增量更新 增量表 源表新增和变化的记录 增量表 全部新分区存储+旧分区删除
全量更新 增量表 源表全量记录,即该业务历史全量记录 全量表 历史记录全量清空,再落地
全量更新 增量表 源表全量记录,即该业务历史全量记录 全量表 新分区落地,旧分区保持不变
全量更新 全量表 源表全量记录 全量表 历史记录全量清空,再无分区落地 用在不关注历史变化的表中
全量更新 全量表 源表全量记录 全量表 新分区落地,旧分区保持不变 多用在数仓第一层,即保留了历史变化情况
全量更新 全量表 源表最新分区记录,即为该业务全量记录 全量表 历史记录全量清空,再无分区落地
全量更新 全量表 源表最新分区记录,即为该业务全量记录 全量表 新分区落地,旧分区保持不变 这种情况说明上下两层都将全量历史记录保存,比较浪费资源,所以不太会出现这样的场景
增量更新 全量表 源表最新分区记录对比次新分区记录,即该业务全量记录对比上次数据落地的全量记录,取其中变化的记录 增量表 新分区落地,旧分区保持不变 这种情况不太会用到
全量更新-表初始化/Reload 增量表 源表全量记录 增量表 历史记录全量清空,再按分区落地
全量更新-表初始化/Reload 增量表 源表全量记录 全量表 历史记录全量清空,再按分区落地
全量更新-表初始化/Reload 增量表 源表全量记录 全量表 历史记录全量清空,再按分区落地
全量更新-表初始化/Reload 全量表 源表全量记录 全量表 历史记录全量清空,再按分区落地
全量更新-表初始化/Reload 全量表 源表全量记录 全量表 历史记录全量清空,再按分区落地

注:

对于增量更新策略,需要注意评估实际数据的取数逻辑是否有TOP1不稳定的情况;

确定更新策略方案的前提下,明确目标表的数据源个数、落地顺序(子调度策略),上表的前提是源数据是固定一组;

关于“全量更新-表初始化/Reload”:

  • 数据仓库初始化也是一种全量更新的策略,即将历史全量数据迁移到数据仓库,后续再切换为定期全量更新或增量更新;
  • 表初始化更新策略不可能存在全量表到增量表的情况;
  • Reload,即根据更新策略分析重跑当前层ETL的方法,以及后续各层的Reload方法、Recalculate方法,如后续ETL重跑、Dashboard重跑、标签回算等;
  • 本质上数仓表初始化是一种特殊的Reload。

4、更新策略开发实现

增量更新
  • 捕捉变化的数据有如下几种:

    • 采用快照方式,需要业务系统建立insert,update,delete触发器;
    • 时间戳方式,在业务系统表建一个时间戳字段,一旦数据发生变化,则修改此字段;
    • 全表删除插入方式,每次ETL操作先将目标表数据删除,然后抽取;
    • hash比对,是全表比对的一个扩展,通过计算主要业务字段的MD5校验码存入hash维表,通过与hash维表的比对进行抽取;
    • 日志表方式,跟进业务系统的日志表进行数据抽取;
    • 数据库变化数据捕捉,通过分析数据库自身日志判断变化的数据;
  • 全表删除插入方式,设计1,

    • Step 1: 源数据进行关联、转换后插入目标表;
    • Step 2: 新建目标表的临时表;
    • Step 3: 在目标表上以KeyID字段组合分组,按目标表中落地的时间字段降序排,取TOP1落到临时表(此步骤要根据具体的业务设计);
    • Step 4: 删除目标表;
    • Step 5: 将临时表更改为正式目标表。
  • 全表删除插入方式,设计2,

    • Step 1: 多组源数据按顺序进行关联、转换后插入目标表;
    • Step 2: 新建目标表的临时表;
    • Step 3: 在目标表上以KeyID字段组合分组,按目标表中落地的时间字段降序排,取TOP1落到临时表(此步骤要根据具体的业务设计);
    • Step 4: 删除目标表;
    • Step 5: 将临时表更改为正式目标表。
  • 设计1与设计2的区别是设计1中只有一个数据源,设计2中数据会跨源覆盖。

5、明确更新周期

根据业务评估和定义更新周期

调度策略设计

调度策略设计,即对整个ETL过程中的各个子的处理过程根据依赖关系设计优先顺序。

1、明确调度的周期;

2、明确每次调度处理的数据边界,如今天ETL处理的是昨天的业务数据;

3、明确该次所要处理的数据是否稳定,如果不稳定是否有影响;

  • 如源数据按订单日期来切分处理的数据范围,即每天零点启动调度ETL处理订单日期是前一天的业务数据,但是当天零点之前订单可能延迟1个小时落到ETL的源数据层,即未取全所有的数据;

4、明确调度启动时间;

5、明确调度的周期,一般同更新周期;

6、一般采取条件驱动的策略来进行Job的调度,Job一满足驱动条件便开始运行,明确每个Job使用以下驱动条件中的哪一种:

  • 前导Job驱动,ETL过程中各个操作需按一定次序进行,前导Job表示ETL过程中先要进行处理的Job;
  • 下传文件驱动,当下传文件未下传完毕时,下传文件清洗不能进行,因此,下传文件通常作为清洗文件的驱动条件,当系统检测到下传文件已下传并正确后,便可进行相应的清洗;
  • 时间驱动,当到达某个时点时,Job便开始运行;
  • 上述三种条件综合驱动,要上述三种情况至少两种均满足,Job才能运行。

7、明确调度的每个驱动条件是否符合业务需求;

8、明确是否有调度监控,如果有测试的时候可用于参考;

9、明确测试的是自动调度过程,而非仅仅手动按调度策略执行的过程;

10、明确调度失败是否可能会导致脏数据、是否有重新调度等。

其他

1、明确是否有性能指标;

2、是否要考虑故障恢复的情况处理;

3、是否有监控系统。

最新文章

  1. 【干货分享】前端面试知识点锦集03(JavaScript篇)——附答案
  2. 导出 XE6 预设 Android Style (*.style) 档案
  3. 后台框架--HUI 的学习跟使用1
  4. BZOJ1037: [ZJOI2008]生日聚会Party
  5. Redis hash数据类型操作
  6. bootstrap3学习1:响应式布局layout
  7. SSH 服务启动时出现如下错误:fatal: Cannot bind any address
  8. iOS坐标转换
  9. swig模板 html代码自然状态下输出是转义的,必须加一个函数来转换为html代码;
  10. 玩转Web之Json(二)----jquery easy ui + Ajax +Json+SQL实现前后台数据交互
  11. (原创)我对未来的人类的发展,以及AI技术发展的一些思考。
  12. C语言之二分猜数字游戏
  13. python 爬取国家粮食局东北地区玉米收购价格监测信息
  14. offset / scroll / client Left / Top
  15. P2P技术详解(一):NAT详解——详细原理、P2P简介
  16. xml转json和实体类的两种方式
  17. html+css+javascript之间的关系与作用
  18. 第25月第4天 Blog-API-with-Django-Rest-Framework项目记录01
  19. 数据恢复Winhex的核心理念
  20. SQL语句汇总(二)——数据修改、数据查询

热门文章

  1. Linux:Ka li 2020.4 安装教程
  2. Linux:CentOS-7常用命令
  3. python之学生信息管理系统
  4. 【spring源码系列】之【Bean的初始化】
  5. 入门 - SpringBoot 2.x 使用 JWT
  6. ORB-SLAM3论文阅读:ORB-SLAM3: An Accurate Open-Source Library for Visual, Visual-Inertial and Multi-Map SLAM
  7. Linux中tomcat随服务器自启动的设置方法
  8. vue 使用 lang="scss" 报错
  9. 【阅读笔记】Java核心技术卷一 #2.Chapter4
  10. videojs踩过的坑