反馈已提交

网络繁忙

数仓拉链表(来源表数据大于10000)

  • 文档创建者:Wendy123456
  • 历史版本:5
  • 最近更新:Wendy123456 于 2023-12-26
  • 1. 概述

    1.1 应用场景

    数仓拉链表 文档中提供的方案,使用「参数赋值」节点将来源表中的 ID 字段输出为参数,但「参数赋值」节点要求输出的参数不能超过 10000 个,若来源表数据超过 10000 条,该方案将不适用。

    本文提供数据量较大场景(来源表数据超过 10000)下拉链表的实现方案。

    1.2 实现思路

    1)将来源表数据同步到中间表中,便于对来源表字段做操作。

    2)标记中间表和拉链表共有字段,便于后续数据关联后区分字段来源。

    3)将中间表与拉链表全外连接:

    注:下图示例中,来源表主键字段为ID,拉链表中也包含ID字段。

    1703556390793455.png

    可看出:

    • 来源表存在 ID,拉链表无 ID,代表新增的数据(上图红色标记的数据)。

    • 来源表无 ID,拉链表存在 ID ,代表删除的数据(上图紫色标记的数据)。

    • 来源表ID=拉链表ID,其他字段不一致,代表更新的数据(上图黄色标记的数据)。

    4)将新增、更新、删除数据标记。

    5)不同类型的数据,根据不同策略输入到拉链表中(具体参考本文 2.2 节)。

    任务Demo详情参见:官方demo:https://demo.finedatalink.com/ 中的定时任务:数仓拉链表(来源表数据大于10000)

    2. 实现方法

    2.1 场景模拟

    1703226415916918.png

    AUTO_INCREMENT_ID 字段为拉链表的主键,为自增字段。

    来源表说明:

    • 更新苹果的数据。

    • 新增橙子的数据。

    • 删除火龙果的数据。

    接下来要将来源表数据的变化,更新到拉链表中,同时满足保留历史快照的要求。

    2.2 方案说明

    数仓拉链表 文档中,来源表中存在更新时间戳字段,拉链表中新增数据的开始时间为来源表的时间戳字段。

    1703147422286495.png

    但很多场景中,用户的来源库中没有更新时间戳字段,或者更新时间戳字段不准确。针对该场景,本文提供方案。

    注:用户来源表中若存在更新时间戳字段,且该字段准确,可用该字段代替「新增数据的开始时间」。

    设计逻辑(以本文场景的拉链表为例):

    场景
    AUTO_INCREMENT_IDIDNAMEUNITSTART_TIMEEND_TIME
    新增
    自增

    1900-01-01

    可替换为来源表的时间戳字段

    9999-12-31
    删除不变
    执行本文 3.2.3 节步骤的时间,值为now()
    更新-旧数据更新不变执行本文 3.2.3 节步骤的时间,值为now()
    更新-新数据插入
    自增

    执行本文 3.2.3 节步骤的时间,值为now()

    可替换为来源表的时间戳字段

    9999-12-31

    所以 2.1 节场景中,拉链表应该:

    • 更新数据:对已存在的苹果数据,END_TIME 更新为执行本文 3.2.3 节步骤的时间;将来源表中的苹果数据,新增到拉链表中,START_TIME 为执行本文 3.2.3 节步骤的时间,END_TIME 为9999-12-31。拉链表中将存在两条苹果数据,一条为失效数据,一条为最新数据。

    • 新增数据:新增橙子的数据,START_TIME 为1900-01-01(由于来源表没有时间戳字段,此为自定义的时间),END_TIME 为9999-12-31

    • 删除数据:更新火龙果数据,END_TIME 为执行本文 3.2.3 节步骤的时间

    3. 操作步骤

    3.1 创建中间表

    拉链表与来源表中,共有字段名称相同;本文方案需要将来源表数据与拉链表数据进行全外连接,识别新增、删除、更新数据,数据关联前需要修改来源表和目标表字段名,便于区分字段。

    所以将来源表数据同步到中间表中,后续对中间表进行操作。

    1)新建定时任务,拖入「数据同步」节点,取出来源表数据。如下图所示:

    18.png

    2)将数据写入到中间表中,设置 ID 为中间表的主键。如下图所示:

    19.png

    写入方式选择「清空目标表,再写入数据」,便于后期定期执行任务。

    3)右键数据同步节点,选择运行节点,运行该节点,生成中间表,便于后续使用。

    3.2 数仓拉链表实现

    43.png

    3.2.1 中间表与拉链表取并集

    中间表与拉链表字段后加后缀,便于后续数据关联后区分字段来源。

    1)拖入数据转换节点,进入数据转换节点。

    2)拖入DB表输入算子,读取中间表数据。如下图所示:

    8.png

    3)拖入字段设置算子,在中间表的每个字段名称后加上_CUR,方便后续数据关联后识别字段来源。如下图所示:

    20.png

    4)拉链表中没被删除过的数据,END_TIME 为9999-12-31,将没被删除过的数据筛选出来,与中间表关联。如下图所示:

    SELECT * FROM `demotest`.`ZIPPER`
    WHERE DATE_FORMAT(END_TIME, '%Y-%m-%d')='9999-12-31'

    10.png

    5)拖入字段设置算子,在拉链表的每个字段名称后加上_PRE方便后续数据关联后识别字段来源。

    其中拉链表主键字段 AUTO_INCREMENT_ID 不用加此后缀,因为中间表中没有包含此字段,该字段无需做处理便于后续区),如下图所示:

    1703228016360373.png

    6)拖入「数据关联」算子,将中间表与拉链表数据取并集(全外连接)。如下图所示:

    12.png

    点击「数据预览」,如下图所示:

    1703228118565987.png

    可看出:

    • ID_CUR(来源表)存在,ID_PRE(拉链表)无,代表新增的数据(上图红色标记的数据)。

    • ID_CUR(来源表)无,ID_PRE(拉链表)存在,代表删除的数据(上图紫色标记的数据)。

    • ID_CUR(来源表)=ID_PRE(拉链表),其他字段不一致,代表更新的数据(上图黄色标记的数据)。

    后续可新增一列,对数据进行标记。

    3.2.2 标记数据

    3.2.1 节中数据关联后,我们已总结新增、删除、更新数据的特征。本节,我们标记这些数据。

    1)拖入「新增计算列」算子,对数据进行标记。如下图所示:

    注:公式中字段为点击生成。

    IF(ISNULL(ID_PRE),"新增",IF(ISNULL(ID_CUR),"删除",IF(OR(NAME_CUR<>NAME_PRE,UNIT_CUR<>UNIT_PRE),
    "更新","相同")))

    1703212662321039.png

    14.png

    2)点击「数据预览」,如下图所示:

    1703228185210865.png

    3.2.3 分发数据准备

    拉链表中数据应该:

    场景
    拉链表数据变化
    更新苹果数据

    对已存在的苹果数据,END_TIME 更新为执行该算子的时间

    将来源表中的苹果数据,新增到拉链表中,START_TIME 为执行该算子的时间,END_TIME 为9999-12-31

    新增数据

    新增橙子的数据,START_TIME 为1900-01-01(由于来源表没有时间戳字段,此为自定义的时间),END_TIME 为9999-12-31

    删除数据更新火龙果数据,END_TIME 为执行该算子的时间

    所以,需要新增数据列:

    1)START_TIME:值为1900-01-01,为新增数据的开始时间

    2)END_TIME:值为9999-12-31,为新增数据的结束时间;更新-新插入数据的结束时间

    3)TIME:执行该算子的时间,值为now()

    拖入「新增计算列」算子,新增计算列。如下图所示:

    1703554206554924.png

    3.2.4 数据分发

    场景
    字段对应关系
    新增数据

    Type 字段值为新增的数据

    将新增数据插入,其中:

    处理后的字段
    拉链表字段
    START_TIME(值为1900-01-01START_TIME
    END_TIME(值为9999-12-31END_TIME
    删除数据

    Type 字段值为删除的数据:

    将拉链表中该条数据的 END_TIME 更新为 TIME 的值now()

    更新-老数据更新

    Type 字段值为更新的数据:

    将拉链表中该条数据的 END_TIME 更新为 TIME 的值now()

    更新-新数据插入

    Type 字段值为更新的数据

    将来源表中的这条数据新增到拉链表中,其中:

    处理后的字段
    拉链表字段
    TIME(值为now()START_TIME
    END_TIME(值为9999-12-31END_TIME

    1)拖入 4 个「DB表输出」算子,与前面的新增计算列」算子相连。

    1703558693974206.png

    2)右键点击新增计算列1算子,点击数据分发。设置如下图所示:

    1703229234666182.png

    3)点击DB表输出算子,处理新增数据,将新增数据输入到拉链表中。如下图所示:

    将标记为新增的数据写入到拉链表中,拉链表中数据的开始时间对应新增字段 START_TIME ,值为 1900-01-01 ;拉链表数据的结束时间对应新增字段 END_TIME ,值为 9999-12-31 。

    1703230478194146.png

    写入方式选择「追加写入数据」。

    4)点击DB表输出1算子,处理删除数据,更新删除数据的 END_TIME 。如下图所示:

    将标记为删除的数据写入到拉链表中,拉链表数据的结束时间对应新增字段 TIME ,值为now() 

    1703554671298779.png

    写入方式选择插入/更新/删除数据」中的更新,标识字段为Type,标识值为删除,逻辑主键为AUTO_INCREMENT_ID。如下图所示:

    1703231237956054.png

    5)点击DB表输出2算子,更新拉链表中存在的旧更新数据中 END_TIME。如下图所示:

    将标记为更新的数据写入到拉链表中,拉链表数据的结束时间对应新增字段 TIME ,值为now() 

    1703554826405704.png

    写入方式选择插入/更新/删除数据」中的更新,标识字段为Type,标识值为更新,逻辑主键为AUTO_INCREMENT_ID。如下图所示:

    1703231435619123.png

    6)点击DB表输出3算子,将来源表中的更新数据,新增到拉链表中,拉链表中的 START_TIME 对应 3.2.3 节中的 TIME,拉链表中的 END_TIME 对应 3.2.3 节中的 END_TIME。如下图所示:

    1703555094509804.png

    写入方式选择「追加写入数据」。

    7)点击右上角保存按钮。

    3.3 效果查看

    点击右上角保存并运行按钮,运行成功后,拉链表如下图所示:

    1703555940638441.png





    附件列表


    主题: 最佳实践
    已经是第一篇
    已经是最后一篇
    • 有帮助
    • 没帮助
    • 只是浏览
    • 评价文档,奖励 1 ~ 100 随机 F 豆!

    鼠标选中内容,快速反馈问题

    鼠标选中存在疑惑的内容,即可快速反馈问题,我们将会跟进处理。

    不再提示

    10s后关闭

    联系我们
    在线支持
    获取专业技术支持,快速帮助您解决问题
    工作日9:00-12:00,13:30-17:30在线
    页面反馈
    针对当前网页的建议、问题反馈
    售前咨询
    采购需求/获取报价/预约演示
    或拨打: 400-811-8890 转1
    qr
    热线电话
    咨询/故障救援热线:400-811-8890转2
    总裁办24H投诉:17312781526
    提交页面反馈
    仅适用于当前网页的意见收集,帆软产品问题请在 问答板块提问前往服务平台 获取技术支持