Hive 拉链表实例

一、业务说明

场景:用户会员等级维度拉链表生效规则:[start_dt, end_dt),永久有效 = 9999-12-31每日凌晨跑:T 日更新 T-1 日变更数据(下面是关于T日的介绍,各位可以参看)

++PS.介绍开始++

前提:只算交易日(周一~周五开盘),周末 / 节假日跳过;15:00 是基金 / 理财分界点

一、先统一基础定义

表格

符号 含义 通俗理解
T 日 有效下单日(15 点前) 正式算交易的当天
T-1 日 T 的前一个交易日 昨天收盘日
T+1 日 T 的后一个交易日 下个开盘日
T+2 日 T 往后两个交易日 再往后一天

二、分场景规则对照表

1. 银行(理财 / 转账 / 大额存单 / 赎回取现)

表格

业务 T 日 T+1 T+2
普通跨行转账(工作日白天) 当天受理 一般实时 / 当日到 极少延 T+2
理财申购(15 点前) 登记日 开始计息 / 确认 部分固收 T+2 显示收益
理财赎回(常规固收) 提交赎回 份额确认 资金到银行卡(常见 T+2)
定期到期 到期日 T 本息自动回活期 可直接取现

银行重点:理财赎回很多是 T 赎回 → T+2 拿钱

2. 公募基金(场外支付宝 / 微信 / 银行买的普通基金)

表格

操作 T 日 (15 点前) T+1 T+2
申购买入 按 T 日净值计价 确认份额、开始算收益 持仓显示完整
赎回卖出(偏股 / 混合) 提交赎回 净值结算 资金到账银行卡(主流 T+2)
货币基金(余额宝类) T 买入 T+1 开始计息 收益到账显示
15 点后下单 顺延为下一个交易日当 T 往后全部顺延 ---

基金口诀:三点前算今天 T;三点后算明天 T;股票基金赎回大多 T+2 到钱

3. 可转债(A 股场内打新 / 买卖 / 转股 / 中签)

表格

业务 T 日 T+1 T+2
可转债打新申购 T 日申购 T+1 摇号配号 T+2 公布中签结果
中签缴款 T+2 中签日当天收市前留足资金 T+3 扣款入账 ---
场内买入转债(股票账户) T 日买入成交 T+1 可以卖出(和股票一样 T+1) 可转股、套利
转债转股操作 T 日申请转股 T+1 变成正股股票 T+1 即可卖出正股
转债卖出回款 T 日卖出 资金可用(买别的) T+2 资金可取现到银行卡

转债重点:打新「T 申购→T+2 中签」;买卖「T 买 T+1 卖」;卖钱 T+2 提现


三、高频易错一句话总结

  1. 所有场景:周末节假日不算、15 点决定算不算今天 T
  2. 银行理财 / 场外基金赎回:大多是 T 赎回,T+2 拿钱
  3. 可转债打新:记死「T 申、T+2 中签
  4. 股票 / 转债买卖:T 买 T+1 能卖;卖出钱 T 可用、T+2 能提现

++PS.介绍结束,以下为正文内容++

二、1. 建表语句(拉链主表 + 增量临时表)

复制代码
-- 1. 用户会员拉链主表(ORC、分区/索引思路、标准拉链字段)
CREATE DATABASE IF NOT EXISTS dw;
USE dw;

DROP TABLE IF EXISTS dw_user_level_zip;
CREATE TABLE dw_user_level_zip (
    user_id      STRING COMMENT '用户唯一ID',
    user_name    STRING COMMENT '用户名',
    member_level STRING COMMENT '会员等级:普通/银卡/金卡/钻石',
    charge_money DECIMAL(18,2) COMMENT '累计充值',
    start_dt     DATE COMMENT '本条记录生效日期(包含)',
    end_dt       DATE COMMENT '本条记录失效日期(不包含)',
    is_current   TINYINT COMMENT '1=当前有效 0=历史失效',
    dw_insert_dt DATE COMMENT '数据入库日期'
)
COMMENT '用户会员等级-拉链维度表'
STORED AS ORC
TBLPROPERTIES (
    'orc.compress'='SNAPPY',
    'hive.merge.mapfiles'='true',
    'hive.support.concurrency'='true',
    'hive.txn.manager'='org.apache.hadoop.hive.ql.lockmgr.DbTxnManager'
);

-- 2. 每日增量临时表(存放T-1日变更数据)
DROP TABLE IF EXISTS tmp_user_level_delta;
CREATE TABLE tmp_user_level_delta (
    user_id      STRING,
    user_name    STRING,
    member_level STRING,
    charge_money DECIMAL(18,2)
) COMMENT '用户会员每日变更增量临时表';

三、2. 首次全量初始化脚本(基线数据)

把源头当前最新全量,灌入拉链表,全部设为永久有效

复制代码
-- 清空历史
TRUNCATE TABLE dw_user_level_zip;

