3. 元数据模型设计:指标分类、指标属性定义、维度与度量建模、血缘关系设计
好,咱们进入第三章节。说实话,元数据模型设计是整个指标字典的「骨架」。骨架没搭好,后面填再多肉也站不起来。我在好几个项目里都见过这种情况——指标字典建了半年,结果分类乱成一锅粥,属性定义各说各话,最后谁也查不清哪个指标是谁算的。
这一章,咱们就把骨架搭结实。我会从四个核心部分展开:指标怎么分类、属性怎么定义、维度和度量怎么建模、血缘关系怎么设计。嗯,咱们一个一个来。
3.1 指标分类:别让指标「无家可归」
指标分类,说白了就是给每个指标找个「家」。你想想看,几百个指标堆在一起,没有分类,找起来得多痛苦?
我个人习惯用三层分类体系:
- 业务域:最顶层,按业务板块划分。比如「交易域」、「用户域」、「营销域」。
- 业务过程:中间层,按具体业务流程划分。比如「交易域」下面可以分「下单」、「支付」、「退款」。
- 指标主题:最底层,按分析主题划分。比如「下单」下面可以分「订单量」、「订单金额」、「客单价」。
关键原则:每个指标只能属于一个叶子节点。不能一个指标既属于「订单量」又属于「支付量」,那分类就失去意义了。
我在项目中遇到过一种情况:业务方把「活跃用户数」同时挂在「用户域」和「增长域」下面。结果两个团队算出来的数字不一样,扯皮扯了半个月。后来我们强制规定——每个指标只能挂在一个分类节点下,如果有跨域需求,用「标签」来解决。
3.2 指标属性定义:把「身份证」办齐
指标属性,就是指标的「身份证信息」。属性定义得越全,后面用起来越顺手。
我建议把属性分成三组:
| 属性分组 | 属性名称 | 说明 | 示例 |
|---|---|---|---|
| 基础属性 | 指标名称 | 业务可读的名称 | 当日订单支付金额 |
| 指标编码 | 全局唯一标识 | IND_TRX_PAY_AMT_D | |
| 指标定义 | 业务含义描述 | 用户当日成功支付的订单总金额 | |
| 所属分类 | 指向分类树叶子节点 | 交易域 > 支付 > 支付金额 | |
| 技术属性 | 数据类型 | 存储格式 | DECIMAL(18,2) |
| 计算口径 | SQL 或公式描述 | SUM(pay_amt) WHERE status='SUCCESS' | |
| 更新频率 | 数据刷新周期 | T+1 / 实时 | |
| 管理属性 | 负责人 | 指标 Owner | 张三 |
| 安全等级 | 数据敏感度 | L1 / L2 / L3 |
一个小技巧:指标编码最好带点「语义」。比如 IND_TRX_PAY_AMT_D,IND 代表指标,TRX 代表交易域,PAY 代表支付过程,AMT 代表金额,D 代表日粒度。这样看编码就能猜出七八分含义。
3.3 维度与度量建模:分清「看什么」和「算什么」
维度是「看什么」,度量是「算什么」。这个区分搞不清楚,指标字典就容易变成一锅粥。
举个例子:「按城市统计的订单金额」——「城市」是维度,「订单金额」是度量。
我习惯用下面的模型来设计:
指标 = 度量 + 维度约束 + 时间范围 + 聚合方式
具体来说:
- 度量:原子指标,不可再拆。比如「支付金额」、「订单数量」。
- 维度:分析的角度。比如「时间」、「城市」、「渠道」、「用户等级」。
- 维度约束:对维度值的过滤。比如「城市 = '北京'」。
- 时间范围:数据的时间窗口。比如「2024-01-01 到 2024-01-31」。
- 聚合方式:SUM、COUNT、AVG、MAX、MIN 等。
注意:同一个度量搭配不同的维度,会产生不同的指标。比如「支付金额」按「城市」聚合是「城市支付金额」,按「渠道」聚合是「渠道支付金额」。这两个指标虽然底层数据一样,但业务含义不同,必须分别定义。
我曾经见过一个团队,把「支付金额」定义成一个指标,然后说「维度可以随便组合」。结果业务方问「北京渠道的支付金额是多少」,数据团队算了三个版本,每个都不一样。为什么?因为维度组合的过滤条件没定义清楚。
3.4 血缘关系设计:让数据「有迹可循」
血缘关系,就是指标从哪来、到哪去、中间经过了哪些变换。没有血缘关系,指标出了问题你根本不知道是源头脏了还是中间算错了。
我建议至少记录三层血缘:
- 源系统 → 贴源层:数据从哪个业务系统来,对应哪张表、哪个字段。
- 贴源层 → 明细层:经过哪些清洗、转换、关联。
- 明细层 → 指标层:经过哪些聚合计算,生成最终指标。
下面这张图展示了完整的血缘链路:
在实际落地时,我建议用一张血缘关系表来存储:
CREATE TABLE meta_lineage (
lineage_id BIGINT PRIMARY KEY,
source_table VARCHAR(100), -- 源表名
source_field VARCHAR(100), -- 源字段
target_table VARCHAR(100), -- 目标表名
target_field VARCHAR(100), -- 目标字段
transform_logic TEXT, -- 转换逻辑描述
etl_job_id VARCHAR(50), -- 对应 ETL 任务
create_time DATETIME
);
避坑指南:血缘关系一定要「自动采集」,不要手工维护。我曾经见过一个团队,靠 Excel 手工记录血缘,三个月后 Excel 丢了,整个指标字典的血缘全断了。后来我们接入了数据治理平台,自动解析 SQL 中的表字段依赖,血缘才真正「活」起来。
3.5 元数据模型总览
最后,我把这四个部分串起来,形成一个完整的元数据模型。你可以在实际项目中直接参考:
元数据模型 = {
"指标分类树": {
"业务域": ["交易域", "用户域", "营销域", ...],
"业务过程": ["下单", "支付", "退款", ...],
"指标主题": ["订单量", "支付金额", "退款率", ...]
},
"指标属性": {
"基础属性": ["名称", "编码", "定义", "分类"],
"技术属性": ["数据类型", "计算口径", "更新频率"],
"管理属性": ["负责人", "安全等级", "创建时间"]
},
"维度与度量": {
"度量": ["支付金额", "订单数量", "用户数"],
"维度": ["时间", "城市", "渠道", "用户等级"],
"聚合方式": ["SUM", "COUNT", "AVG", "MAX", "MIN"]
},
"血缘关系": {
"源系统 → 贴源层": "字段级映射",
"贴源层 → 明细层": "清洗转换逻辑",
"明细层 → 指标层": "聚合计算逻辑"
}
}