首页/数据/数据工程与 ETL 速查/粒度声明与唯一键校验

粒度声明与唯一键校验

粒度声明回答一行代表什么,并以主键或唯一键固化:订单明细用订单号加明细序号,日快照用日期加实体键;没有唯一键的表几乎必然产生重复数据。

粒度声明是什么

粒度声明用一句话回答「这张表的一行代表什么」,并以主键或唯一键固化下来:订单明细用订单号加明细序号,日快照用日期加实体键,流水用流水号。粒度一旦含糊,下游必然按各自理解去聚合,重复计数、口径打架、对账失败都会从这里开始。粒度也是维度建模的起点——先定粒度,再选维度、再选度量,顺序不能颠倒。

基本信息

声明位置建表注释、数据字典、任务说明三处保持一致
固化方式主键、唯一键约束,或加工中的确定性去重逻辑
常见粒度事件级、明细行级、日快照级、月汇总级
验证方法按业务键分组计数,结果应恒等于 1
变更影响粒度变化等于表语义变化,必须同步下游口径说明

典型使用场景

  • 建表评审:先写清一行代表什么,再讨论字段与索引
  • 数据异常定位:结果翻倍时先查粒度是否被打破
  • 上游变更评估:源表从明细变汇总会直接改变下游可用粒度
  • 对账与审计:粒度是比行数和校验和更根本的对齐基准
  • 血缘与文档治理:数据字典中的粒度字段是下游自助取数的前提

粒度校验 SQL

粒度校验 SQL
-- 明细表:订单号 + 明细序号 组合应唯一,正常结果为空
SELECT order_id, item_no, COUNT(1) AS c
FROM dwd_trade_order_detail_di
WHERE dt = '2026-10-11'
GROUP BY order_id, item_no
HAVING COUNT(1) > 1
LIMIT 50;

-- 快照表:日期 + 实体键 应唯一
SELECT dt, product_sk, warehouse_sk, COUNT(1) AS c
FROM fact_inventory_daily
WHERE dt = '2026-10-11'
GROUP BY dt, product_sk, warehouse_sk
HAVING COUNT(1) > 1
LIMIT 50;

常见表粒度对照

表类型一行代表什么业务唯一键
事务事实表一次业务事件单据号 或 交易流水号
明细事实表单据中的一行商品单据号 + 行号
周期快照表某周期某实体的状态日期 + 实体键
累积快照表一个流程全生命周期流程实例号
维表一个实体的当前或历史版本代理键(历史用 代理键 + 生效时间)
把粒度校验做成每日例行稽核并接入告警,能在上游变更导致重复时当天发现,而不是等财务报表对不上才回溯。
汇总表若只写字段不写粒度,下游很容易按明细口径关联使用,一笔订单被多次计数,错误会一路上浮到经营指标。

易错点

  • 明细表没有唯一键约束,上游重跑叠加出重复行,指标虚高且难以追溯是哪天开始脏的
  • 粒度升级(明细变汇总)时未同步更新下游口径说明,取数方按旧粒度关联导致重复计数
  • 把「主键唯一」当成「业务唯一」:物理主键是代理键,业务重复照样存在
  • 去重逻辑依赖 ROW_NUMBER 但不指定确定性排序字段,重跑结果不稳定
  • 数据字典里的粒度描述与建表注释不一致,新人按注释取数直接踩坑

数据来源与参考

  • Kimball《The Data Warehouse Toolkit》粒度声明
  • 行业数仓建模规范
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