1. 概述
1.1 问题描述
用户在定时任务进行数据同步时,如果源数据库同时有增删改变化,且来源表中没有时间戳时,可以使用数据比对,但是如果数据量很大,想要更好的提高同步效率,就可以使用本文的方案进行数据同步。
时间戳:一般是记录数据的增删改时间。
业务时间:一般是记录业务发生的时间(如果数据修改,业务的发生时间还是不变的)。
1.2 实现思路
由于数据表只有业务时间,因此需要使用删除指定业务时间一部分的数据,然后再更新数据的方式。
1)获取参数:获取上次同步的时候,记录的业务时间,并将其设置为参数 cur_timestamp,便于后续目标表删除该业务时间之后的数据、来源表获取该业务时间之后的数据。
注:cur_timestamp 初始值改到很早之前,就是初次同步全量数据。
2)同步删除数据:删除目标表数据中 >cur_timestamp,即目标表中业务时间晚于上次同步的业务时间的数据。
3)增量同步:获取来源表业务时间晚于 cur_timestamp 的数据,并将增量/变化的数据同步到目标表。
4)更新时间表同步时间戳和执行记录。 cur_timestamp 更新为特定频率时间。注:可根据业务情况设置,比如业务一般不修改3个月前的数据。
demo 示例详情请参见:https://demo.finedatalink.com/ 增删改数据同步(非数据比对且无时间戳,有业务时间)
2. 操作步骤
来源表中相对于目标表修改了 1003 的 order_quantity 值,同时新增 1004 这条数据,并且删除了 1002 数据,如下图所示:
其中 order_business_date 为业务时间,也就是订单交易时间。
2.1 前提条件
创建执行记录数据表,便于获取每次同步的时间戳,如下图所示:
注:两个时间字段初始值可以设置为一个比较早的时间,早于业务数据时间戳,以便初次同步全量数据。
2.2 获取上次同步记录的业务时间作为参数
1)使用「参数赋值」获取上次同步的时候记录的业务时间,如下图所示:
注:cur_timestamp 初始值改到很早之前,就是初次同步全量数据。
SELECT cur_timestamp
FROM `demotest`.`ETL_RECORD`
WHERE table_name='F_ORDER_NOTIMESTAMP_DATE_FROM'
并将其设置为参数 cur_timestamp,便于后续目标表删除该业务时间之后的数据、来源表获取该业务时间之后的数据,如下图所示:
2.3 删除部分数据
使用 SQL 脚本,删除目标表数据中 >cur_timestamp,即目标表中业务时间晚于上次同步的业务时间的数据,如下图所示:
DELETE
FROM `demotest`.`F_ORDER_NOTIMESTAMP_DATE_TARGET`
WHERE order_business_date>'${cur_timestamp}'
2.4 增量同步
新建「数据转换」,进入编辑界面后使用DB表输入功能,获取来源表业务时间晚于 cur_timestamp 的数据,如下图所示:
SELECT
*,
NOW() AS etl_time
FROM `demotest`.`F_ORDER_NOTIMESTAMP_DATE_FROM`
WHERE order_business_date>'${cur_timestamp}'
使用 DB表输出,将增量/变化的数据同步到目标表,如下图所示:
写入方式设置为追加写入并设置主键冲突策略,如下图所示:
2.5 更新时间表同步时间戳和执行记录
使用 SQL 脚本,更新时间表同步时间戳和执行记录,cur_timestamp 更新为特定频率时间,同时将上次同步记录时间写入 pre_timestamp 字段,etl执行次数写入 etl_time,如下图所示:
注:可根据业务情况设置,比如业务一般不修改3个月前的数据。
UPDATE `demotest`.`ETL_RECORD`
SET
cur_timestamp=NOW() - INTERVAL 3 MONTH , ##默认3个月,按需配置
pre_timestamp='${cur_timestamp}',
etl_times=etl_times+1,
etl_last_time=NOW()
WHERE table_name='F_ORDER_NOTIMESTAMP_DATE_FROM'
2.6 效果查看
执行定时任务后,即可在目标数据表中看到同步后的数据,如下图所示:
同时记录表 ETL_RECORD 结果如下图所示: