数据质量六维指标体系:从理论到实战
做数据质量,说白了就是回答六个问题。我做了这么多年数据治理,发现不管业务多复杂,最终都能归到这六个维度上。今天咱们就一个一个拆开聊。
完整性:数据有没有缺胳膊少腿?
完整性是最基础的要求。字段不能为空,记录不能丢失,这就是完整性的核心。
我记得刚入行时接手一个用户画像项目,跑出来一看,30%的用户手机号是空的。业务方直接炸了——营销短信发不出去啊。后来一查,是上游采集系统有个字段没做非空校验。
完整性检查的三种场景:
- 字段级完整性:某个字段是否为空,比如手机号、身份证号
- 记录级完整性:某条记录是否完整,比如订单必须有商品ID+价格+时间
- 表级完整性:两张表之间的关联记录是否匹配,比如订单表有1000条,但支付表只查到980条
实际项目中,我习惯用SQL先跑一轮空值检查:
-- 字段级完整性检查
SELECT
COUNT(*) AS total_rows,
COUNT(phone) AS phone_filled,
COUNT(email) AS email_filled,
ROUND(100.0 * COUNT(phone) / COUNT(*), 2) AS phone_completeness_pct
FROM user_profile;
我的经验:完整性阈值不要一刀切。核心业务字段(如订单金额)要求100%,辅助字段(如用户昵称)可以放宽到80%。我曾经见过一个团队把所有字段都设成99%,结果天天报警,最后没人看了。
准确性:数据对不对?
完整性只解决「有没有」,准确性解决「对不对」。数据存在,但值是错的,比没有更可怕。
举个例子:用户年龄字段填了「-5岁」,或者订单金额多了两个零。这种数据你用了,决策就歪了。
准确性检查通常依赖规则引擎或参照数据:
-- 准确性检查:年龄必须在0-120之间
SELECT
user_id,
age,
CASE
WHEN age < 0 OR age > 120 THEN '异常'
ELSE '正常'
END AS accuracy_status
FROM user_profile
WHERE age IS NOT NULL;
避坑指南:我曾经遇到过一个客户,他们的「性别」字段只有「男」和「女」两个值,但数据里出现了「未知」「保密」「其他」——这些值本身没错,但业务规则没定义清楚。准确性检查的前提是:你得先定义什么是「正确」。
一致性:数据打架怎么办?
同一个用户,CRM系统里叫「张三」,订单系统里叫「张先生」。同一个商品,库存系统里编码是「A001」,电商系统里是「ITEM-001」。这就是一致性问题。
一致性检查的核心是跨系统、跨表、跨字段的比对:
| 对比维度 | 检查内容 | 常见问题 |
|---|---|---|
| 同名同义 | 相同含义的字段在不同系统中值是否一致 | 用户姓名、商品编码、订单状态 |
| 同名异义 | 相同字段名在不同系统中含义是否一致 | 「状态」字段:A系统=订单状态,B系统=支付状态 |
| 异名同义 | 不同字段名是否指向同一业务含义 | 「客户ID」vs「用户编号」 |
我个人习惯在数据仓库层做一致性校验,因为这里数据已经过ETL清洗,比较起来更干净:
-- 跨系统一致性检查:用户姓名是否一致
SELECT
a.user_id,
a.user_name AS crm_name,
b.user_name AS order_name,
CASE
WHEN a.user_name != b.user_name THEN '不一致'
ELSE '一致'
END AS consistency_status
FROM crm_user a
JOIN order_user b ON a.user_id = b.user_id;
及时性:数据来得够快吗?
数据再准再全,如果来得太晚,就是废纸。及时性衡量的是数据从产生到可用的时间差。
你想想看,双十一的实时大屏,延迟超过5分钟,运营团队就抓瞎了。但如果是月度财务报表,T+1天完全能接受。
及时性指标定义:
- 数据延迟:业务发生时间 vs 数据入库时间
- ETL耗时:从源系统抽取到目标表可查询的时间
- 时效达标率:在约定时间内完成的数据批次占比
-- 及时性检查:计算数据延迟
SELECT
batch_id,
business_time,
load_time,
TIMESTAMPDIFF(MINUTE, business_time, load_time) AS delay_minutes,
CASE
WHEN TIMESTAMPDIFF(MINUTE, business_time, load_time) <= 60 THEN '达标'
ELSE '超时'
END AS timeliness_status
FROM data_load_log;
我的建议:及时性阈值要和业务方一起定。我曾经帮一个金融客户做实时风控,业务方说「越快越好」,结果我们设了1秒延迟,运维成本翻了3倍。后来坐下来一聊,其实5秒以内他们就能接受。所以,别自己拍脑袋。
唯一性:数据重复了吗?
唯一性就是去重。同一个用户注册了两次,同一个订单生成了两条记录——这种问题在数据集成时特别常见。
唯一性检查通常依赖主键或业务唯一键:
-- 唯一性检查:查找重复的用户ID
SELECT
user_id,
COUNT(*) AS dup_count
FROM user_profile
GROUP BY user_id
HAVING COUNT(*) > 1;
嗯,这里要注意:唯一性不等于主键约束。主键约束是数据库层面的强制规则,唯一性检查是数据质量层面的主动发现。有些系统没有设主键,或者主键设错了,就得靠质量检查来兜底。
我曾经踩过的坑:一个客户说他们的订单表主键是「order_id」,结果我发现同一个order_id对应了不同的用户。后来一查,他们的订单系统在分库分表时,主键生成逻辑有bug。所以,别信系统说的「我们有主键」,自己跑一遍唯一性检查最靠谱。
规范性:数据格式统一吗?
规范性是最后一个维度,也是最容易被忽略的。数据格式、编码规则、命名规范是否统一?
举个例子:日期格式,有的用「2024-01-01」,有的用「2024/01/01」,有的用「01/01/2024」。手机号,有的带「+86」,有的不带。这些数据在人工看的时候没问题,但机器处理起来就头疼了。
规范性检查通常用正则表达式或枚举值匹配:
-- 规范性检查:手机号格式是否规范
SELECT
user_id,
phone,
CASE
WHEN phone REGEXP '^1[3-9]\\d{9}$' THEN '规范'
ELSE '不规范'
END AS format_status
FROM user_profile;
| 数据项 | 规范格式 | 不规范示例 |
|---|---|---|
| 手机号 | 11位数字,1开头 | +8613800138000、138-0013-8000 |
| 日期 | YYYY-MM-DD | 2024/01/01、01-01-2024 |
| 金额 | 保留两位小数 | 100、100.0、100.000 |
| 邮箱 | 符合RFC 5322 | abc、abc@、@abc.com |
我的习惯:规范性检查最好在数据入库时就做,别等到分析阶段再处理。我一般会在ETL流程里加一个「格式清洗」步骤,把不规范的数据先标准化,再写入目标表。这样下游用起来就省心了。
六维关系:一张图看懂
这六个维度不是孤立的,它们之间有依赖关系。我画了张图,帮你理清思路:
从这张图你能看出来,六个维度其实有个隐含的顺序。我个人习惯先做完整性和准确性,这是地基。地基打好了,再去看一致性和及时性。唯一性和规范性更像是贯穿始终的「保洁工作」,随时都要做。