将根据时间戳增量数据方案修改为根据批次号增量数据方案

1、之前写过根据时间戳来增量数据,时间戳增量数据存在一定的缺点,就是如果开启自动的话,以后如果因为某个外在因素出错了,那么这个开始时间和结束时间不好控制,那么就可能造成一些其他数据量不准的情况,但是根据批次号不会出现这个问题:

使用kettle来根据时间戳或者批次号来批量导入数据,达到增量的效果。

方案一、
1、第一步、获取目标数据库数据表名称最大批次号;
select '数据表名称' as table_name, 1 as part,'数据来源' as source,IFNULL(max(Cd_batch), CONCAT(DATE_FORMAT(now(),'%Y%m%d'),'00001')) as next_batch from 数据对账数据表名称 where UPPER(TableName)='数据表名称'
2、第二步、获取系统数据库数据表开始批次号;
注意:记得勾选替换SQL语句里的变量。然后从步骤插入数据进行选中,上一步的名称。
select ? as table_name, ? as part,? as source,start_batch, ? as next_batch from 系统对账数据表数据名称 where table_name='数据表名称' and part=1 and source='数据来源'
3、第三步、获取目标数据库数据表对账批次号;
注意:记得勾选替换SQL语句里的变量。然后从步骤插入数据进行选中,上一步的名称。执行每一行进行勾选,可以保证查询出的多条SQL语句的值可以被执行。
select Cd_count, Cd_batch from 数据对账数据表名称 where '数据表名称'=?  and 1=? and '数据来源'=?  and TableName='数据表名称' and Cd_batch>? and Cd_batch<=? ORDER BY Cd_batch
4、第四步、获取目标数据库数据表批次数据量Cd_count;
注意:记得勾选替换SQL语句里的变量。然后从步骤插入数据进行选中,上一步的名称。执行每一行进行勾选,可以保证查询出的多条SQL语句的值可以被执行。
select (count(*) - ?) as COUNTS, Cd_batch from 数据表名称 where Cd_batch=?
5、第五步、过滤记录,发送true数据给步骤进行选择正常的目标数据库数据表表输入,发送false数据给步骤进行选择中止。条件是COUNTS = 0;
6、第六步、目标数据库数据表表输入;
注意:记得勾选替换SQL语句里的变量。然后从步骤插入数据进行选中,上一步的名称。执行每一行进行勾选,可以保证查询出的多条SQL语句的值可以被执行。
select *,'数据来源' as Cd_source,'数据表名称' as table_name, 1 as part,'数据来源' as source, ? as COUNTS from 数据表名称  where Cd_batch=?
7、第七步、可以将表输出和表输出1进行字段获取和映射,然后进行更新操作,将next_batch进行更新,更新的条件字段是table_name、part、source。

方案一和方案二:

方案三和方案四:

方案五和方案六:

下面简单介绍了一下,各种方案的缺点和设计思路:

方案一、
a、设计思路,首先获取到目标数据库数据表的最大批次号,然后获取到系统数据库数据表的开始批次号(系统数据库数据表记录了每次开始批次和最大批次,这样可以保住增量数据),然后获取到目标数据库数据表的数据对账批次号以及数据量,然后获取到目标数据库数据表的数据量。然后使用过滤记录,判断数据对账数据表里面的批次和数据量和实际的数据表的数据量是否一致,如果一致,就进行表表输入和表输出,如果不一致就中止。
b、设计缺点、如果按照设计思路,正常流程的话,如果都是正常执行,是没有问题的。
缺点一,更新放到最后,会导致,如果有查询出一百万条数据,会更新系统数据表一百万次,影响系统性能。
缺点二,如果数据对账数据表的批次数据量和实际数据表的批次数据量没有对应着,就会中止,问题就出现在这里,kettle的转换是并行的,比如我有一百个批次在数据对账表里面,然后前两个批次的数据对账表的数据量和实际数据表的批次数据量对着呢,当第三个的数据对账数据表的数据量和实际数据表的数据量没有对上,就会中止,前两个数据对账表的数据量对上的,也不会执行插入操作,不符合要求。


