hashdiff 是什么
hashdiff(哈希差异列)把需要跟踪变更的属性按固定顺序拼成一个字符串再取哈希,作为一列存在维表上。更新时只比较新旧 hashdiff 是否相等,就能判断成员属性有没有变,省掉逐列书写比较条件。SCD2 拉链更新、增量同步与数据质量比对都靠它做变更检测。它只回答「变没变」,不回答「哪一列变了」。
基本信息
| 拼接方式 | 跟踪属性按固定顺序 concat,空值先占位 |
|---|---|
| 算法 | md5(32位)、sha1(40位)、sha256(64位) 均可,全链路统一 |
| 存储 | varchar 或 char,长度与算法输出等长 |
| 比较语义 | 相等=未变更,不等=有变更,NULL 视为未计算 |
| 生成时机 | 抽取层或 staging 层统一生成,维表只接收结果 |
典型使用场景
- SCD2 拉链更新:只对哈希变化的成员关闭旧行、开新版本行
- 增量入仓:源表全量抽取后按哈希挑出真正变化的行
- 数据质量比对:上下游两份数据按哈希快速定位差异成员
- 多列去重:宽表按业务键去重时的变更判断
- 变更审计:版本行留一列 hashdiff,便于回溯每次记录的变化
- 口径回归:口径调整前后各算一次哈希,量化受影响范围
hashdiff 生成
hashdiff 生成
-- 拼接顺序与占位符全局统一;改动等于全量误判
SELECT id,
md5(concat_ws('|',
coalesce(name, '#'),
coalesce(phone, '#'),
coalesce(tier, '#'))) AS hashdiff
FROM stg_user; -- 空值统一占位,避免 NULL 传染整个哈希常见写法对照
| 写法 | 说明 | 风险 |
|---|---|---|
| concat_ws + coalesce | 分隔符固定,空值占位 | 值里出现分隔符会串位,需确认值域 |
| concat 直接拼 | 不处理 NULL | 任一列为 NULL 则整行结果为 NULL,变更永远测不到 |
| 先 to_date/to_char 再拼 | 消除格式差异 | 日期格式不统一仍会误判 |
| 按表结构列序全拼 | 属性直接按存储顺序拼 | 加字段后顺序漂移,一夜全量变更 |
增量落地
增量落地
-- 1) 只取哈希变化或新增的成员
SELECT s.id, s.hashdiff
FROM stg_user s
LEFT JOIN dim_user d
ON s.id = d.user_id_nk
AND d.is_current = 1
WHERE d.user_sk IS NULL
OR s.hashdiff <> d.hashdiff;
-- 2) 跑完看变更率是否合理,异常升高说明拼接口径变了哈希只做「变没变」的判断,若要排查具体差异,仍需保留一份原值快照或 staging 数据。md5 在维表规模下碰撞概率可忽略;审计要求强一致时改用 sha256,并保留拼接明文以便复算。