一、业务场景要求的逻辑规则

  1. 连续两个版本之间:

    • 如果数据在两个版本中都存在,则数据保留。
    • 如果数据在下一个版本中不存在,则数据的有效期结束。
    • 如果数据在下一个版本中新增,则插入新数据。
  2. 最终结果:

    • 每条数据需要记录其进入版本号(start_version)和离开版本号(end_version)。
    • 如果数据仍然有效,则 end_version 为 NULL。

二、示例数据

2.1 输入数据

  1. current_data存放当前最新的版本数据:

    • 版本 20250101:A, B, C
    • 版本 20250102:A, E
    • 版本 20250103:E, B, C
  2. history_data(拉链表,初始为空)。


2.2 处理过程

第一天(版本 20250101)
  • current_data:A, B, C
  • history_data:
    • 插入 A, B, C,start_version 为 20250101,end_version 为 NULL。

结果:

datastart_versionend_version
A20250101NULL
B20250101NULL
C20250101NULL

第二天(版本 20250102)
  • current_data:A, E
  • 更新 history_data:
    • B 和 C 不在 current_data 中,设置 end_version 为 20250102。
    • A 仍然存在,保持不变。
    • E 是新数据,插入 start_version 为 20250102,end_version 为 NULL。

结果:

datastart_versionend_version
A20250101NULL
B2025010120250102
C2025010120250102
E20250102NULL

第三天(版本 20250103)
  • current_data:E, B, C
  • 更新 history_data:
    • A 不在 current_data 中,设置 end_version 为 20250103。
    • E 仍然存在,保持不变。
    • B 和 C 是重新加入的数据,插入新的记录,start_version 为 20250103,end_version 为 NULL。

结果:

datastart_versionend_version
A2025010120250103
B2025010120250102
C2025010120250102
E20250102NULL
B20250103NULL
C20250103NULL


三、Hive SQL 实现

表结构假设
  1. current_data:存储当前版本的数据。

    • data:数据值
    • version:版本号
  2. history_data:存储拉链表的历史数据。

    • data:数据值
    • start_version:数据进入的版本号
    • end_version:数据离开的版本号(如果数据仍然有效,则为 NULL)

SQL 实现
-- 1. 更新已经不存在的数据的 end_version
INSERT OVERWRITE TABLE history_data
SELECT
    hd.data,
    hd.start_version,
    CASE
        WHEN cd.data IS NULL THEN '20250102' -- 当前版本号
        ELSE hd.end_version
    END AS end_version
FROM history_data hd
LEFT JOIN current_data cd
ON hd.data = cd.data
WHERE hd.end_version IS NULL;

-- 2. 插入新加入的数据
INSERT INTO TABLE history_data
SELECT
    cd.data,
    '20250102' AS start_version, -- 当前版本号
    NULL AS end_version
FROM current_data cd
LEFT JOIN history_data hd
ON cd.data = hd.data AND hd.end_version IS NULL
WHERE hd.data IS NULL;

四、注意事项

  1. 动态版本号:

    • 每天运行时,需要将 20250102 替换为当天的版本号。
    • 可以通过 Hive 的动态分区或参数化脚本实现。
  2. 性能优化:

    • 如果数据量较大,建议对 data 列建立分区或索引以提高查询性能。
    • Hive 的 INSERT OVERWRITE 会重写整个表,因此需要合理设计表的存储格式和分区。
  3. 数据完整性:

    • 确保 history_data 表中有唯一约束(如 data 和 start_version 的组合),以避免重复插入。
Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