首页/数据/数仓建模速查/事实表粒度测试方法
维度与事实设计149 条

事实表粒度测试方法

粒度声明后必须用测试验证:主键去重后行数是否相等、同键是否多行、空主键占比;测试 SQL 固化进交付物。

数仓建模速查数据更新于 2026-10-13

粒度为什么要测

粒度是事实表的定义性属性:声明「一行代表什么」之后,必须用数据证明这句话成立。粒度测试聚焦主键唯一性与空值率——如果订单号本该唯一却出现重复,所有基于这张表的金额与计数都会虚高,而且越往后越难判断重复是在哪一步引入的。

基本信息

测试对象事实表的主键或业务唯一键
核心断言总行数等于去重后的键数量
辅助断言键空值率、重复行分布、样例行抽查
运行时机上线验收、重大变更回归、每日质量巡检
落地形态SQL 化并纳入调度,结果留档作为验收证据

典型使用场景

  • 建模评审:用测试结果证明粒度声明成立,而不是只在设计文档里写一句话
  • 上线验收:新表首次全量后跑一轮,作为交付验收的硬证据留存
  • 变更回归:上游口径或关联条件改动后重跑,防止重复行回流
  • 日常巡检:接入质量平台,重复率超过阈值自动告警到责任人
  • 问题定位:下游数字虚高时先跑粒度测试,区分数据重复与口径不同两类原因

粒度校验 SQL

粒度校验 SQL
-- 一条 SQL 同时给出重复与空键两类问题
SELECT
  count(1) AS rows_all COMMENT '分区总行数',
  count(DISTINCT order_id) AS rows_distinct COMMENT '去重后键数',
  count(1) - count(DISTINCT order_id) AS dup_rows COMMENT '重复行数',
  sum(CASE WHEN order_id IS NULL OR trim(order_id) = '' THEN 1 ELSE 0 END) AS null_key_rows
FROM dwd_order
WHERE dt = '2026-10-12';

结果逐列读法

列含义正常与异常
rows_all分区总行数应与上游单据数同量级,差异需要解释
rows_distinct去重后的键数量应等于总行数,小于即存在重复
dup_rows重复行数大于 0 必须按来源与时间定位
null_key_rows主键为空或空串的行数大于 0 会集中落到未知成员上
重复行还要看分布:集中在某几个来源系统或某几个小时,通常能直接指向重跑、双写或关联放大中的具体环节,比逐行查样例快得多。
粒度测试只证明键唯一,不证明数据完整;完整性要用上游单据数与金额对账另外补齐,两件事不能互相替代。

易错点

  • 只测总量不测唯一键:行内重复与漏行互相抵消,总量看起来正确,问题被掩盖
  • 测试写在临时 SQL 里不落库:人员变动后测试消失,回归时无人知道该跑什么
  • 空主键行不设规则:关联维度时集中落到未知成员,指标被归入未知类目却无人发现
  • 只在全量跑测试:增量分区被跳过,而重复往往正是增量写入引入的
  • 把重复行直接去重当修复:上游重发问题依旧存在,下次加载还会再重复一遍

数据来源与参考

  • 数仓测试实践:粒度校验
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