农产品“溯源系统”是什么样子的?

用户名: @
密&&码:&&&|
密&&码:&|
密&&码:&|
您的位置: &
开源ETL工具kettle系列之增量更新设计技巧
作者:IT168 gemini5201314&&
内容导航:
ETL中增量更新是一个比较依赖与工具和设计方法的过程,Kettle中主要提供Insert / Update 步骤,Delete 步骤和Database
步骤来支持增量更新,增量更新的设计方法也是根据应用场景来选取的,虽然本文讨论的是Kettle的实现方式,但也许对其他工具也有一些帮助。本文不可能涵盖所有的情况,欢迎大家讨论。
应用场景增量更新按照数据种类的不同大概可以分成:1.&只增加,不更新,2.&只更新,不增加3.&即增加也更新4.&有删除,有增加,有更新其中1
3种大概都是相同的思路,使用的步骤可能略有不同,通用的方法是在原数据库增加一个时间戳,然后在转换之后的对应表保留这个时间戳,然后每次抽取数据的时候,先读取这个目标数据库表的时间戳的最大值,把这个值当作参数传给原数据库的相应表,根据这个时间戳来做限定条件来抽取数据,抽取之后同样要保留这个时间戳,并且原数据库的时间戳一定是指定默认值为sysdate当前时间(以原数据库的时间为标准),抽取之后的目标数据库的时间戳要保留原来的时间戳,而不是抽取时候的时间。&&
对于第一种情况,可以使用Kettle的Insert / Update 步骤,只是可以勾选Don’t perform any
update选项,这个选项可以告诉Kettle你只会执行Insert
步骤。对于第二种情况可能比较用在数据出现错误然后原数据库有一些更新,相应的目标数据库也要更新,这时可能不是更新所有的数据,而是有一些限定条件的数据,你可以使用Kettle的Update
步骤来只执行更新。关于如何动态的执行限定条件,可以参考前一篇文章。第三种情况是最为常见的一种情况,使用的同样是 Kettle的Insert /
Update 步骤,只是不要勾选Don’t perform any update 选项。第四种情况有些复杂,后面专门讨论。
对于第1,2,3种情况,可以参考下面的例子。这个例子假设原数据库表为customers , 含有一个id , firstname ,
lastname , age 字段,主键为id , 然后还加上一个默认值为sysdate的时间戳字段。转换之后的结果类似:id , firstname ,
lastname , age , updatedate . 整个设计流程大概如下:
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
图1其中第一个步骤的sql 大概如下模式:Select max(updatedate) from target_你会注意到第二个步骤和第一个步骤的连接是黄色的线,这是因为第二个table input
步骤把前面一个步骤的输出当作一个参数来用,所有Kettle用黄色的线来表示,第二个table input 的sql 模式大概如下:Select
field1 , field2 , field3 from customers where updatedate & ?
后面的一个问号就是表示它需要接受一个参数,你在这个table input 下面需要指定replace variable in script
选项和execute for each row 为选中状态,这样,Kettle就会循环执行这个sql ,
执行的次数为前面参数步骤传入的数据集的大小。&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
关于第三个步骤执行insert / update 步骤需要特别解释一下,&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
Kettle执行这个步骤是需要两个数据流对比,其中一个是目标数据库,你在Target table 里面指定的,它放在The keys to look up
the values(s) 左边的Table field 里面的,另外一个数据流就是你在前一个步骤传进来的,它放在The keys to look up the
value(s) 的右边,Kettle首先用你传进来的key
在数据库中查询这些记录,如果没有找到,它就插入一条记录,所有的值都跟你原来的值相同,如果根据这个key找到了这条记录,kettle会比较这两条记录,根据你指定update
field 来比较,如果数据完全一样,kettle就什么都不做,如果记录不完全一样,kettle就执行一个update
步骤。所以首先你要确保你指定的key字段能够唯一确定一条记录,这个时候会有两种情况:1.维表2.事实表维表大都是通过一个主键字段来判断两条记录是否匹配,可能我们的原数据库的主键记录不一定对应目标数据库中相应的表的主键,这个时候原数据库的主键就变成了业务主键,你需要根据某种条件判断这个业务主键是否相等,想象一下如果是多个数据源的话,业务主键可能会有重复,这个时候你需要比较的是根据你自定义生成的新的实际的主键,这种主键可能是根据某种类似与sequence
的生成方式生成的,事实表在经过转换之后,进目标数据库之前往往都是通过多个外键约束来确定唯一一条记录的,这个时候比较两条记录是否相等都是通过所有的维表的外键决定的,你在比较了记录相等或不等之后,还要自己判断是否需要添加一个新的主键给这个新记录。上面两种情况都是针对特定的应用的,如果你的转换过程比较简单,只是一个原数据库对应一个目标数据库,业务主键跟代理主键完全相同的时候完全可以不用考虑这么多。1
【内容导航】
&版权所有。未经许可,不得转载。
[责任编辑:]
相关论坛贴
itpub.net All Right Reserved.&&&&E-mail:
北京皓辰广域网络信息技术有限公司.&版权所有&&&&&&&&&&Kettle定时执行(ETL工具)
ETL高级教程
1,Kettle跨平台使用。
例如:在AIX下(AIX是IBM商用UNIX操作系统,此处在LINUX/UNIX同样适用),运行Kettle的相关步骤如下:
1)进入到Kettle部署的路径
&&& 2)执行 chmod
*.sh,将所有shell文件添加可执行权限
3)在Kettle路径下,如果要执行transformation,就运行./pan.sh -file=?.ktr
-debug=debug -log=log.log
其中。-file说明你要运行的transformation文件所在的路径;-debug说明日志输出的级别;-log说明日志输出的路径
4)同理,对于job的执行,请将./pan.sh更换成./kitchen.sh,其他部分说明不变。
2,Kettle环境变量使用。
在transformation中,Core
Objects--&Job--&Set
Variables,可以设置环境变量,对于绝对路径和相对路径的转换很有帮助,Kettle的跨平台很大程度依靠它
3,其它功能的使用。
其它功能包括DB存储过程调用,流查询,值映射,聚合记录等,各位自行摸索
4,Kettle定时功能。
在Job下的start模块,有一个定时功能,可以每日,每周等方式进行定时,对于周期性的ETL,很有帮助。
a.使用资源库(repository)登录时,默认的用户名和密码是admin/admin。
b.当job是存放在资源库(一般资源库都使用数据库)中时,使用Kitchen.bat执行job时,需使用如下的命令行:
Kitchen.bat /rep kettle /user admin
/pass admin /job job名
c.当job没有存放在资源库而存放在文件系统时,使用Kitchen.bat执行job时,需使用如下的命令行:
Kitchen.bat /norep /file user-transfer-job.kjb
d.可以使用命令行执行job后,就可以使用windows或linux的任务调度来定时执行任务了
e.如果出现异常语句,
Unexpected error during transformation metadata load
No repository defined!
请按上面的操作排除。
5,Kettle经验之日志。
Kettle对于日志的处理,存在一个BUG,看过上一篇的人或许已经看到了我的留言,Kettle对于日志处理有一个BUG,当日志多于49M(不是50M,也不是49M),Kettle就会自动停止,这一点我在源码里面也没有找到对应的设置和约束,原因还找不到,因为是日志没有写,所以原因也不好跟踪还不知道具体原因。
6,Kettle之效率提升。
Kettle作为一款ETL工具,肯定无法避免遇到效率问题,当很大的数据源输入的时候,就会遇到效率的问题。对此有几个解决办法:
1)数据库端创建索引。对需要进行查询的数据库端字段,创建索引,可以在很大程度上提升查询的效率,最多的时候,我不创建索引,一秒钟平均查询4条记录,创建索引之后,一秒钟查询1300条记录。
2)数据库查询和流查询注意使用环境。因为数据库查询为数据输入端输入一条记录,就对目标表进行一次查询,而流查询则是将目标表读取到内存中,数据输入端输入数据时,对内从进行查询,所以,当输入端为大数据量,而被查询表数据量较小(几百条记录),则可以使用流查询,毕竟将目标表读到内存中,查询的速度会有非常大的提升(内存的读写速度是硬盘的几百倍,再加上数据库自身条件的制约,速度影响会更大)。同理,对于目标表是大数据量,还是建议使用数据库查询,不然的话,一下子几百M的内存被干进去了,还是很恐怖的。
3)谨慎使用javascript脚本,因为javascript本身效率就不高,当你使用js的时候,就要考虑你每一条记录,就要执行一次js所需要的时间了。
4)数据库commit次数,一条记录和一百条记录commit对效率的影响肯定是不一样的。
5)表输入的sql语句的写法。有些人喜欢在表输入的时候,将所有关联都写进去,要么from
N多个表,要么in来in去,这样,就要面对我在2)里面说道的问题,需要注意。
6)注意日志输出,例如选择数据库更新方式,而且日志级别是debug,那么后台就会拼命的输出日志,会在很大程度上影响速度,此处一定要注意。
7,常见的调试BUG。
Kettle提供了很多调试的解决办法,但是对于常见的调试BUG还是能避免就避免。
1)路径问题。我最常遇到的问题就是在windows下调试成功,但是部署到UNIX下出问题,忘记将windows下路径变成unix下,经常会出现问题。
2)输出端,数据库插入更新选择不对。输出端,提供了三种数据库输出的办法,数据库输出,插入/更新,更新,对于这三种,各有利弊,如果你知道数据库输出,完全是插入,如果有重复数据,则会报错;插入更新和更新,因为更新数据时,后台输出很多日志,会导致效率很低。
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。}

我要回帖

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信