数据仓库中的ETL详细的分为四个阶段:提取,传输,转换,装载。我先简单的介绍一下提取和传输的分类和方法
一:提取
提取可以分为逻辑提取,和物理提取。
1:逻辑提取按照规模分为:完全提取,增量提取。
完全提取简单运用EXP或者全表扫描可以完成。
增量提取是提取相比上次提取增加了的数据,也可以是按照数据产生时间PATITION了的一个分区等等。Oracle‘s Change Data Capture 是ORACLE为增量提取提供的一个完备的机制。可以运用基于Timestamps,Partitioning,Triggers的增量提取。
2:物理提取又分为在线提取和离线提取。
在线提取是直接连接数据库,访问数据库的表,然后提取。
离线提取是指提取数据库以外的一些文件,比如Flat file,Dump file,Redo or Archive log.Transportable tablespaces。等等。
提取的方法很多。可以用sqlplus把数据提取到FLAT file中,也可以用exp,甚至可以直接用oracle net处理。比如
CREATE TABLE country_city AS SELECT distinct t1.country_name, t2.cust_city
FROM countries@source_db t1, customers@source_db t2
WHERE t1.country_id = t2.country_id
AND t1.country_name=‘United States of America‘;
所有提取不是ETL中困难的过程。
二:传输
通过FTP或者Transportable Tablespaces(建立一个临时的表空间用来存提取出来需要传输的数据,然后EXP这个表空间)
三:转换
转换的过程是ETL最复杂,处理时间最长的过程。这个过程涉及的ORACLE知识比较多。开发人员需要知道怎样选择最有效,最便捷的技术,我将在本文详细说明。
我理解的转化过程就是,通过若干个步骤来处理转化过程中需要处理的每一个问题,而这若干步骤是通过建立若干的临时表来完成的,后一个步骤建立的临时表是在前一个步骤建立的临时表的基础上建立起来的。这样一次一次的转化,最后得到转化的结果。
1:Transformation Flow
如果你自己涉及转化的过程,你会想到什么?首先明确,咱们的目的是什么,我们有一个STAGING表,我们是要把这个表的数据添加到DW的事实表中,但是不是简单的添加,这些数据需要按照SCHEMA DESIGN的要求,把所有和维表对应的描述信息分离到维表中。这是一步,第二,我们需要考虑事实表的主键和staging表的主键一定有冲突,因为他们不是同一个SEQUENCE生成的。第三步,就是INSERT到事实表。
Transformation Flow就是按照这样的逻辑来处理的。我们可以写PL/SQL实现整个功能。
以下这个SQL可以创建一个表,大家一看就能明白它的作用了
CREATE TABLE temp_sales_step2 NOLOGGING PARALLEL AS SELECT sales_transaction_id,
product.product_id sales_product_id, sales_customer_id, sales_time_id,
sales_channel_id, sales_quantity_sold, sales_dollar_amount
FROM temp_sales_step1, product
WHERE temp_sales_step1.product_name = product.product_name;
解释一下
一般,从数据源过来的staging表带有和维表某个字段相同或者相似的信息,比如说产品名称。我们就可以通过产品名称链接维表和 staging表,SQL中WHERE中的连接就是这样做的。然后就可以把在维表中的产品名称对应的产品ID找出来,标识成为要插入的事实表中的 sales_product_id。然后创建temp表把查询结果保存下来。这样就实现了和维的主外键对接。
这个过程会衍生出一个问题。如果product_name在product中没有,就需要吗?大部分情况可能答案是需要的。那就需要做一个验证操作。咱们看看以下的代码
CREATE TABLE temp_sales_step1_invalid NOLOGGING PARALLEL AS
SELECT * FROM temp_sales_step1 s
WHERE NOT EXISTS (SELECT 1 FROM product p WHERE p.product_name=s.product_name);
这个CTAS statement语句就可以把查询出的新的SALE记录。
咱们也可以做左链接
CREATE TABLE temp_sales_step2 NOLOGGING PARALLEL AS
SELECT sales_transaction_id, product.product_id sales_product_id,
sales_customer_id, sales_time_id, sales_channel_id, sales_quantity_sold,
sales_dollar_amount
FROM temp_sales_step1, product
WHERE temp_sales_step1.upc_code = product.upc_code (+);
把所有在维表中没有找到product_name的记录的sales_product_id设置为空。
