元数据模型:技术元数据、业务元数据、操作元数据

搞数据治理这么久,我见过太多团队一上来就建模型,结果建出来的东西没人用。你想想看,元数据模型要是跟业务对不上号,那就是个空壳子。今天咱们把这三大类拆开来聊。

先问个问题:什么是好的元数据模型?我个人习惯把它看作三层楼——技术层、业务层、操作层。每层解决不同的问题,但加在一起才能把管道的全貌看清楚。

技术元数据:管道的骨架

说白了,技术元数据就是描述数据「长什么样」的信息。它包括数据库表结构、字段类型、分区信息、ETL 脚本、存储路径这些东西。

实践中常见的例子:
  • 表名、列名、数据类型、长度约束
  • 主键与外键关系
  • 索引、分区键、分桶策略
  • 存储格式(Parquet、ORC、Avro)
  • ETL 脚本、任务依赖

我刚开始做数据治理时,遇到最头疼的事就是脚本依赖一团乱。一次上线改了个表的字段类型,下游十几个任务全挂了。

看看我们怎么抓取技术元数据。从 Hive 表来举个例子:

DESCRIBE FORMATTED dwd.user_order_daily;

-- 输出示例
+----------------------+--------------------------+---------+
| col_name             | data_type                | comment |
+----------------------+--------------------------+---------+
| user_id              | bigint                   | 用户ID  |
| order_id             | bigint                   | 订单ID  |
| order_amount         | decimal(18,2)            | 订单金额 |
| order_status         | int                      | 订单状态 |
| create_time          | timestamp                | 创建时间 |
+----------------------+--------------------------+---------+

# Partition Information
# col_name              data_type               comment
+----------------------+--------------------------+---------+
| dt                   | string                   | 分区日期 |
+----------------------+--------------------------+---------+

# Storage Information
SerDe Library:          org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe
InputFormat:            org.apache.hadoop.mapred.TextInputFormat
OutputFormat:           org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat
Compressed:             No
Num Buckets:            -1
Bucket Columns:         []
Sort Columns:           []
Storage Desc Params:
	serialization.format	1

抓元数据时,我建议你同时采集完整的数据血缘分。血缘分不清,排查问题就像大海捞针。我曾经踩过这个坑——某个报表数据对不上,折腾了两天才发现是上游一个临时表改了逻辑。

业务元数据:管道的灵魂

光有技术元数据,你知道字段叫什么,但不知道它「代表什么」。这就是业务元数据要解决的问题。

业务元数据重点包括:

  • 业务术语表——比如「活跃用户」的定义是什么?30天内登录一次?还是7天内?
  • 数据质量规则——比如金额字段不能为负、用户ID必须在用户表存在
  • 数据安全等级——哪些字段属于敏感信息?PII数据如何脱敏?
  • 数据地图与血缘——哪张表对应业务哪个环节?
  • 指标口径说明——GMV是怎么算的?包含退款订单吗?

血的教训:有个项目,技术团队跟业务团队对「新客」的理解完全不一样。技术台账认为只要没下过单就算新客;业务说注册当天就算新客。由于在元数据模型中没有统一字段定义,最终报表对不上数,废了三天时间重新对齐。

业务元数据的采集,通常从数据词典和指标系统入手。拿我们团队的配置来说,会在治理平台里维护一份业务术语表:

{
  "business_terms": [
    {
      "term_name": "活跃用户",
      "term_id": "BT-001",
      "definition": "最近30天内有登录行为的去重用户数",
      "domain": "用户增长",
      "owner": "张三",
      "approval_status": "已发布",
      "related_fields": ["dwd.user_login.dt", "dwd.user_login.user_id"]
    },
    {
      "term_name": "GMV",
      "term_id": "BT-002",
      "definition": "用户已支付订单的总金额,含退款订单按正数计入",
      "domain": "交易分析",
      "owner": "李四",
      "approval_status": "已发布",
      "related_fields": ["dwd.order_daily.order_amount", "dwd.order_daily.order_status"]
    }
  ]
}

别小看这个配置表。有了它,新来的分析师可以快速理解数据,不用到处问人。我每次做数据治理项目,第一件事就是拉着业务方把术语表过一遍,你想想看,这块搞不定,后面全是虚的。

操作元数据:管道的脉搏

