第三章 技术元数据采集:从数据库到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任务,可能有几十个步骤、上百个字段转换。要理清每条数据的来龙去脉,确实不容易。

我常用的方法有三种:

  1. 静态解析:解析ETL任务的配置文件或脚本,提取Source→Transform→Target的映射关系
  2. 动态追踪:在ETL运行时注入探针,记录每条数据的实际流向
  3. 日志分析:从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工具里又做了一次聚合。

我建议分两步走:

  1. 粗粒度血缘:先搞清楚报表用了哪些表、哪些字段
  2. 细粒度血缘:再深入到字段级别的转换逻辑

我的经验:细粒度血缘采集,别指望自动化工具能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 技术元数据采集架构总览

说了这么多,咱们用一张图来总结一下技术元数据采集的整体架构。这张图我画了很多次,每次给团队培训都用它。

技术元数据采集架构总览 数据源层 数据库(MySQL/PostgreSQL/Oracle) | ETL工具(Informatica/Airflow) | BI工具(Tableau/Power BI) | API网关(Kong/Apigee) 采集适配层 JDBC/ODBC连接器 | ETL API适配器 | BI REST客户端 | OpenAPI解析器 元数据加工层 数据清洗 | 格式标准化 | 字段映射 | 血缘解析 | 质量校验 存储与消费层 元数据存储库(Neo4j/Elasticsearch) | 数据目录 | 血缘图谱 | API文档

这张图展示了技术元数据采集的四个层次:

  • 数据源层:各种数据源,包括数据库、ETL、BI、API
  • 采集适配层:针对不同数据源的连接器和适配器
  • 元数据加工层:对采集到的原始元数据进行清洗、标准化、关联
  • 存储与消费层:将加工后的元数据存入元数据平台,供数据目录、血缘图谱等消费

总结一下:技术元数据采集不是一次性工作,而是一个持续迭代的过程。我建议你从数据库元数据开始,逐步扩展到ETL、BI、API。每扩展一个数据源,都要做好元数据的关联映射。别贪多求快,稳扎稳打才是正道。