1、指标层设计概述:什么是指标层、指标层在数据仓库中的位置、为什么需要指标层
大家好,我是这次课程的主讲。咱们直接进入正题。
指标层,英文叫 Metrics Layer。很多朋友第一次听到这个词,会觉得它是个新概念。其实不然。指标层不是什么高大上的新架构,它更像是一个「翻译层」——把底层那些乱七八糟的物理表、字段名,翻译成业务人员能看懂、能直接用的指标。
什么是指标层?
说白了,指标层就是一组经过统一口径定义、标准化计算逻辑的指标集合。它位于数据仓库的模型层之上,应用层之下。
我个人的理解是:指标层是数据仓库的「语义层」。它不存原始数据,只存「如何计算这个指标」的规则。
核心定义:指标层 = 业务指标 + 计算逻辑 + 口径管理。它让「销售额」这个说法,在全公司只有一个计算方式。
举个例子。你公司有 CRM 系统、ERP 系统、还有一堆 Excel 报表。每个系统里都有「客户数」这个字段。但 CRM 的客户数是「注册用户」,ERP 的客户数是「有交易记录的用户」。口径不一样,数据对不上。指标层就是来解决这个问题的——它把「客户数」统一成「过去 30 天有过至少一笔交易的客户去重数」,然后所有报表都从这个层取数。
指标层在数据仓库中的位置
咱们先看一张图,你就明白了。
从这张图可以清楚看到:指标层在 DWS 之上、应用层之下。它不直接对接原始数据,而是基于已经清洗、汇总好的数据,做二次语义封装。
我记得有一次给一家电商公司做数据治理。他们的 BI 团队直接对着 DWD 层写 SQL,每个报表里都有一段长达 200 行的「销售额」计算逻辑。结果呢?三个报表算出三个不同的销售额。后来我把指标层架上去,所有报表统一调用指标层接口,问题就解决了。
为什么需要指标层?
这个问题,我分三点来讲。
1. 解决口径不一致的问题
这是最直接的原因。没有指标层,每个分析师、每个报表都在自己定义指标。同一个「活跃用户」,有人算「登录过就算」,有人算「有过操作行为才算」。口径打架,数据没法用。
我的经验:口径不一致是数据团队的「慢性病」。初期不痛不痒,等公司做到一定规模,你会发现所有跨部门的数据对账都在吵架。指标层就是那个「裁判」。
2. 提升开发效率
你想想看,如果没有指标层,每次新报表需求来了,开发都得重新写一遍指标计算逻辑。重复劳动,还容易出错。
有了指标层,指标的定义和计算逻辑只写一次。后续所有应用层直接引用。改口径也只需要改指标层一处,不用满世界找 SQL。
3. 让业务人员能自助取数
这个点很关键。很多公司花大价钱上了数据平台,但业务人员还是得找 IT 要数据。为什么?因为底层表名是 t_ord_20231023_di,字段名是 amt,业务看不懂。
指标层把这些翻译成「订单金额」、「客户数」、「客单价」。业务人员通过指标层,自己就能拖拽出报表。这才是数据驱动业务的真正落地。
注意:指标层不是银弹。它解决的是「语义统一」和「计算复用」的问题,解决不了「数据质量差」和「源系统数据不准」的问题。底层数据是垃圾,指标层再漂亮也是垃圾。
指标层的核心组成
我习惯把指标层拆成三个部分:
| 组成部分 | 说明 | 举例 |
|---|---|---|
| 原子指标 | 不可再拆分的业务度量 | 订单金额、用户数、访问次数 |
| 派生指标 | 基于原子指标计算得到 | 客单价 = 订单金额 / 用户数 |
| 维度 | 指标的观察角度 | 时间、地区、产品品类 |
举个例子。原子指标「订单金额」加上维度「时间」和「地区」,就变成了「2024年华东区订单金额」。如果再除以「用户数」,就得到「2024年华东区客单价」——这就是一个派生指标。
一个简单的指标层定义示例
下面我用伪代码展示一下指标层的定义方式。实际项目中可能会用 YAML、JSON 或者专门的指标管理平台来定义。
# 指标层定义示例(YAML 格式)
metrics:
- name: order_amount
display_name: "订单金额"
description: "用户下单支付的总金额,含税"
type: atomic
data_source: dws.dws_order_daily
field: total_amount
aggregation: sum
filters:
- status = 'paid'
- name: order_count
display_name: "订单数"
description: "支付成功的订单数量"
type: atomic
data_source: dws.dws_order_daily
field: order_id
aggregation: count_distinct
filters:
- status = 'paid'
- name: avg_order_value
display_name: "客单价"
description: "平均每笔订单的金额"
type: derived
formula: "order_amount / order_count"
depends_on:
- order_amount
- order_count
你看,这样定义之后,任何报表工具只要接入指标层,就能直接使用「客单价」这个指标,不用关心它背后的计算逻辑。
避坑指南
我曾经踩过一个坑:指标层定义得太细。把「上午的订单金额」和「下午的订单金额」都定义成独立指标。结果指标数量膨胀到上千个,维护成本极高。
后来我总结了一个原则:指标层只定义业务语义,不定义业务场景。场景(比如「上午 vs 下午」)应该由应用层通过维度筛选来实现,而不是在指标层硬编码。
核心原则:指标层做「定义」,不做「枚举」。一个指标 + 多个维度 = 无限场景。别把场景写死在指标里。