指标定义与分层:原子指标、派生指标、复合指标的定义与分层策略
做实时指标看板,最怕什么?
我见过太多团队,一上来就堆 SQL,把几十个指标塞进一张大宽表。结果呢?业务方说「这个销售额怎么跟报表对不上」,开发说「我改一个口径要改 8 个地方」。说白了,指标没有分层,就是给自己挖坑。
这一章,我跟你聊聊指标的分层策略。原子指标、派生指标、复合指标,这三层怎么定义、怎么落地,咱们一个一个说清楚。
1. 原子指标:不可再拆的业务度量
原子指标,是业务过程中最基础的度量单位。它不能再拆,拆了就失去业务含义。
举个例子,「订单金额」是原子指标吗?是,因为它代表一笔订单的实际成交金额。但「订单金额的平方」就不是,那是计算出来的。
原子指标三要素:
- 业务含义明确:每个原子指标对应一个业务事件(下单、支付、退款等)
- 统计粒度单一:不依赖其他指标,直接从事实表获取
- 口径稳定:一旦定义,不轻易修改
我在项目中遇到过这样的坑:业务方说「我要看订单数」,结果开发把「订单创建数」「订单支付数」「订单完成数」全算成一个指标。后来对账时发现差了 30%,查了半天才找到原因。所以,原子指标必须跟业务事件一一绑定。
| 业务域 | 原子指标 | 业务事件 | 统计粒度 |
|---|---|---|---|
| 交易 | 订单金额 | 订单创建 | 单笔订单 |
| 交易 | 支付金额 | 支付成功 | 单笔支付 |
| 用户 | 注册用户数 | 用户注册 | 单个用户 |
| 物流 | 发货单数 | 发货完成 | 单张发货单 |
我的习惯:原子指标命名用「业务域_事件_度量」的格式,比如 trade_order_amount。这样一看就知道它来自哪个域、对应什么事件。
2. 派生指标:带过滤条件的原子指标
派生指标,就是在原子指标上加过滤条件或维度限定。它不改变原子指标的计算逻辑,只是缩小了统计范围。
你想想看,「订单金额」是原子指标,那「北京地区的订单金额」呢?这就是派生指标——在原子指标上加了「城市=北京」的过滤。
派生指标 = 原子指标 + 维度限定 + 统计周期
我记得有一次,业务方要求看「双十一当天,女性用户,购买美妆类目的订单金额」。这个指标怎么拆?
- 原子指标:订单金额
- 维度限定:用户性别=女,商品类目=美妆
- 统计周期:2024-11-11 全天
你看,派生指标的本质就是「原子指标 + 业务场景」。它不需要重新定义计算逻辑,只需要在查询时加上过滤条件。
避坑指南:我曾经见过一个团队,把「北京订单金额」「上海订单金额」「广州订单金额」都定义成独立的派生指标,存了 30 多个字段。其实只需要一个原子指标 + 城市维度,查询时动态过滤就行。派生指标不要过度物化,否则维护成本会爆炸。
3. 复合指标:多个指标的组合运算
复合指标,是由两个或多个原子/派生指标通过四则运算、比率、排名等方式组合而成的指标。它反映的是业务之间的关联关系。
举个例子,「客单价」= 订单金额 ÷ 订单数。这里「订单金额」和「订单数」都是原子指标,但「客单价」是复合指标。
| 复合指标 | 计算公式 | 依赖的原子/派生指标 |
|---|---|---|
| 客单价 | 订单金额 ÷ 订单数 | 订单金额、订单数 |
| 转化率 | 支付订单数 ÷ 创建订单数 | 支付订单数、创建订单数 |
| 毛利率 | (收入 - 成本) ÷ 收入 | 收入、成本 |
| 同比 | (本期值 - 同期值) ÷ 同期值 | 本期指标、同期指标 |
复合指标有个特点:它的计算时机可以灵活选择。可以在 ETL 阶段预计算,也可以在查询时实时计算。我个人建议:
- 高频使用的复合指标(比如日活、月活)→ 预计算,存到宽表
- 低频或临时分析的复合指标(比如某个活动的转化率)→ 实时计算,不落盘
我的经验:复合指标最容易出问题的地方是「分母为零」。比如转化率,如果创建订单数为 0,除法就报错。我习惯在定义复合指标时,同时定义「空值处理策略」——是返回 0、返回 NULL,还是返回上一个有效值?这个要跟业务方提前对齐。
4. 三层指标的分层策略
这三层指标不是平级关系,而是有明确的依赖层级。我画了一张图,帮你理解它们的关系:
分层策略的核心原则就一句话:上层依赖下层,下层不依赖上层。原子指标是地基,派生指标是场景化应用,复合指标是业务洞察。每一层只关注自己的职责,不要越界。
分层的好处:
- 复用性高:一个原子指标可以被多个派生指标复用,一个派生指标可以被多个复合指标复用
- 口径统一:所有指标的计算逻辑都追溯到原子指标,不会出现「同一个指标不同口径」的问题
- 维护成本低:改口径只需要改原子指标,派生和复合指标自动生效
5. 落地实践:指标注册与元数据管理
光有分层理论还不够,落地才是关键。我建议用「指标注册表」来管理所有指标,把每一层的定义、口径、依赖关系都记录下来。
| 指标ID | 指标名称 | 层级 | 计算公式 | 依赖指标 | 统计周期 |
|---|---|---|---|---|---|
| M001 | 订单金额 | 原子 | SUM(order.amount) | — | 实时 |
| M002 | 北京订单金额 | 派生 | M001 WHERE city='北京' | M001 | 实时 |
| M003 | 客单价 | 复合 | M001 ÷ M004 | M001, M004 | 日 |
| M004 | 订单数 | 原子 | COUNT(order.id) | — | 实时 |
我的建议:指标注册表最好用 YAML 或 JSON 来维护,方便版本管理和自动化校验。每次新增指标时,先查一下原子指标池里有没有现成的,避免重复定义。
嗯,指标分层这件事,说白了就是「把复杂问题拆成简单问题」。原子指标管「是什么」,派生指标管「在什么场景下」,复合指标管「业务怎么看」。三层各司其职,你的看板才不会变成一团乱麻。