方案二、
a、设计思路,和方案一基本相同,改进的地方是将过滤记录修改为了switch/case。这样做的好处是更新次数减少了很多很多,如果0值的话,就执行更新和表输入操作。
b、设计缺点,缺点同方案一的缺点二。


方案三、
a、设计思路,此方案是根据开始批次进行查询的,只要大于开始批次的都会进行查询出来,
b、设计缺点,缺点同方案一的缺点一、缺点二。


方案四、
a、设计思路,和方案一基本相同,改进的地方是将过滤记录修改为了switch/case。这样做的好处是更新次数减少了很多很多,如果0值的话,就执行更新和表输入操作。
b、设计缺点,缺点同方案一的缺点二。


方案五、
a、设计思路,和方案四基本相同,是在switch/case的时候,在中止的前面加了阻塞数据直到步骤都完成。阻塞的步骤是switch/case正确执行的步骤,包含目标数据库数据表表输入 2步骤、表输出2步骤、表输出1 2步骤。
b、设计缺点,缺点就是在数据对账数据表里面的批次对应的数据量和实际数据表批次对应的数据量,如果两边相等的都会正常执行,然后插入到表输出1、表输出1 2,然后数据对账数据表里面的批次对应的数据量和实际数据表批次对应的数据量,不相等的全部都不会正常执行,那么就将数据对账批次对应的数据量和实际表批次对应的数据量,这些错误的都没有执行,这个缺点还是挺麻烦的,所以最后没有使用此方案。


方案六、
a、设计思路,方案一、方案二、方案三、方案四、方案五、是使用kettle的流程进行控制的,但是还是存在一些问题,因为kettle的job是按照顺序执行的,转换是并发执行的,所以转换不是很好控制,方案六采用了拼接sql实现此功能,以上方案存在的问题都是关于,如果数据对账数据表批次号对应的数据量和实际数据表对应的数据量不一致如何解决,要求将正常的批次对应的数据量都进行插入操作,但是遇到第一个错误的,即数据对账数据表批次号对应的数据量和实际数据表批次号对应的数据量不一致就停止转换。最后采用阻塞数据,将最后一条数据,即最大开始的批次号更新到系统平台,以供下次使用。最终实现增量导入数据。
b、设计缺点,此方案是最终采用的方案,缺点吗,暂时未发现,但是呢,此方案实现的SQL如下所示:
    1、开始获取到开始的批次号,这样方便第二步使用,查询大于开始批次的,这样将大于开始批次的都插入到目标数据库数据表。
        select start_batch,start_batch as start_batch1 from 系统对账数据表数据名称 where table_name='数据表名称' and part=1 and source='来源标识';    
    2、如果是正常的情况,会查询出所有的批次对应的数据量,然后将批次号传递到下一步,这样查询出N条数据,将执行每条数据勾选,即可将每条数据都执行的。
如果出现错误的情况,就会将开始错误的批次查询出来,然后将开始错误的批次之前全部的批次都回插入到目标数据库数据表的。    
        SELECT cd_batch FROM 数据对账数据表名称 WHERE TableName='数据表名称' AND cd_batch > ? AND cd_batch < ( SELECT  ifnull(min(cd_batch), '9999999999999') FROM ( SELECT aa.cd_count,(SELECT count(*) AS bcount FROM 数据表名称 bb  WHERE bb.cd_batch = aa.cd_batch) AS countb, cd_batch FROM  数据对账数据表名称 aa WHERE aa.TableName = '数据表名称' AND aa.cd_batch > ? ) tt WHERE  tt.cd_count != tt.countb) ORDER BY Cd_batch;
    3、执行上一步查询出的所有批次,执行每一行,然后插入到目标数据库数据表。
        select *,'来源标识' as Cd_source,'数据表名称' as table_name, 1 as part,'来源标识' as source from 数据表名称  where Cd_batch=?;

待续......

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

扫码关注云+社区

领取腾讯云代金券