-- 全量初始化
INSERT INTO dw_user_level_zip
SELECT
    user_id,
    user_name,
    member_level,
    charge_money,
    '2026-01-01' AS start_dt,   -- 统一基线起始日
    '9999-12-31' AS end_dt,     -- 永久有效
    1 AS is_current,
    CURRENT_DATE AS dw_insert_dt
FROM ods.ods_user_member_full; -- 你的源头全量表

四、3. 每日增量调度脚本(核心・直接调度)

变量说明(调度平台传入)

  • biz_dt:业务日期(跑 T 日任务,biz_dt = T-1)例:2026-04-01 跑任务,biz_dt='2026-03-31',新数据生效日 =2026-04-01

    USE dw;

    -- 步骤1:加载当日增量(T-1日变更/新增用户)
    TRUNCATE TABLE tmp_user_level_delta;
    INSERT INTO tmp_user_level_delta
    SELECT
    user_id,
    user_name,
    member_level,
    charge_money
    FROM ods.ods_user_member_inc
    WHERE dt = '${biz_dt}'; -- 调度传参:前一日日期

    -- 步骤2:拉链闭环(保留不变+关闭旧记录+新增当前记录)
    INSERT OVERWRITE TABLE dw_user_level_zip

    -- ① 未发生变化的【当前有效旧数据】直接保留
    SELECT
    user_id,user_name,member_level,charge_money,
    start_dt,end_dt,is_current,dw_insert_dt
    FROM dw_user_level_zip
    WHERE is_current = 1
    AND user_id NOT IN (SELECT user_id FROM tmp_user_level_delta)

    UNION ALL

    -- ② 发生变化的用户:旧记录截止到biz_dt,置为失效
    SELECT
    user_id,user_name,member_level,charge_money,
    start_dt,
    '${biz_dt}' AS end_dt, -- 旧数据失效日=前一日
    0 AS is_current,
    dw_insert_dt
    FROM dw_user_level_zip
    WHERE is_current = 1
    AND user_id IN (SELECT user_id FROM tmp_user_level_delta)

    UNION ALL

    -- ③ 插入新的当前有效记录:生效日=biz_dt+1,永久有效
    SELECT
    user_id,
    user_name,
    member_level,
    charge_money,
    DateAdd('${biz_dt}',1) AS start_dt,
    '9999-12-31' AS end_dt,
    1 AS is_current,
    Current_Date AS dw_insert_dt
    FROM tmp_user_level_delta;

五、4. 常用查询模板(直接用)

① 查当前最新全量(报表 / 日常分析)

复制代码
SELECT * 
FROM dw_user_level_zip 
WHERE is_current = 1;

② 回溯任意历史时间点(比如看 2026-02-15 当时状态)

复制代码
SELECT *
FROM dw_user_level_zip
WHERE start_dt <= '2026-02-15'
  AND end_dt   >  '2026-02-15';

③ 查单个用户全生命周期变更记录

复制代码
SELECT *
FROM dw_user_level_zip
WHERE user_id = 'U10086'
ORDER BY start_dt ASC;

六、5. 配套规范 & 踩坑说明

  1. 严禁物理删除:拉链只改 end_dt、加新数据,不删历史
  2. 空值统一处理:等级 / 金额为空先在 ods 层兜底,避免拉链错乱
  3. Hive 必须开事务:否则 overwrite 会并发脏数据
  4. 长期累积数据:可按 end_dt 归档冷数据到历史分区表,提升查询速度
  5. 新增字段:直接加在拉链表末尾,初始化 + 增量同步都带上即可
相关推荐
王者鳜錸2 小时前
闲鱼商品自动发布实战:基于Java实现API轮询与批量上架
java·开发语言·python·商品自动发布
ZzzZZzzzZZZzzzz…2 小时前
MySQL备份还原方法1---mysqldump
linux·运维·数据库·mysql·还原备份
551只玄猫2 小时前
【数学建模 matlab 实验报告2】
开发语言·数学建模·matlab·课程设计·实验报告
麦聪聊数据2 小时前
企业数据流通与敏捷API交付实战(二):微服务取数与冗余CRUD
数据库·sql·低代码·微服务·restful
不愿透露姓名的大鹏2 小时前
SQL Server数据库的LDF文件过大的清理方式
数据库·sqlserver
Wyawsl2 小时前
MySQL高可用集群
数据库·mysql
尽兴-2 小时前
MySQL 与 Elasticsearch 数据一致性保障的四大主流方案
数据库·mysql·elasticsearch
liuyao_xianhui2 小时前
优选算法_岛屿数量_floodfill算法)_bfs_C++
java·开发语言·数据结构·c++·算法·链表·宽度优先
天行健,君子而铎2 小时前
政务行业高准确率、可控、符合规范的数据库审计与监测实践方案
网络·数据库·政务