ETL过程中的主要环节就是数据抽取、数据转换和加工、数据装载。
1.1 从数据库中抽取数据的方式:
1.1.1 全量抽取
全量抽取类似于数据迁移或数据复制,它将数据源中的表或视图的数据原封不动的从数据库中抽取出来,并转换成自己的ETL工具可以识别的格式。
全量抽取比较简单。
1.1.2 增量抽取
增量抽取只抽取自上次抽取以来数据库中要抽取的表中新增或修改的数据。
在ETL使用过程中,增量抽取较全量抽取应用更广,如何捕获变化的数据是增量抽取的关键。
对捕获方法一般有两点要求:
- 准确性,能够将业务系统中的变化数据按一定的频率准确地捕获到;
- 性能,不能对业务系统造成太大的压力,影响现有业务。
1.2 手工开发抽取作业时候的常用方法:
1.2.1 当数据源和DW为同一类数据库时
一般情况下,DBMS(SQLServer、Oracle)都会提供数据库链接功能,可以在数据源(业务系统)和DW内建立数据库链接(如DB2的联邦数据库NICKNAME),然后在DW内直接SELECT访问。
- 优点是实现使用简单,逻辑简单;
- 缺点是容易被滥用对源数据库造成较大的负载压力。
1.2.2 当数据源和ODS为不同类型数据库时
- 将源数据库的数据导出为文本文件,利用FTP协议进行传输导入ODS区域。
- 优点是实现简单,对源系统压力较小。
- 缺点是传输步骤增加了,处理需要的时间增加。
- 将部分数据库间能通过ODBC建立源数据库和目标数据库链接,此时也能直接使用SELECT获取数据。
- 优点是实现使用简单,逻辑简单;
- 缺点是容易被滥用对源数据库造成较大的负载压力,且建立时较为复杂。
2.1 数据清洗
任务是过滤不符合条件或者错误的数据。
这一步常常出现在刚刚开始建立数据仓库或者源业务系统仍未成熟的时候,此时发现错误数据需要联系源业务系统进行更正,部分可预期的空值或者测试用数据可以过滤掉。
2.2 数据转换和加工
这一步是整个ETL流程中最为占用时间和资源的一步。
数据转换包含了简单的数据不一致转换,数据粒度转换和耗时的数据关联整合或拆分动作。
这里可能存在各种各样千奇百怪的需求。
对于核心数据仓库来说,里面往往是对数据进行按照主题划分合并的动作。
同时,也会添加一些为了提升执行效率而进行反范式化添加的冗余字段。
数据的转换和加工可以在ETL引擎中进行,也可以在数据抽取过程中利用关系数据库的特性同时进行。
根据实现方式的不同,可以区分为使用数据库存储过程转换和使用高级语言转换
2.2.1 ETL引擎中的数据转换和加工
ETL引擎中一般以组件化的方式实现数据转换。
常用的数据转换组件有字段映射、数据过滤、数据清洗、数据替换、数据计算、数据验证、数据加解密、数据合并、数据拆分等。
2.2.2 在数据库中进行数据加工
关系数据库本身已经提供了强大的SQL、函数来支持数据的加工,如在SQL查询语句中添加where条件进行过滤,查询中重命名字段名与目的表进行映射,substr函数,case条件判断等等。
下面是一个SQL查询的例子。
select ID as USERID, substr(TITLE, 1, 20) as TITLE, case when REMARK is null then ' ' else REMARK end as CONTENT from TB_REMARK where ID > 100;
2.2.3 使用数据库存储过程转换
使用SQL开发存储过程完成转换作业是很多银行常用的方法。
- 优点是开发简单、能支持绝大部分转换场景;
- 缺点在于占用资源多且受制于单一数据库性能,无法做到横向扩展。
因此,除了业务的理解能力外,对SQL海量数据处理的优化能力在此也非常重要。
比如:
- 利用数据库的分区性,选择良好的分区键。
- 建表时合理选择主键和索引,关联时候必须使用主键或索引进行关联。
- 关注数据库对SQL的流程优化逻辑,尽量选择拆分复杂SQL,引导数据库根据你选择流程进行数据处理
- 合理反范式化设计表,留出适当的冗余字段,减少关联动作。
2.2.4 使用高级语言转换
使用高级语言包含了常用的开发C/C++/JAVA等程序对抽取的数据进行预处理。
3. 加载作业
将转换和加工后的数据装载到目的库中通常是ETL过程的最后步骤。
转换作业生成的数据有可能直接插入目标数据库,一般来说,这种情况常见于使用数据库存储过程进行转换作业的方案。
装载数据的最佳方法取决于所执行操作的类型以及需要装入多少数据。当目的库是关系数据库时,一般来说有两种装载方式:
- 直接SQL语句进行insert、update、delete操作。
- 采用批量装载方法,如bcp、bulk、关系数据库特有的批量装载工具或api。