关于Informatica增量抽取时间戳的管理

目前在做的项目涉及到了增量抽取,就增量抽取时间戳的设定做点总结。
     
     项目中涉及到了OLTP库(DB2)、Informatica这方面建了三个库,分别为CDS、ODS、DW,这三个库均为Oracle数据库。
OLTP库中的表均有自更新时间(self_update_time)字段,标识下级节点上报到OLTP库节点的时间;CDS、ODS、DW三层库也均有ETL_LOADTIME字段,分别标识数据到本库的时间戳。
     CDS库只存放每次增量的快照,ODS存有历史数据(相当于OLTP的拷贝),DW库就不用说了 。

     在OLTP->CDS抽取和ODS->DW抽取时均要要用时间截取增量数据,对于这块时间的使用讨论如下:

     1、第一种方式,同样也是最简单、最经典的方式。使用自建变量string($$Vtime)和系统变量($$SessStartTime)
OLTP->CDS:
在SQ组件的sql覆盖中加where字句:    where self_update_time>=to_date('$$Vtime','yyyy-mm-dd hh24:mi:ss')
                                                                 and self_update_time
                (注:这块在运行会话时有可能会报错,是因为此处字符转换格式的问题,字符转换的格式具体要依库而定,帮助文档里有常用库的转换格式。也可在日志中查找错误信息,错误信息对转换错的字符格式有显示,可根据其更改成相应格式即可)
     变量$$Vtime 在此使用过之后,在后续的Exptrans组件中更改变量的值,以备下次抽取使用。更改表达式如下:
                                                                 SETVARIABLE ($$VTIME,to_char( SESSSTARTTIME,'yyyymmddhh24miss' ))
ODS - > DW:
SQ组件sql覆盖和上面一样,不过在这里不用self_update_time字段了,而是用在CDS->ODS转换过程中生成的 ETL_LOADTIME字段(ETL_LOADTIME 字段在Exptrans组件中是由表达式 systimestamp() 函数生成的一个新字段,标识这一层转换结束的时间
     在此处若用self_update_time 字段结果不会有差异,原因是CDS每次是抽取的快照,但是在逻辑上理解起来就有点复杂,ODS层的数据却用到OLTP的时间来卡数据,是不是有点越级了!!

     2、使用日期增量(如每次加1天),原理和第一种方式相差无几,但在变量$$Vtime(date类型)更新时有所不同。
     比如我将来任务调度起来要实现的是每日加工,那么数据就要每天都要抽取一次。如设定每天凌晨1:00开始抽取数据,上次抽取数据的时间戳是
                              where self_update_time>=$$Vtime(2015-9-1 1:00:00)
            2015-9-2 1:00:00开始抽取 ,抽取了10分钟,即2015-9-2 1:10:00结束抽取(此时抽取得是2015-9-1号的数据)。更改变量值:$$Vtime=$$Vtime+1,此时$$Vtime变量值变为:2015-9-2 1:00:00,那么本次抽取时的起始时间就为:2015-9-2 1:00:00
          这样的话也可以实现增量抽取,并且可以避免数据丢失。缺点:如果将来要改动加工频率,即从日加工改为每2小时加工一次,这样的话需要去纯人工的去改每层mapping,相对代价较大,第一种方案同业也存在这种问题。
          不过还是要针对项目的具体情况而定,比如像银行的项目的话,整个调度起来基本都是每天对本日的数据进行汇总加工,更改可能性较小,不过不排除客户的领导头脑发热,要让你改也没办法。
     3、最隆重的介绍第三种方式,表管理时间。(后期管理最方便
     就本次我们做的来说吧,这样比较有针对性。
     如文章开头,OLTP是DB2的数据库,CDS、ODS、DW均为ORACLE。     
     对于表管理,首先提出了两个方案:(1)使用到时间的源表的每个库内建一个表(本例:OLTP和ODS中个建一张表);
                                                                 (2)仅在DW库内建一张表,将所用到的所有时间放在一张表里管理。
分析:动OLTP库,这放在哪个项目中都是完全被禁止的,想都不要想,故还是要使用第二种方案。
        但是,
          若只在DW库中建表来管理所有时间,那么在ODS->DW用时间时,就要从ODS到DW中进行跨库查询;在OLTP->CDS用时间时,同样也要跨到DW库中查询,但是OLTP和DW属于异构的库,似乎有点麻烦。
          ODS->DW的跨库查询好解决,只需在ODS中建一个指向DW的DBLink即可:
                                                       
create database link ycdcdwDBL
        connect to [database_name(DW)] identified by [pass_word(DW)] 
        using '(DESCRIPTION =
                (ADDRESS_LIST =
                  (ADDRESS = (PROTOCOL = TCP)(HOST = [node_ip(DW)])(PORT = [端口]))
                )
                (CONNECT_DATA =
                  (SERVICE_NAME = [dw_server_name])
                )
              )'; 
       这样,每次在SQ组件中进行sql覆盖时,直接就能子查询DW中的时间戳管理表(表名:DW_T_ETL_LASTRUN_TIME,字段:SESSION_NAME,LAST_TIME)
sql覆盖如下:
                         select~~~~~~~~~from [OLTP_table_name] t
                              where t.ETL_LOADTIME>(select last_time from DW_T_LASTRUN_TIME where session_name='DW层mapping对应的SESSION_NAME')
         最后在mapping的目标表中更改‘属性’->'post SQL',
sql覆盖如下:update DW_T_LASTRUN_TIME set last_time=sysdate where session_name='DW层mapping对应的SESSION_NAME '

OLTP->CDS抽取涉及到了异构服务,我们才用的方法是:将DW中的时间管理表映射成一个参数文件,映射参数文件要进行字符串拼接,具体格式帮助文档上面有详细的解释,这里不再详述了,我的拼接形式如下:
                              
'[' ||SESSION_NAME|| ']' || '
'||
'$$Param_SrcOwnerName=' ||SESSION_NAME|| '
'||
'$$Param_SrcOwnerLASTTIME=' || to_char (LAST_TIME, 'YYYY-MM-DD-HH24.MI.SS' )|| '
'

参数文件中的内容如下格式:
 [s_CDS_BS_YC_FORECAST]
$$Param_SrcOwnerName=s_CDS_BS_YC_FORECAST
$$Param_SrcOwnerLASTTIME=1900-01-01-00.00.00
     本机的参数文件自动保存目录(D:\apps\infa\9.5.1\server\infa_shared\TgtFiles)。在调度任务的时候,将映射参数文件的session放在最前面,即每次调度之前将参数文件中的数据更新一次。在OLTP->CDS的mapping 中设置参数‘$$Param_SrcOwnerLASTTIME’,参数名随便取,不要忘了两个$符号。
     Mapping中SQ组件的sql覆盖就可以直接用参数来写了:where self_update_time>'$$Param_SrcOwnerLASTTIME '
注意:
     参数此时还没有初始化,给参数传数据,就要靠参数文件了。在session的‘属性’->'Parameter Filename'中填入参数文件路径和参数文件名,session的‘映射’->‘源(SQ)’->'属性'->'Owner Name'中填入参数名称。这样会话在运行时会自动去参数文件中与此session_name相同的相同参数名称的参数值。
     同样,最后也要更新表中的时间:
最后在mapping的目标表中更改‘属性’->'post SQL',
sql覆盖如下:update DW_T_LASTRUN_TIME set last_time=sysdate where session_name='CDS层mapping对应的SESSION_NAME '

你可能感兴趣的:(关于Informatica增量抽取时间戳的管理)