3. 数据质量维度与治理指标设计

数据质量维度不是抽象口号,而是把“数据好不好用”拆成可定义、可计算、可追责的六个观察角度。在Databricks中,这六个维度最终都要落到三件东西上:一张表或一个字段、一条可执行的SQL或PySpark断言、一个随时间变化的指标值。只有同时具备这三者,维度才真正可治理。下面逐一说明每个维度在Databricks中的定义方式、典型度量表达式,以及结果如何判读。

完整性:该有的值不能缺

完整性衡量的是“应存在的数据是否真的存在”,通常分两个层次:行级完整性(应到达的记录是否到达)和列级完整性(关键字段是否为空)。在Databricks中,列级完整性最直接的度量是空值率:

SELECT
  COUNT(*) AS total_rows,
  SUM(CASE WHEN customer_id IS NULL THEN 1 ELSE 0 END) AS null_cnt,
  ROUND(SUM(CASE WHEN customer_id IS NULL THEN 1 ELSE 0 END) / COUNT(*), 4) AS null_rate
FROM prod.silver.orders;

假设某日 total_rows = 1,000,000,null_cnt = 2,500,则 null_rate = 0.25%。若治理阈值设定为“关键字段空值率 ≤ 0.1%”,则该指标未达标,应触发告警。行级完整性则常用“应到 vs 实到”对比,例如上游订单系统当日应产生 100 万条,Delta表实际写入 98.7 万条,行级完整率 = 98.7%。注意:完整性阈值必须按字段分级,主键、金额、时间字段通常要求 0 空值,而备注类字段可放宽。

准确性:值与真实世界是否一致

准确性最难直接度量,因为“真实值”往往不在库内。Databricks中常用三种可操作方式:参照比对(与权威源对账)、业务规则校验(值域、格式、勾稽关系)、统计异常检测(分布偏移)。例如订单金额应等于明细金额之和,可用勾稽规则度量:

SELECT COUNT(*) AS mismatch_cnt
FROM prod.silver.orders o
JOIN (
  SELECT order_id, SUM(amount) AS detail_sum
  FROM prod.silver.order_items GROUP BY order_id
) d ON o.order_id = d.order_id
WHERE ABS(o.total_amount - d.detail_sum) > 0.01;

若 mismatch_cnt = 37,总订单 100 万,则准确率 = 1 − 37/1,000,000 = 99.9963%。准确性指标通常以“违规记录数 / 总记录数”表达,并保留样本明细供人工复核。在Databricks中可结合 expectations(Lakeflow Declarative Pipelines 的期望)在写入时直接拦截或标记违规行。

一致性:跨表、跨系统是否说得通

一致性关注同一事实在不同位置是否一致,包括跨表一致性(订单表与客户表的外键匹配)、跨系统一致性(Delta表与上游Kafka/数据库对账)、格式一致性(日期、编码、币种统一)。典型度量是外键失配率:

SELECT COUNT(*) AS orphan_cnt
FROM prod.silver.orders o
LEFT JOIN prod.silver.customers c ON o.customer_id = c.customer_id
WHERE c.customer_id IS NULL;

若 orphan_cnt = 120,则外键一致率 = 1 − 120/1,000,000 = 99.988%。一致性还常表现为“同一指标两个口径对不上”,例如财务口径GMV与业务口径GMV差异超过 0.5% 即视为不一致。治理上应把口径定义写入Unity Catalog的列注释或指标视图,避免各写各的SQL。

及时性:数据是否在需要时可用

及时性衡量数据从产生到可用的延迟,以及是否在SLA内完成。Databricks中可用Delta表历史(DESCRIBE HISTORY)或审计日志提取写入时间,计算数据新鲜度和SLA达成率:

SELECT
  MAX(_commit_timestamp) AS last_commit,
  TIMESTAMPDIFF(MINUTE, MAX(_commit_timestamp), CURRENT_TIMESTAMP()) AS lag_minutes
FROM prod.silver.orders;

假设SLA要求“每日 07:00 前完成T+1数据就绪”,实际最近提交时间为 07:42,则当日延迟 42 分钟,SLA未达成。及时性指标应记录延迟分钟数和近30天SLA达成率,例如 30 天中 28 天按时,达成率 93.3%。注意区分“数据产生时间”“入湖时间”“加工完成时间”三个时间戳,否则延迟会被低估。

唯一性:同一实体是否只出现一次

唯一性针对主键或业务键,度量重复记录的比例。在Delta表中可用窗口函数或 GROUP BY ... HAVING COUNT(*) > 1 检测:

SELECT COUNT(*) AS dup_keys FROM (
  SELECT order_id FROM prod.silver.orders
  GROUP BY order_id HAVING COUNT(*) > 1
);

