第三章 技术元数据采集:从数据库到API的全链路实战
技术元数据采集,说白了就是给企业的数据资产做「人口普查」。你得知道有哪些表、字段怎么定义的、数据从哪里来、又流向了哪里。我做了这么多年数据治理,发现很多团队一开始都栽在采集这一步——要么漏采了关键元数据,要么采回来的数据质量太差,根本没法用。
这一章,咱们就聊聊四种核心技术元数据的采集方法。我会把我在项目中踩过的坑、总结的经验都抖出来。
3.1 数据库元数据采集
数据库元数据是技术元数据的基础。没有它,后面的ETL、BI、API元数据都成了空中楼阁。
3.1.1 表与字段元数据
采集表与字段元数据,最直接的方式就是查询系统表或信息模式(Information Schema)。不同的数据库,查询方式略有差异,但核心信息大同小异。
| 数据库类型 | 系统表/视图 | 关键字段 |
|---|---|---|
| MySQL | information_schema.TABLES, COLUMNS | TABLE_NAME, COLUMN_NAME, DATA_TYPE, IS_NULLABLE |
| PostgreSQL | pg_catalog.pg_tables, information_schema.columns | tablename, column_name, udt_name, is_nullable |
| Oracle | ALL_TAB_COLUMNS, ALL_TABLES | TABLE_NAME, COLUMN_NAME, DATA_TYPE, NULLABLE |
| SQL Server | sys.tables, sys.columns | name, object_id, system_type_id, is_nullable |
我的经验:别只采字段名和类型。我建议把字段的注释(COMMENT)也一并采集。很多业务字段光看名字根本猜不出含义,注释往往是救命稻草。我在一个项目中,就因为采集了注释,才发现有30%的字段命名和实际业务含义对不上。
采集脚本其实不复杂,核心就是拼SQL。我给你看个MySQL的例子:
-- 采集所有表的元数据
SELECT
TABLE_SCHEMA,
TABLE_NAME,
TABLE_TYPE,
ENGINE,
TABLE_ROWS,
CREATE_TIME,
TABLE_COMMENT
FROM information_schema.TABLES
WHERE TABLE_SCHEMA NOT IN ('mysql', 'information_schema', 'performance_schema');
-- 采集所有字段的元数据
SELECT
TABLE_SCHEMA,
TABLE_NAME,
COLUMN_NAME,
ORDINAL_POSITION,
COLUMN_DEFAULT,
IS_NULLABLE,
DATA_TYPE,
CHARACTER_MAXIMUM_LENGTH,
NUMERIC_PRECISION,
NUMERIC_SCALE,
COLUMN_COMMENT
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA NOT IN ('mysql', 'information_schema', 'performance_schema')
ORDER BY TABLE_SCHEMA, TABLE_NAME, ORDINAL_POSITION;
3.1.2 索引与分区元数据
索引和分区信息,很多人觉得不重要。其实不然——它们直接影响查询性能和数据分布。我见过一个团队,因为没采集分区信息,导致数据生命周期管理完全失控。
索引元数据采集要点:
- 索引名称与类型:主键、唯一索引、普通索引、全文索引
- 索引字段:字段顺序、排序方向
- 索引状态:是否有效、是否启用
- 存储参数:填充因子、页数、大小
分区元数据采集要点:
- 分区策略:范围分区、列表分区、哈希分区
- 分区键:用于分区的字段
- 分区边界:每个分区的值范围
- 分区状态:是否可访问、数据行数
避坑指南:我曾经在一个金融项目中,采集了5000多张表的分区信息。结果发现,有200多张表的分区策略已经失效——数据全写到了默认分区。原因就是开发人员改了业务代码,但忘了更新分区边界。从那以后,我每次采集都会加一个「分区有效性」的校验逻辑。
3.2 ETL元数据采集
ETL元数据,说白了就是数据血缘的「骨架」。你得知道数据从哪里来、经过什么转换、最终去了哪里。
3.2.1 ETL任务元数据
采集ETL任务元数据,核心是抓取任务的定义信息和运行状态。不同的ETL工具,采集方式不同:
| ETL工具 | 采集方式 | 核心元数据 |
|---|---|---|
| Informatica | Repository API | Workflow, Session, Mapping, Source/Target |
| DataStage | Director API | Job, Stage, Link, Parameter |
| Kettle | XML解析 | Transformation, Step, Hop, Database Connection |
| Airflow | MetaDB查询 | DAG, Task, Operator, Dependencies |
我个人的习惯是,不管用什么工具,都优先采集以下信息:
- 任务名称与描述:方便后续检索
- 调度频率:每天、每小时、还是实时
- 依赖关系:上游任务、下游任务
- 运行历史:最近100次运行的状态、耗时、数据量
- 错误日志:最近10次失败的详细原因
3.2.2 数据血缘采集
数据血缘是ETL元数据中最难啃的骨头。你想想看,一个复杂的ETL任务,可能有几十个步骤、上百个字段转换。要理清每条数据的来龙去脉,确实不容易。
我常用的方法有三种:
- 静态解析:解析ETL任务的配置文件或脚本,提取Source→Transform→Target的映射关系
- 动态追踪:在ETL运行时注入探针,记录每条数据的实际流向
- 日志分析:从ETL的运行日志中,解析出输入输出关系
核心观点:静态解析适合简单场景,动态追踪准确但性能开销大。我建议先做静态解析,覆盖80%的血缘关系。剩下的20%,用动态追踪做补充。别一上来就想做到100%准确,那会把你累死。
3.3 BI报表元数据采集
BI报表元数据,是技术元数据中最容易被忽视的一块。很多团队把数据库和ETL的元数据采完了,就觉得万事大吉。结果业务部门问「这个报表的数据准不准?」——没人能回答。
3.3.1 报表与仪表板元数据
BI报表元数据采集,核心是抓取报表的定义信息和数据源关系。主流BI工具都提供了API或系统表:
- Tableau:通过Tableau Server REST API或工作簿XML解析
- Power BI:通过Power BI REST API或数据集元数据查询
- Superset:直接查询元数据库的slices和dashboards表
- Metabase:通过Metabase API或数据库直连
采集的内容包括:
- 报表名称、描述、创建者、创建时间
- 报表使用的数据源(数据库、表、视图)
- 报表中的字段、度量、维度
- 报表的刷新频率、最后刷新时间
- 报表的访问权限、使用频率
3.3.2 字段级血缘追溯
BI报表的字段级血缘,是最有价值但也最难采集的。举个例子:报表上显示「本月销售额」,这个字段可能来自数据库的3个表、经过5个ETL步骤、最后在BI工具里又做了一次聚合。
我建议分两步走:
- 粗粒度血缘:先搞清楚报表用了哪些表、哪些字段
- 细粒度血缘:再深入到字段级别的转换逻辑
我的经验:细粒度血缘采集,别指望自动化工具能100%搞定。我通常会结合人工标注——让BI开发人员把关键字段的血缘关系手动录入元数据平台。虽然听起来有点「土」,但效果比纯自动采集好得多。
3.4 API元数据采集
API元数据,是技术元数据的新成员。以前大家只关注数据库和ETL,现在微服务架构普及了,API成了数据流转的关键节点。
3.4.1 API接口元数据
API元数据采集,核心是抓取接口的定义信息和数据契约。常用的采集方式:
- OpenAPI/Swagger:解析API文档的YAML或JSON文件
- gRPC:解析proto文件,提取service和message定义
- GraphQL:解析schema文件,提取type、query、mutation
- API网关:从Kong、Apigee等网关的管理API获取
采集的内容:
- 接口路径、方法(GET/POST/PUT/DELETE)
- 请求参数、请求体结构
- 响应结构、状态码
- 接口版本、废弃状态
- 接口的调用频率、平均响应时间
3.4.2 数据契约与Schema
API的数据契约,说白了就是接口的输入输出规范。它和数据库的表结构一样重要——决定了数据在服务间流转时的格式和约束。
我建议把API的Schema和数据库的表结构做关联映射。举个例子:
// API响应Schema
{
"orderId": "string",
"customerName": "string",
"totalAmount": "number",
"items": [
{
"productId": "string",
"quantity": "integer",
"price": "number"
}
]
}
// 对应的数据库表结构
orders: order_id(varchar), customer_name(varchar), total_amount(decimal)
order_items: order_id(varchar), product_id(varchar), quantity(int), price(decimal)
避坑指南:我曾经在一个项目中,发现API的响应字段和数据库字段有30%的命名不一致。比如API叫「customerName」,数据库叫「cust_name」。这种不一致,如果不做映射,数据血缘根本连不起来。所以,API元数据采集一定要做字段映射。
3.5 技术元数据采集架构总览
说了这么多,咱们用一张图来总结一下技术元数据采集的整体架构。这张图我画了很多次,每次给团队培训都用它。
这张图展示了技术元数据采集的四个层次:
- 数据源层:各种数据源,包括数据库、ETL、BI、API
- 采集适配层:针对不同数据源的连接器和适配器
- 元数据加工层:对采集到的原始元数据进行清洗、标准化、关联
- 存储与消费层:将加工后的元数据存入元数据平台,供数据目录、血缘图谱等消费
总结一下:技术元数据采集不是一次性工作,而是一个持续迭代的过程。我建议你从数据库元数据开始,逐步扩展到ETL、BI、API。每扩展一个数据源,都要做好元数据的关联映射。别贪多求快,稳扎稳打才是正道。