1、数据血缘基础:什么是数据血缘、血缘的元数据模型、血缘在数据治理中的价值
各位同学,咱们今天聊数据血缘。说实话,这词儿在圈里已经不算新鲜了,但真正把它用明白的团队,我见过的不多。
数据血缘,说白了就是数据的“族谱”。你想想看,一张报表里的某个数字,它是从哪张表来的?中间经过了哪些ETL脚本?被哪个任务加工过?谁改了它的口径?——把这些链路串起来,就是血缘。
一句话定义:数据血缘是记录数据从产生、加工、流转到最终消费的完整路径,以及过程中所有依赖关系的元数据。
1.1 为什么我们需要血缘?
我记得刚做数据治理那会儿,有一次线上报表数据对不上。业务方追过来问:“这个月销售额怎么比上个月少了30%?”我查了三天,最后发现是上游一个字段的过滤条件被人改过,但没有任何人通知下游。那三天我翻了几十个脚本,挨个问人,效率极低。
如果有血缘,这种问题几分钟就能定位。这就是血缘最直接的价值——追根溯源。
再往深了说,血缘还能帮我们做这几件事:
- 影响分析:上游表结构改了,下游哪些报表会挂?血缘一查就知道。
- 质量回溯:某个字段质量不合格,顺着血缘找到根因节点。
- 合规审计:监管问“这个数据从哪来的?谁碰过?”血缘就是证据链。
- 成本优化:哪些表被频繁引用?哪些任务没人用?血缘帮你做“断舍离”。
1.2 血缘的元数据模型
聊完价值,咱们看看血缘长什么样。我习惯把血缘模型拆成三个层次:
1.2.1 核心实体
| 实体 | 含义 | 举例 |
|---|---|---|
| 数据集 | 数据存储的载体 | 表、视图、文件、Kafka Topic |
| 数据字段 | 数据集内的最小数据单元 | 列、字段、JSON key |
| 数据任务 | 产生或转换数据的逻辑单元 | ETL脚本、SQL任务、Spark Job |
| 数据消费 | 数据被使用的场景 | 报表、API、数据产品 |
1.2.2 关系类型
实体之间怎么连?我归纳了三种基本关系:
- 数据流关系:任务A的输出 → 数据集B。这是最基础的“谁生谁”。
- 依赖关系:任务C依赖数据集D作为输入。没有D,C跑不了。
- 派生关系:字段E = 字段F + 字段G。这是字段级别的血缘。
我的经验:很多团队只做了表级血缘,但字段级血缘才是真正能定位问题的。我建议一开始就设计字段级模型,哪怕先不全量采集,也要把模型留好。
1.2.3 元数据模型示例
下面是一个简化的血缘元数据模型,用JSON表示:
{
"dataset": {
"id": "ds_001",
"name": "dwd_sales_order",
"type": "hive_table",
"fields": [
{"id": "f_001", "name": "order_id", "type": "string"},
{"id": "f_002", "name": "amount", "type": "decimal"}
]
},
"task": {
"id": "t_001",
"name": "etl_sales_daily",
"type": "spark_sql",
"input_datasets": ["ds_000"],
"output_datasets": ["ds_001"],
"field_mappings": [
{"from": "f_000", "to": "f_001", "expression": "cast(order_id as string)"},
{"from": "f_001", "to": "f_002", "expression": "sum(amount)"}
]
}
}
嗯,这里要注意:字段映射是血缘模型里最难做、也最有价值的部分。它记录了“下游字段是怎么从上游算出来的”。
1.3 血缘在数据治理中的价值
咱们把血缘放到整个数据治理体系里看。我画了张图,帮你理解血缘的位置:
从这张图你能看到,血缘不是孤立的。它跟数据标准、数据质量、数据安全、数据架构都有关系。我举个例子:
- 血缘 + 数据标准:标准定义了一个字段叫“客户ID”,血缘能告诉你哪些表用了这个字段,哪些没用标准命名。
- 血缘 + 数据质量:质量规则发现“金额”字段有空值,血缘能追溯到是哪个上游任务没做非空校验。
- 血缘 + 数据安全:敏感数据字段(比如身份证号)被血缘标记后,可以自动检查哪些下游消费场景没有脱敏。
- 血缘 + 数据架构:架构师改表结构时,血缘能列出所有受影响的下游,避免“改一处、崩一片”。
避坑提醒:我曾经见过一个团队,花了大半年把血缘关系全采回来了,但没人用。为什么?因为血缘没有跟质量监控、变更流程这些日常操作绑定。血缘的价值在于“用”,不在于“采”。
1.4 血缘的采集方式
最后简单提一下血缘怎么来。常见的有三种方式:
| 方式 | 原理 | 优点 | 缺点 |
|---|---|---|---|
| 解析SQL | 解析ETL脚本、SQL语句中的表名和字段引用 | 准确、细粒度到字段 | 对复杂SQL(UDF、CTE嵌套)解析难度大 |
| 日志解析 | 从计算引擎(Spark、Flink)的执行计划日志中提取 | 覆盖真实执行路径 | 依赖引擎版本,日志格式不统一 |
| 埋点/手动录入 | 开发者在代码中显式声明血缘关系 | 灵活、可补充自动采集遗漏 | 依赖人工,容易遗漏或过期 |
我个人习惯的做法是:以SQL解析为主,日志解析为辅,手动录入兜底。三种方式互补,才能把血缘采全。