数据质量出了问题怎么发现?——完整性、准确性、一致性、及时性四性体系
先说结论
数据质量可以用四个维度来衡量,简称「四性」:完整性(数据有没有丢)、准确性(数据对不对)、一致性(多个系统是否对得上)、及时性(数据有没有按时到)。
治理的核心不是「出了问题再修」,而是建立自动化的监控和拦截机制,在数据进入下游之前就发现问题。这就像工厂的质检流程——不是等产品卖出去再召回,而是在生产线上就拦住不合格品。
落地的关键是分层校验:ODS层校验完整性,DWD层校验准确性,DWS/ADS层校验一致性,全链路监控及时性。
先把这段讲顺;面试官追问时,再展开下面的原理和细节。
详细讲解
数据质量是数据治理的核心。面试官问你「怎么保证数据质量」的时候,如果你只说「写个校验脚本」,那基本上拿不到高分。面试官想听的是你有一套体系化的思路,能覆盖数据生命周期的各个阶段。这道题我在准备面试时反复打磨过答法,因为几乎每轮面试都会问到。
实战场景:我在出海硬件公司搭建的数据质量体系
我在某知名出海硬件品牌做数据平台时,刚接手的时候数据质量问题非常多——业务每周至少反馈2-3个「数据不准」的问题。有一次,市场部用我们的报表去做广告投放决策,结果某个国家的用户量被统计少了30%,直接导致那个区域的广告预算被砍。老板很火,我们复盘后发现是某个埋点事件的上报丢失了。
这件事之后,我花了两个月搭了一套完整的数据质量监控体系。核心思路就是按「四性」分别设计校验规则,每层数据都有对应的检查点。
-- 完整性校验:检查今天的数据量是否异常
-- 如果比昨天少了20%以上,就触发告警
SELECT
ds,
COUNT(*) AS row_cnt,
LAG(COUNT(*), 1) OVER (ORDER BY ds) AS prev_cnt,
ROUND((COUNT(*) - LAG(COUNT(*), 1) OVER (ORDER BY ds))
* 100.0 / LAG(COUNT(*), 1) OVER (ORDER BY ds), 2) AS change_pct
FROM ods_user_event
WHERE ds >= DATE_SUB(CURRENT_DATE, 7)
GROUP BY ds
ORDER BY ds;
-- 如果change_pct < -20,发送钉钉/飞书告警
这个SQL我每天凌晨4点跑一次,检查过去7天的数据趋势。如果波动超过阈值,自动发告警到数据质量群。
四性详解:每个维度怎么检查
① 完整性(Completeness):数据有没有丢、有没有缺字段。最常见的问题是:某个时间段的数据没上报,或者关键字段是NULL。
-- 完整性校验:关键字段NULL率检查
SELECT
ds,
COUNT(*) AS total,
SUM(CASE WHEN user_id IS NULL THEN 1 ELSE 0 END) AS null_user_id,
SUM(CASE WHEN event_time IS NULL THEN 1 ELSE 0 END) AS null_event_time,
SUM(CASE WHEN country IS NULL THEN 1 ELSE 0 END) AS null_country,
ROUND(SUM(CASE WHEN user_id IS NULL THEN 1 ELSE 0 END)
* 100.0 / COUNT(*), 2) AS null_rate_pct
FROM dwd_user_event
WHERE ds = '${bizdate}'
GROUP BY ds;
-- null_rate_pct > 5% 就需要排查
② 准确性(Accuracy):数据的值是否在合理范围内。比如年龄不应该是负数,订单金额不应该是0,经纬度不应该超出范围。
-- 准确性校验:值域检查
SELECT
ds,
SUM(CASE WHEN age < 0 OR age > 150 THEN 1 ELSE 0 END) AS invalid_age,
SUM(CASE WHEN amount <= 0 THEN 1 ELSE 0 END) AS invalid_amount,
SUM(CASE WHEN latitude < -90 OR latitude > 90 THEN 1 ELSE 0 END) AS invalid_lat,
SUM(CASE WHEN event_time > NOW() THEN 1 ELSE 0 END) AS future_events
FROM dwd_order_detail
WHERE ds = '${bizdate}';
-- 任何一项 > 0 都需要排查数据源
③ 一致性(Consistency):同一份数据在不同系统、不同层级是否一致。比如ODS层的订单数和DWS层聚合后的订单数应该对得上。
-- 一致性校验:跨层数据对账
SELECT
a.ds,
a.ods_cnt,
b.dws_cnt,
a.ods_cnt - b.dws_cnt AS diff,
ROUND(ABS(a.ods_cnt - b.dws_cnt) * 100.0 / a.ods_cnt, 2) AS diff_pct
FROM (
SELECT ds, COUNT(*) AS ods_cnt FROM ods_order WHERE ds = '${bizdate}' GROUP BY ds
) a
JOIN (
SELECT ds, SUM(order_cnt) AS dws_cnt FROM dws_order_daily WHERE ds = '${bizdate}' GROUP BY ds
) b ON a.ds = b.ds;
-- diff_pct > 1% 说明某一层处理有问题
④ 及时性(Timeliness):数据是否按时产出。离线任务有没有延迟?实时数据的延迟是多少?我在出海硬件公司设了SLA:核心报表每天早上8点前必须产出,延迟超过30分钟就告警。
分层校验体系
| 数仓层级 | 校验重点 | 典型规则 | 告警方式 |
|---|---|---|---|
| ODS | 完整性 | 行数波动<20%、关键字段NULL率<5% | 钉钉/飞书群消息 |
| DWD | 准确性 | 值域检查、格式校验、去重检查 | 邮件+即时消息 |
| DWS | 一致性 | 跨层对账、指标交叉验证 | 邮件报告 |
| ADS | 一致性+及时性 | 与业务系统对账、产出时间监控 | 电话+短信(紧急) |
核心原则是:越靠近上游,校验越严格。ODS层如果数据就有问题,后面的DWD、DWS全部会受影响。所以我们的规则是:ODS校验不通过,下游任务不启动。
自动化监控架构
光有校验SQL还不够,关键是要自动化运行、自动告警、有人跟进。我们的做法是:
1. 校验规则配置化:把所有校验规则存在一张元数据表里(rule_id, table_name, check_type, threshold, alert_level),不用每次改代码。
2. 调度系统集成:在DataWorks里,每个核心任务后面都挂一个质量检查节点。任务跑完自动触发校验。
3. 分级告警:Warning级别发群消息,Critical级别打电话。避免告警疲劳。
# 数据质量检查框架伪代码
def run_quality_check(table_name, ds):
rules = get_rules_from_meta(table_name) # 从元数据表获取规则
results = []
for rule in rules:
if rule.check_type == 'completeness':
result = check_row_count(table_name, ds, rule.threshold)
elif rule.check_type == 'accuracy':
result = check_value_range(table_name, ds, rule.column, rule.min, rule.max)
elif rule.check_type == 'consistency':
result = check_cross_layer(table_name, rule.target_table, ds)
results.append(result)
# 根据结果发送告警
failed = [r for r in results if not r.passed]
if failed:
send_alert(table_name, failed, level=max(r.level for r in failed))
面试高频追问
追问一:数据质量问题发现了之后怎么修?
分两种情况。如果是ODS层数据源的问题(比如埋点丢失),需要联系上游修复后重新导入,这叫「数据回补」。如果是ETL逻辑的问题(比如JOIN条件写错了),修复逻辑后重跑下游任务即可。关键是要有幂等设计——重跑不会产生重复数据。我们的做法是全部用INSERT OVERWRITE,不用INSERT INTO,这样重跑是安全的。
追问二:校验规则太多会不会影响任务执行效率?
会的,所以要分级。核心表(影响报表的)做全量校验,非核心表只做行数和NULL率的轻量校验。我们在出海硬件公司有300+张表,但全量校验的只有50张核心表,其余的只做基本检查。全量校验的SQL一般在30秒内跑完,不会成为瓶颈。
追问三:你怎么衡量数据质量治理的效果?
我们用三个指标:① 数据质量问题工单数(从每周5-6个降到每月1-2个);② 核心报表准时率(从85%提升到99%);③ 校验覆盖率(核心表100%覆盖)。这些数字每月汇报给领导,让他们看到治理的价值。
实战踩坑
我在某知名出海硬件品牌做数据质量监控时,有一次踩了一个大坑。我们的完整性校验规则是「今天行数不能比昨天少20%」。结果有一个周末,业务正好搞了一个大促活动,数据量暴涨了3倍。等周一恢复正常后,校验规则判断「比昨天少了70%」,疯狂告警。
这个事故教会我:简单的环比校验不靠谱,需要考虑业务周期性。后来我改成了「同比」校验——跟上周同一天比,同时设了一个「绝对值下限」,低于这个下限才告警。
-- 改进后的完整性校验:同比+绝对值双重判断
SELECT
today.ds,
today.cnt AS today_cnt,
last_week.cnt AS last_week_cnt,
ROUND((today.cnt - last_week.cnt) * 100.0 / last_week.cnt, 2) AS wow_change_pct
FROM
(SELECT ds, COUNT(*) AS cnt FROM ods_event WHERE ds = '${bizdate}' GROUP BY ds) today
LEFT JOIN
(SELECT ds, COUNT(*) AS cnt FROM ods_event WHERE ds = DATE_SUB('${bizdate}', 7) GROUP BY ds) last_week
ON 1 = 1;
-- 告警条件:wow_change_pct < -30 AND today_cnt < 10000(绝对值下限)
解决方案:改成同比+绝对值双重校验后,误报率从每周3-4次降到了接近0。这个经验后来也沉淀成了我们的校验规则模板,所有新表接入时默认使用同比校验。
总结
数据质量治理的核心是「四性」体系:完整性、准确性、一致性、及时性。落地的关键是分层校验+自动化监控+分级告警。面试时能说出「四性」框架,再结合具体的校验SQL和实际的监控架构来讲,就很有深度。记住一句话:好的数据质量不是靠人盯出来的,是靠机制保证的。
下一篇聊一个让很多数据团队头疼的问题:上游表字段突然改了,下游全挂了——数据血缘到底怎么用?
你们公司的数据质量监控是怎么做的?有没有踩过类似的坑?评论区聊聊~
关注「Wood聊大数据」| 9年大数据老兵,聊技术、聊职场、聊成长