操作元数据是关于「运行状态」的信息。管道跑了吗?跑成功了吗?跑多久?有多少行?报错了吗?

我通常会把它分成几类:

类别 内容 示例
作业运行 任务开始/结束时间、执行状态 ETL作业2024-01-15 08:00:00 开始,08:15:32 完成
数据质量 校验结果、异常规则命中数 字段order_amount空值率超过阈值(5%)
数据量指标 插入行数、更新行数、文件大小 今天写入1,234,567行,比昨日增长8%
错误日志 异常堆栈、失败原因 Java.lang.OutOfMemoryError 导致任务失败
性能统计 CPU使用率、内存瓶颈、I/O Shuffle阶段CPU使用率持续95%

操作元数据怎么采集?最常见的方式是在作业框架里埋点。比如我处理过的一个 Spark 任务,会在完成后把运行信息写到一张审计表:

INSERT INTO meta.operation_log (
  task_name, 
  run_date, 
  start_time, 
  end_time, 
  status, 
  rows_inserted, 
  error_msg
)
VALUES (
  'dwd_user_order_daily',
  '2024-01-15',
  '2024-01-15 08:00:00',
  '2024-01-15 08:15:32',
  'SUCCESS',
  1234567,
  NULL
);
注意操作元数据的存储时长。你不可能把历史所有日志全留下,磁盘受不了。我建议:
  • 近30天:保留完整明细
  • 30天到1年:聚合到小时级粒度
  • 超过1年:只存成功/失败计数,用于长期趋势分析

三类元数据的协同关系

我遇到很多新手会问:这三类元数据是不是分开维护?不,它们必须在一个模型里协同工作。

举个例子,你在排查数据异常时:

  1. 用业务元数据确认指标口径(这个GMV为什么比预估低?)
  2. 用技术元数据找到对应的表和字段(订单金额来自哪张表?)
  3. 用操作元数据检查当天的管道运行情况(作业有没有失败?数据有没有丢失?)

我个人习惯在治理平台的元数据模型里,为每个数据资产都挂载三类标签。比如一张订单明细表,除了技术信息,还要关联业务术语、运行记录。这样一次查询就能拿到完整上下文,效率翻倍。

模型的落地实践建议

好,说了这么多理论,来点实际的。我一般按这个步骤做:

  1. 先盘点后建模——不要闭门造车,先拉出所有已有数据资产
  2. 从技术元数据入手——最简单,用工具批量采集,两天搞定
  3. 逐步补齐业务信息——拉上业务方,每周两个领域地过术语
  4. 操作元数据要自底向上——从最频繁报错的作业开始收割
  5. 测试血缘链路的完整性——从报表反查到源数据,确保每跳都有记录

避坑指南:我曾经一口气把整个数据湖所有表和字段的元数据全部采集到位,结果一百多页的模型文档没人看。后来学乖了——业务元数据要按使用频率分级,常用字段优先标注。你想想看,没人关心的冷门表,标注再完整也没用。

三类元数据的关系可以用一张图呈现,我把它画成三个相互重叠的环,每个环都有自己的核心内容,交叉区域才是元数据治理的价值所在。

元数据三层模型协同关系图 技术元数据 表结构 · 字段类型 分区键 · 存储格式 ETL脚本 · 血缘依赖 业务元数据 术语表 · 指标口径 数据安全等级 数据质量规则 操作元数据 作业运行 · 数据量 异常记录 · 性能 三环交叉处 = 治理核心 数据资产全视角呈现 技术元数据 业务元数据 操作元数据 虚线圆表示相互关联

你看这个三层环,每个圆都有自己聚焦的内容,但中间的交集才是元数据治理真正发挥作用的地方。技术元数据告诉我们数据在哪、长什么样;业务元数据解释它有什么含义、应该怎么用;操作元数据告诉我们它今天有没有好好运行。

三个环缺一不可。光有技术和操作,你只能看到管道在转但不知道转什么;光有业务和操作,你找不到对应的实际数据在哪;光有技术和业务,你没法知道数据今天是不是可靠的。

嗯,这里要注意:不同团队对三层元数据的侧重点不同。数据平台团队更关注技术元数据,数据分析团队更关注业务元数据,运维团队更关注操作元数据。但我一直跟人讲,不管你是哪个角色,最后都要看懂这三层打通之后的全景图。