ETL工具箱3 抽取(3.3抽取变化数据)
初始化加载数据,捕获源数据中的数据内容的变化不重要。但是加载完成后,捕获源系统中的数据变化立即变成非常重要的任务。要提前规划这个任务。
必须制定相应的策略来在项目中捕获源数据中不断增长的变化。
几种捕获源数据变化的方法:
使用审计列:审计列示附在每个表的最后用来存储记录增加或者修改的日期或者时间,审计列一般通过数据库触发器产生,当插入或更新记录的时候自动生成(有时候为了提升性能,这些列由前端产生)。确认审计列是可靠的,则需要制定策略来利用他们,比如:比较每个记录最后修改的日期和时间与上次加载后的最后的日期和时间,取他们中较晚的值。
由于事实表和维表可以来源于许多不同的表和系统,并且由于事实表只包含外建和度量值,因此不能直接存储审计日期列到事实表中。如果事实表需要对行数进行审计统计,可以考虑建立一个审计维。
数据库日志的获取和提取:对数据库重做日志进行有效的快照并把它作为对ETL加载过程中所关心的表产生影响的数据源。
按时抽取:选择所有创建或者修改的日期等于昨天的日期,获取昨天记录,看起来对,实际不对,这种处理方式及其不可靠。比如中间处理失败,会需要重新加载重复的行,然后需要人工干预和数据清洗,万一有一天没有记载,那么就出问题。除非ETL处理非常简单而且数据量小,否则不要单纯的基于时间加载数据。
排出处理:排除处理在集结区保存了每个上次导出数据副本作为将来所用。在下一次运行过程中,整个源表被拿到集结区与最后一次处理留下的数据副本进行比较,只有增量部分会进行处理,送到数据仓库。
初始增量和更改:创建两个表,增加,删除,减去等
抽取时候的 技巧:
1 强制列索引,确保where语句中的列都有索引,否则可能引起对整个生产数据库的全表扫描
2获取需要的数据
3谨慎使用distinct ,distinct语句太慢,在抽取查询中执行distinct和在etl工具中对结果进行聚合或分组两种方式如何平衡是一个挑战,一般会随着数据源中重复百分比的不同而不同。
4谨慎使用set 操作。 Union,Minus,Intersect都是set操作符,这些和distinct一眼都很慢。
5 根据需要使用HINT。尤其当使用IN或者OR操作符时候这个功能尤其重要,因为这个时候往往会进行全表扫描而不是使用索引,即使有可用的索引存在
6 避免使用not。如果可能,尽量避免不等于的限制和连接,无论使用关键字NOT还是操作符 “<>”,数据库此时也会选择扫描整个表而不是利用索引。
7 避免where中使用函数,无论如何尽量尝试使用比较关键字而不是函数。比如:like'%J' 而不是 substr('last_name',1,1)='J'
检测数据源中删除或者覆盖的事实记录
如果没有删除或者覆盖事件发生的通知机制,对于源系统中删除或覆盖的度量记录如何发现可能会给数据仓库带来大的挑战。
1 和源系统的所有者商讨,如果可能,明确地通知所有的删除或者覆盖的度量
2 周期性的检查来自源系统的历史汇总数据并通知ETL人员内容变化,当发现变化的时候,尽可能的钻取下去找到这个变化。