数据质量六维指标体系:从理论到实战

做数据质量,说白了就是回答六个问题。我做了这么多年数据治理,发现不管业务多复杂,最终都能归到这六个维度上。今天咱们就一个一个拆开聊。

完整性:数据有没有缺胳膊少腿?

完整性是最基础的要求。字段不能为空,记录不能丢失,这就是完整性的核心。

我记得刚入行时接手一个用户画像项目,跑出来一看,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流程里加一个「格式清洗」步骤,把不规范的数据先标准化,再写入目标表。这样下游用起来就省心了。

六维关系:一张图看懂

这六个维度不是孤立的,它们之间有依赖关系。我画了张图,帮你理清思路:

数据质量六维指标体系 数据质量 完整性 准确性 一致性 及时性 唯一性 规范性 六个维度层层递进 先保证完整性 → 再检查准确性 → 然后做一致性 → 同时关注及时性 → 最后去重和规范

从这张图你能看出来,六个维度其实有个隐含的顺序。我个人习惯先做完整性和准确性,这是地基。地基打好了,再去看一致性和及时性。唯一性和规范性更像是贯穿始终的「保洁工作」,随时都要做。