若 dup_keys = 8,唯一率 = 1 − 8/1,000,000 = 99.9992%。唯一性还常与幂等写入相关:使用 MERGE INTO 按主键更新可避免重复累积。若重复率突然上升,往往意味着上游重跑或流式任务重复消费,应结合 _commit_version 排查。

有效性:值是否符合既定格式与规则

有效性检查值是否落在允许的集合、格式或范围内,例如邮箱格式、枚举值、日期范围、金额非负。Databricks中可用正则和范围条件度量:

SELECT
  SUM(CASE WHEN email NOT RLIKE '^[^@]+@[^@]+\\.[^@]+$' THEN 1 ELSE 0 END) AS bad_email,
  SUM(CASE WHEN status NOT IN ('NEW','PAID','SHIPPED','CLOSED') THEN 1 ELSE 0 END) AS bad_status
FROM prod.silver.orders;

若 bad_email = 300、bad_status = 15,则有效率分别为 99.97% 和 99.9985%。有效性规则应集中维护,例如放入Unity Catalog的约束或质量规则表,避免散落在各任务中。

Databricks 数据质量六维度:定义 → 度量 → 判定 prod.silver.orders Delta 表 · 1,000,000 行(示例) ① 完整性 度量:空值率 / 行到达率 null_rate = 2,500 / 1,000,000 结果:0.25% 判定:阈值 ≤0.1% → 未达标 ② 准确性 度量:勾稽违规数 / 参照比对 mismatch_cnt = 37 结果:准确率 99.9963% 判定:达标,保留样本复核 ③ 一致性 度量:外键失配 / 口径差异 orphan_cnt = 120 结果:一致率 99.988% 判定:达标,口径需登记 ④ 及时性 度量:新鲜度 / SLA达成率 lag = 07:42 − 07:00 = 42 min 结果:30天达成 28/30 = 93.3% 判定:当日 SLA 未达成 ⑤ 唯一性 度量:重复主键数 / 幂等写入 dup_keys = 8 结果:唯一率 99.9992% 判定:达标,排查重跑来源 ⑥ 有效性 度量:格式/枚举/范围违规率 bad_email=300, bad_status=15 结果:有效率 99.97% / 99.9985% 判定:达标,规则集中维护

把六个维度组织成可运行的治理指标

六个维度单独看并不难,难的是让它们在同一套机制里持续运行。推荐在Databricks中采用“规则表 + 调度任务 + 指标表 + 告警”的结构:把每个维度的检查SQL、阈值、责任人和告警级别登记到一张质量规则表(例如 governance.dq_rules),由Databricks Workflows按日调度执行,结果写入 governance.dq_metrics,字段至少包含 rule_id、table_name、dimension、metric_value、threshold、status、run_time。这样每个维度都有历史趋势,可以回答“上周完整性为什么掉了”这类问题。

阈值设定要避免“一刀切”。建议按字段重要度分级:主键、金额、时间字段用严格阈值(如空值率 0、唯一率 100%),一般属性字段用宽松阈值(如空值率 ≤ 5%)。同时区分阻断型与告警型规则:阻断型在写入时用期望直接拒绝,告警型只记录并通知。下面是一份可直接参考的规则登记示例:

维度检查对象度量表达式(示例)阈值级别
完整性orders.customer_idnull_rate≤ 0.1%告警
准确性orders.total_amount勾稽违规率≤ 0.01%阻断
一致性orders.customer_id → customers外键失配率≤ 0.05%告警
及时性silver.orders 日批完成延迟分钟≤ 0 min(07:00前)告警
唯一性orders.order_id重复主键数= 0阻断
有效性orders.status枚举违规率≤ 0.01%告警
在Databricks中,可以把上述规则封装为参数化函数,例如 dq.null_rate(table, column)、dq.dup_key_rate(table, key),由规则表驱动调用,避免为每张表重复写SQL。指标结果建议同时写入Delta表并暴露为Databricks SQL Dashboard,让业务方直接看到六个维度的趋势。
常见误区:把“有效性”当成“准确性”。格式正确不等于值真实,例如邮箱格式合法但属于已注销用户。准确性必须依赖外部参照或业务勾稽,不能只靠正则。另一个误区是只统计不闭环——指标算出来却没有责任人、没有阈值、没有告警,维度就退化成报表数字。

最后要强调:六个维度不是并列孤立的。完整性差会拉低准确性(空值参与计算导致偏差),唯一性差会破坏一致性(同一实体两条记录对不上),及时性差会让准确性失去意义(过期数据再准也没用)。因此在Databricks中设计治理指标时,应把六维度放在同一张指标宽表里按 table_name + run_date 对齐,观察它们之间的联动,而不是各自为政。这样,数据质量才从“检查项”变成“可运营的治理体系”。