2、血缘元数据模型:表级血缘、字段级血缘、ETL过程血缘、血缘的粒度与层次
聊完了血缘分析的价值,咱们得落地了。落地第一步,就是搞清楚血缘数据长什么样——也就是元数据模型。
我见过不少团队,一上来就急着画血缘图,结果连「表跟字段的关系」都没理清,画出来的图根本没法用。说白了,血缘元数据模型就是给数据关系「建档案」。档案建得细,后面查问题才快。
2.1 表级血缘:最粗的粒度
表级血缘,看的是表与表之间的依赖关系。比如一张报表数据来自哪几张源表,或者一张中间表被哪些下游表引用。
我个人习惯把表级血缘比作「数据地图上的城市」。你不需要知道城市里每条街怎么走,但得知道A城市到B城市有路。
表级血缘的核心要素:
- 源表:数据从哪里来
- 目标表:数据往哪里去
- 依赖方向:上游→下游
- 调度批次:T+1、实时等
举个例子,一个典型的数仓分层:
ODS.order_info → DWD.dwd_order_detail → DWS.dws_order_daily → APP.rpt_order_summary
这就是一条表级血缘链。你看到APP层报表数据有问题,顺着这条链往上查,很快就能定位到ODS层还是DWD层出了岔子。
我在项目中遇到过,有个同事排查数据延迟,从APP层一路查到ODS层,花了整整两天。后来我帮他搭了表级血缘图谱,再出问题,鼠标点两下就定位到了。嗯,这就是建模的价值。
2.2 字段级血缘:精细到细胞
表级血缘能告诉你「哪张表影响了哪张表」,但很多时候这还不够。比如某个金额字段算错了,你得知道这个字段是从源表的哪个字段来的、经过了什么转换。
字段级血缘,说白了就是「字段到字段」的映射关系。它比表级血缘精细得多,也复杂得多。
| 维度 | 表级血缘 | 字段级血缘 |
|---|---|---|
| 粒度 | 表 | 字段 |
| 复杂度 | 低 | 高 |
| 存储量 | 小 | 大(可能大10倍以上) |
| 典型场景 | 链路追踪、影响分析 | 字段溯源、口径对齐 |
| 维护成本 | 低 | 高(需解析SQL) |
字段级血缘怎么存?我建议至少记录这几个属性:
- 源字段:如
ods.order_info.pay_amount - 目标字段:如
dwd.dwd_order_detail.pay_amt - 转换逻辑:如
COALESCE(pay_amount, 0) - 表达式类型:直接映射、函数转换、条件判断
我的经验:字段级血缘的解析,核心是SQL解析器。别自己从头写,用开源的 sqlparse(Python)或 ANTLR 生成的语法树来解析,省时省力。我曾经手写过一次解析器,踩了无数坑,后来老老实实换了开源方案。
2.3 ETL过程血缘:把「怎么变的」记下来
表级和字段级血缘,更多是描述「数据是什么」。但数据不会自己变,它得经过ETL过程。ETL过程血缘,记录的就是「数据是怎么变的」。
你想想看,一个字段从源表到目标表,中间可能经历了:
- 从A表JOIN B表
- 过滤掉状态为0的记录
- 对金额做四舍五入
- 聚合求和
每一步都可能引入问题。ETL过程血缘,就是把每一步的算子、参数、输入输出都记录下来。
注意:ETL过程血缘的存储量非常大。一个复杂的ETL任务,可能产生上千个算子节点。我建议只记录关键算子(JOIN、FILTER、AGGREGATE、UNION),不要事无巨细全记,否则存储和查询都会爆炸。
ETL过程血缘的典型结构:
{
"job_id": "etl_dwd_order_001",
"job_type": "SPARK_SQL",
"operators": [
{
"op_id": "op_001",
"op_type": "TABLE_SCAN",
"input_table": "ods.order_info",
"output_fields": ["order_id", "pay_amount", "status"]
},
{
"op_id": "op_002",
"op_type": "FILTER",
"condition": "status = 1",
"input_op": "op_001"
},
{
"op_id": "op_003",
"op_type": "AGGREGATE",
"group_by": ["order_id"],
"agg_func": "SUM(pay_amount)",
"input_op": "op_002",
"output_table": "dwd.dwd_order_detail"
}
]
}
有了这个过程血缘,哪天数据对不上了,你可以回放整个ETL流程,看看是哪一步出了问题。我曾经靠这个定位过一个Bug——一个FILTER条件写反了,导致过滤掉了90%的数据。如果没有过程血缘,这种问题查起来简直是大海捞针。
2.4 血缘的粒度与层次:怎么选?
讲到这里,你可能会问:那我到底该用哪种粒度?
答案是:看场景。不同场景需要不同粒度的血缘。
| 场景 | 推荐粒度 | 原因 |
|---|---|---|
| 数据链路监控 | 表级 | 快速定位哪张表延迟或失败 |
| 字段口径对齐 | 字段级 | 精确知道字段来源和转换逻辑 |
| ETL故障排查 | 过程级 | 回放每一步,定位具体算子 |
| 影响分析(上游变更) | 表级+字段级 | 先看表级影响范围,再看字段级细节 |
| 数据质量稽核 | 字段级+过程级 | 需要知道字段的完整加工链路 |
我个人建议,起步阶段先做表级血缘,成本低、见效快。等团队成熟了、工具链完善了,再逐步上字段级和过程级。别一上来就想搞大而全,容易烂尾。
2.5 血缘层次模型:一张图看懂
下面这张图,是我梳理的血缘元数据层次模型。它把表级、字段级、ETL过程级的关系串在了一起。
这张图想表达的核心思想是:三层血缘不是互斥的,而是互补的。表级血缘给你「全局地图」,字段级血缘给你「街道详情」,ETL过程血缘给你「交通摄像头记录」。三者结合,才能真正做到数据问题可追溯。
总结一下:
- 表级血缘:快速定位「哪张表」出了问题
- 字段级血缘:精确找到「哪个字段」、怎么来的
- ETL过程血缘:回放「每一步」加工,定位具体算子
- 粒度选择:从粗到细,逐步建设,别贪多