前言

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、是否有监控系统。

ETL需求要求的更多相关文章

  1. 如何在 ETL 项目中统一管理上百个 SSIS 包的日志和包配置框架

    一直准备写这么一篇有关 SSIS 日志系统的文章,但是发现很难一次写的很完整.因为这篇文章的内容可扩展的性太强,每多扩展一部分就意味着需要更多代码,示例和理论支撑.因此,我选择我觉得比较通用的 LOG ...

  2. 系统设计与架构笔记:ETL工具开发和设计的建议

    最近项目组里想做一个ETL数据抽取工具,这是一个研发项目,但是感觉公司并不是特别重视,不重视不是代表它不重要,而是可能不会对这个项目要求太高,能满足我们公司的小需求就行,想从这个项目里衍生出更多的东西 ...

  3. Kettle进行数据迁移(ETL)

    由于开发新的系统,需要将之前一个老的C/S应用的数据按照新的数据设计导入到新库中.此过程可能涉及到表结构不一致.大数据量(千万级,甚至上亿)等情况,包括异构数据的抽取.清洗等等工作.部分复杂的工作需要 ...

  4. [转载] 使用Kettle进行数据迁移(ETL)

    由于开发新的系统,需要将之前一个老的C/S应用的数据按照新的数据设计导入到新库中.此过程可能涉及到表结构不一致.大数据量(千万级,甚至上亿)等情况,包括异构数据的抽取.清洗等等工作.部分复杂的工作需要 ...

  5. Hive原理总结(完整版)

    目录 课程大纲(HIVE增强) 3 1. Hive基本概念 4 1.1 Hive简介 4 1.1.1 什么是Hive 4 1.1.2 为什么使用Hive 4 1.1.3 Hive的特点 4 1.2 H ...

  6. KETTLE监控

    kettle单实例环境下自身没有监控工具,但在集群下自带了监控工具. 一.集群自带的监控 kettle自带的集群监控工具可以监控转换的执行情况. 配置好集群后,打开浏览器:输入http://local ...

  7. kettle-学习参考

    一      关于Kettle Kettle是一款国外开源的ETL工具,纯java编写,数据抽取高效稳定的数据迁移工具.Kettle中有两种脚本文件,transformation和job,transf ...

  8. 管理SSIS 日志

    转自:http://www.cnblogs.com/biwork/p/biworklog.html 一直准备写这么一篇有关 SSIS 日志系统的文章,但是发现很难一次写的很完整.因为这篇文章的内容可扩 ...

  9. 深度介绍Flink在字节跳动数据流的实践

    本文是字节跳动数据平台开发套件团队在1月9日Flink Forward Asia 2021: Flink Forward 峰会上的演讲分享,将着重分享Flink在字节跳动数据流的实践. 字节跳动数据流 ...

随机推荐

  1. PV操作的概念

    PV操作:一种实现进程互斥与同步的有效方法,包含P操作与V操作. P操作:使 S=S-1 ,若 S>=0 ,则该进程继续执行,否则排入等待队列. V操作:使 S=S+1 ,若 S>0 ,唤 ...

  2. phpstorm之"Can not run PHP Code Sniffer"

    前言 其实我是不太愿意写这种工具使用博客的,因为实在没有营养,只是有些简单问题,搜索一番,却始终找不到答案,遂以博客记录下来,希望后面的人,可以省去搜索之苦. 相信你搜到这篇博客,肯定是已经安装好了P ...

  3. linux 操作目录

    脚本 获取一个目录下各子目录中的文件个数 #!/bin/sh find /tmp/homework -maxdepth 1 -type d | while read dir; do count=$(f ...

  4. Swoole_process实现进程池的方法

    Swoole 的进程之间有两种通信方式,一种是消息队列(queue),另一种是管道(pipe),对swoole_process 的研究在swoole中显得尤为重要. 预备知识 IO多路复用 swool ...

  5. 「AGC023D」 Go Home

    「AGC023D」 Go Home 传送门 神题. 首先我们可以倒着考虑. 当车到达最后一栋楼的时候,车上一定只有到这栋楼的员工. 当车到达倒数第二栋楼的时候,车上一定只有到达剩下两栋楼的员工. 设这 ...

  6. python远程备份mysql并压缩

    import osimport timeimport tarfileimport zipfile'''mysqldumpUsage: mysqldump [OPTIONS] database [tab ...

  7. C语言:fopen

    fopen,传递文件名参数,w+选项读取用fread或fgets,其中fread是按字节读取,fgets每次读取一个字符串写入用fwrite或fputs或fprintf,fwrite按字节写入,fpu ...

  8. Fastjson使用示例及常见问题(九)

    一.介绍 1. 什么是fastjson? fastjson是阿里巴巴的开源JSON解析库,它可以解析JSON格式的字符串,支持将Java Bean序列化为JSON字符串,也可以从JSON字符串反序列化 ...

  9. kafka单机环境配置以及基本操作

    安装地址(已亲测有效):https://www.linuxidc.com/Linux/2019-03/157650.htm

  10. C++第四十篇 -- 研究一下Windows驱动开发(三)-- NT式驱动的基本结构

    对于NT式驱动来说,主要的函数是DriverEntry例程.卸载例程及各个IRP的派遣例程. 一.驱动加载过程与驱动入口函数(DriverEntry) 和编写普通应用程序一样,驱动程序有个入口函数,也 ...