有效性校验是什么
有效性检查取值是否落在合法范围内:枚举字段有没有字典外的值、数值是否处于业务合理区间、字符串格式是否符合约定(手机号、日期、编码位数)。它的特点是规则明确、可完全自动化,因此最适合放在 DWD 层做入库拦截:把脏数据挡在公共层之外,比事后到报表上排查便宜得多。
基本信息
| 枚举 | 状态、渠道、类型等字段的合法取值集合,需维护字典 |
|---|---|
| 范围 | 金额非负、比例在 0 到 1 之间、年龄在合理区间 |
| 格式 | 手机号、日期字符串、编码位数、统一社会信用代码 |
| 引用完整性 | 外键值必须能在维表或字典表中找到 |
| 处置策略 | 字典外取值告警、计数并转 unknown,不静默丢弃 |
| 适用平台 | Hive、Spark SQL、MySQL、Flink SQL 均可用正则与集合判定 |
典型使用场景
- 上游新增枚举值:源端加了状态码,DWD 未同步字典,需要立即发现
- 格式变更:源端手机号或编码格式调整,正则校验可第一时间暴露
- 外键有效性:订单里的商品号在商品维中不存在,提前拦截避免关联丢行
- 入库拦截:DWD 加工时对不合规行打标,防止脏数据流入公共层
- 字典治理:定期输出字典外取值清单,反向推动源端与字典同步更新
取值分布与字典比对
取值分布与字典比对
-- 列出各状态取值与占比,出现字典外取值即异常
SELECT status_name, COUNT(1) AS cnt,
ROUND(COUNT(1) / SUM(COUNT(1)) OVER (), 4) AS ratio
FROM dwd_trade_order_detail_di
WHERE dt = '2026-10-11'
GROUP BY status_name
ORDER BY cnt DESC;
-- 与字典表比对,直接列出字典外的值
SELECT DISTINCT d.status_name
FROM dwd_trade_order_detail_di d
LEFT JOIN dim_order_status_dict c ON d.status_name = c.status_name
WHERE d.dt = '2026-10-11' AND c.status_name IS NULL;范围与格式校验
范围与格式校验
-- 范围 + 格式一次扫描,输出不合规行数
SELECT COUNT(1) AS bad_rows
FROM dwd_trade_order_detail_di
WHERE dt = '2026-10-11'
AND (pay_amount < 0
OR (phone IS NOT NULL AND phone NOT RLIKE '^1[3-9][0-9]{9}$')
OR (discount_rate IS NOT NULL AND (discount_rate < 0 OR discount_rate > 1)));
-- 按类型分别计数,便于定位是哪类规则被触发
SELECT SUM(CASE WHEN pay_amount < 0 THEN 1 ELSE 0 END) AS neg_amt,
SUM(CASE WHEN phone IS NOT NULL AND phone NOT RLIKE '^1[3-9][0-9]{9}$' THEN 1 ELSE 0 END) AS bad_phone
FROM dwd_trade_order_detail_di WHERE dt = '2026-10-11';规则类型与处置
| 类型 | 示例 | 建议处置 |
|---|---|---|
| 枚举 | 状态码出现字典外值 | 告警 + 转 unknown,同时更新字典 |
| 范围 | 金额为负、比例超 1 | 告警并阻断下游,需业务确认 |
| 格式 | 手机号位数不对、日期串非法 | 告警,按规则清洗或置空 |
| 引用完整性 | 商品号在维表不存在 | 转未知成员,禁止留空导致丢行 |
字典外取值不要静默丢弃:先落档并计数,再按策略清洗。直接丢掉的代价是问题线索永久消失,几个月后没人知道当初为什么少了一批数据。
枚举字典要与源端同步更新:源端上线新状态码而校验字典未更新时会产生大量误报,团队很快就会忽略这类告警,真正的脏数据也一起被忽略。