元数据分类与模型:技术元数据、业务元数据、操作元数据
聊元数据管理,第一个绕不开的问题就是:元数据到底分几类?
我见过不少团队,一上来就搞统一元数据仓库,结果发现业务部门看不懂技术字段,技术部门又嫌业务描述太啰嗦。说白了,分类没做好,后面全是坑。
今天咱们就把这三类元数据掰开揉碎讲清楚。我个人习惯把它们比作房子的三张图纸:结构图(技术)、装修图(业务)、维护日志(操作)。
技术元数据:数据的基础骨架
技术元数据,说白了就是描述数据「长什么样、在哪存、怎么取」的信息。它是数据工程师最常打交道的部分。
核心定义:描述数据系统中技术细节的元数据,包括数据结构、存储位置、访问路径、数据血缘等。
我在项目中遇到过最典型的场景:新来的数据开发要改一张表,结果不知道下游有 20 个报表依赖它。这就是技术元数据没管好。
技术元数据通常包含以下几类:
- 数据源信息:数据库连接串、表名、字段名、字段类型、主键、外键
- ETL 作业信息:作业名称、调度频率、输入输出映射、转换逻辑
- 数据血缘:字段级、表级、作业级的上下游依赖关系
- 存储信息:文件格式(Parquet/ORC/CSV)、压缩方式、分区策略
- 访问控制:权限策略、加密方式、审计日志
举个例子,一个典型的表级技术元数据长这样:
表名: dwd_order_detail
所属库: dwd_layer
字段列表:
- order_id: BIGINT, NOT NULL, PK
- user_id: BIGINT, NOT NULL
- product_id: BIGINT, NOT NULL
- amount: DECIMAL(10,2), NOT NULL
- create_time: TIMESTAMP, NOT NULL
分区字段: dt (STRING, 格式 yyyy-MM-dd)
存储格式: Apache Parquet, Snappy 压缩
数据保留: 90 天
ETL 作业: job_dwd_order_detail, 每天 02:00 执行
上游依赖: ods_order, ods_user, ods_product
下游消费: 报表系统(3张宽表), 推荐引擎(实时特征)
我的经验:技术元数据最容易犯的错是「只记录不维护」。我曾经接手一个项目,技术元数据表里 40% 的字段已经废弃了。建议每次表结构变更时,强制更新元数据,别等月底再补。
业务元数据:让数据能被看懂
技术元数据工程师看得懂,但业务人员呢?你想想看,一个叫 cust_id 的字段,业务方怎么知道它是「客户编号」还是「客户身份证号」?
业务元数据就是干这个的——给数据穿上业务的外衣。
核心定义:描述数据的业务含义、使用场景、业务规则和业务术语的元数据。
业务元数据包括:
- 业务术语表:字段的业务名称、定义、计算口径、枚举值含义
- 数据质量规则:非空约束、唯一性约束、取值范围、业务逻辑校验
- 数据使用说明:数据用途、适用场景、使用限制、敏感级别
- 数据所有者:业务负责人、数据管家、审批流程
- 变更历史:业务口径变更记录、变更原因、生效时间
我举个例子你就明白了。同样是「订单金额」这个字段:
| 维度 | 技术元数据 | 业务元数据 |
|---|---|---|
| 字段名 | order_amt |
订单金额 |
| 类型 | DECIMAL(12,2) | 保留两位小数,单位元 |
| 定义 | — | 用户实际支付的金额,含运费,不含退款 |
| 计算口径 | — | sum(商品单价 × 数量 + 运费 - 优惠) |
| 敏感级别 | — | L2 敏感,仅限财务和运营团队访问 |
注意:业务元数据最怕「写一次就再也不管」。我曾经见过一个业务术语表,里面还写着「双十一大促口径:满 200 减 20」,但那个活动已经结束两年了。业务元数据必须跟着业务规则走,建议每季度 review 一次。
操作元数据:数据运营的「黑匣子」
操作元数据,很多人容易忽略它。但说实话,没有操作元数据,你根本不知道数据系统跑得好不好。
操作元数据记录的是数据系统运行过程中的「痕迹」——谁在什么时候做了什么,系统状态如何,有没有出过问题。
核心定义:描述数据系统运行状态、操作行为、性能指标和审计信息的元数据。
操作元数据主要包括:
- 作业运行日志:每次 ETL 作业的开始时间、结束时间、状态(成功/失败/超时)、处理行数
- 数据访问审计:谁在什么时间查询了哪些表、执行了什么 SQL、返回了多少行
- 性能指标:查询响应时间、数据加载速度、存储使用率、CPU/内存消耗
- 数据质量监控:数据完整性检查结果、异常检测告警、数据延迟情况
- 变更记录:表结构变更、权限变更、配置变更的操作人和时间戳
举个例子,操作元数据的一条典型记录:
操作类型: 数据查询
操作人: zhang.san@company.com
操作时间: 2024-03-15 14:32:18
数据源: dwd_order_detail
执行 SQL: SELECT order_id, amount FROM dwd_order_detail WHERE dt='2024-03-14'
返回行数: 12,345
响应时间: 2.3s
状态: 成功
来源 IP: 10.0.1.45
应用名称: 运营报表系统
我的建议:操作元数据一定要保留足够长的历史。我曾经排查一个数据质量问题,需要回溯三个月前的作业日志,结果发现只保留了一周。从那以后,我坚持操作元数据至少保留 6 个月,审计相关的保留 2 年。
三类元数据的关系
这三类元数据不是孤立的。你想想看,一个数据资产要管好,技术元数据告诉你「它是什么」,业务元数据告诉你「它有什么用」,操作元数据告诉你「它用得怎么样」。
下面这张图展示了它们之间的关系:
元数据模型设计原则
分类搞清楚了,接下来就是怎么设计元数据模型。我踩过不少坑,总结出 5 条核心原则,分享给你。
原则一:面向领域,而非面向系统
很多团队设计元数据模型时,习惯按系统来分——「这个表是 MySQL 的,那个表是 Hive 的」。但数据网格强调的是数据域。
我建议按业务领域来组织元数据模型。比如电商场景,分成「订单域」「用户域」「商品域」「支付域」。每个域独立管理自己的元数据,但遵循统一的模型规范。
避坑指南:我曾经见过一个团队,元数据模型按数据源分了 12 个类别,结果同一个业务字段在 MySQL 里叫 user_id,在 Hive 里叫 uid,在 Kafka 里叫 userId。面向领域设计,这些问题在模型层面就能解决。
原则二:分层抽象,避免扁平化
元数据模型不能太扁平。我习惯分三层:
- 核心层:所有数据域共享的基础元数据,如数据源、数据实体、字段定义
- 领域层:特定数据域的业务元数据,如订单域的业务规则、用户域的敏感级别
- 实例层:具体数据对象的操作元数据,如某张表的运行日志、访问记录
这样做的好处是:核心层保证一致性,领域层保证灵活性,实例层保证可追溯性。
原则三:版本化,不可变
元数据是会变的。表结构会改,业务口径会调,数据质量规则会更新。每次变更都应该生成一个新版本,而不是覆盖旧数据。
我坚持一个原则:元数据模型必须支持时间旅行。也就是说,你能查到「2024 年 1 月 1 日时,这张表的字段定义是什么」。
-- 元数据版本表示例
元数据ID: meta_order_amount_v3
实体: dwd_order_detail.amount
变更类型: 业务口径调整
旧口径: 订单金额 = 商品金额 + 运费
新口径: 订单金额 = 商品金额 + 运费 - 优惠金额
变更原因: 2024年Q1财务核算规则更新
生效时间: 2024-01-01 00:00:00
变更人: li.si@company.com
审批人: wang.wu@company.com
原则四:关联优先,属性次之
元数据的价值在于关联。一个字段单独看没什么意义,但如果你知道它属于哪张表、被哪些报表引用、由哪个 ETL 作业生成、对应的业务口径是什么——信息量就大了。
设计模型时,我建议把关联关系作为一等公民。比如:
- 字段 → 表(所属关系)
- 表 → ETL 作业(生成关系)
- ETL 作业 → 下游表(依赖关系)
- 字段 → 业务术语(映射关系)
- 表 → 数据域(归属关系)
注意:关联关系本身也是元数据,也需要版本管理。我曾经遇到过一个场景:字段和业务术语的映射关系变了,但没人更新,导致报表数据口径对不上。关联关系的变更,一定要通知到所有下游消费者。
原则五:可扩展,不过度设计
最后一条原则,也是我吃过亏最多的——别一开始就想把所有东西都装进去。
元数据模型要支持扩展,但不要过度设计。我建议:
- 核心属性固定下来(字段名、类型、描述、所有者)
- 扩展属性用键值对或标签系统实现
- 预留自定义字段,让每个数据域可以加自己的元数据
举个例子,核心模型只定义 10 个必填字段,但允许每个数据域通过标签系统添加自己的扩展属性。这样既保证了统一性,又保留了灵活性。
总结一下:技术元数据、业务元数据、操作元数据,三者缺一不可。模型设计记住 5 条原则——面向领域、分层抽象、版本化、关联优先、可扩展。做到这几点,你的元数据管理就成功了一半。