元数据采集:手动采集 vs 自动采集
元数据采集,说白了就是把你数据库里那些「关于数据的数据」给捞出来。我刚开始做数据治理那会儿,觉得这事特简单——不就是查几个系统表嘛。后来才发现,采集方式选不对,后面整个数据目录都是坑。
今天咱们就聊聊采集的两种主流方式:手动和自动。以及两个最常用的技术手段:JDBC/ODBC 和 API。
手动采集 vs 自动采集
先看个对比,心里有个底:
| 对比维度 | 手动采集 | 自动采集 |
|---|---|---|
| 操作方式 | 人工编写 SQL / 导出 CSV | 调度任务定时执行 |
| 实时性 | 低,依赖人工触发 | 高,可配置分钟级 |
| 准确性 | 容易出错,漏字段是常事 | 稳定,按规则执行 |
| 适用场景 | 临时调研、小规模验证 | 生产环境、大规模治理 |
| 维护成本 | 低(但隐性成本高) | 初期高,后期省心 |
手动采集,我最早在项目里用过。那时候团队刚起步,就几张表,我直接连上数据库跑 SELECT * FROM information_schema.columns,然后把结果贴到 Excel 里。嗯,当时觉得挺快。但后来表多了,业务方天天改字段,我每周都要手动跑一遍,漏一次就出问题。
自动采集就不一样了。你写一个采集脚本,挂到调度平台上,每天凌晨跑一次。新表、新字段自动入库,你只需要看增量报告就行。说白了,自动采集才是数据目录的「心脏」。
JDBC/ODBC 采集数据库元数据
JDBC 和 ODBC 是两种最经典的数据库连接协议。JDBC 是 Java 生态的,ODBC 是微软家的。但不管哪种,核心思路都一样:通过标准接口,读取数据库的系统表或视图。
我习惯用 JDBC,因为 Java 生态的工具链太成熟了。比如你要采集 MySQL 的元数据,核心代码就这几行:
// 获取数据库元数据
DatabaseMetaData metaData = connection.getMetaData();
// 获取所有表
ResultSet tables = metaData.getTables(null, null, "%", new String[]{"TABLE"});
while (tables.next()) {
String tableName = tables.getString("TABLE_NAME");
String tableComment = tables.getString("REMARKS");
System.out.println("表名: " + tableName + ", 注释: " + tableComment);
}
// 获取指定表的列信息
ResultSet columns = metaData.getColumns(null, null, "user_info", "%");
while (columns.next()) {
String colName = columns.getString("COLUMN_NAME");
String colType = columns.getString("TYPE_NAME");
int colSize = columns.getInt("COLUMN_SIZE");
String colComment = columns.getString("REMARKS");
System.out.println("字段: " + colName + ", 类型: " + colType + ", 大小: " + colSize + ", 注释: " + colComment);
}
你看,核心就两个方法:getTables() 和 getColumns()。但实际项目中,你还要处理更多信息:
- 主键信息:
getPrimaryKeys() - 索引信息:
getIndexInfo() - 外键关系:
getImportedKeys() - 存储过程:
getProcedures()
我记得有一次,客户要求把 Oracle 里几百个存储过程的入参和出参都采集出来。我一开始用 getProcedureColumns() 一个个查,慢得要死。后来改成批量查询 ALL_ARGUMENTS 视图,效率直接翻了 10 倍。所以,JDBC 标准接口虽然好用,但遇到性能瓶颈时,别忘了直接查数据库原生的系统表。
getTables() 默认不返回视图,需要把类型参数改成 new String[]{"VIEW"}。踩过一次坑之后,我每次都会先打印一下驱动版本。
API 采集
API 采集,说白了就是调用数据源对外暴露的 HTTP 接口来拿元数据。这招在云数据库、SaaS 平台、或者自研系统中特别常用。
举个例子,你要采集 AWS Glue 数据目录里的元数据,直接调它的 REST API:
GET /v1/databases/{databaseName}/tables HTTP/1.1
Authorization: Bearer <your->
Content-Type: application/json
响应示例:
{
"TableList": [
{
"Name": "user_info",
"CreateTime": "2024-01-15T10:30:00Z",
"StorageDescriptor": {
"Columns": [
{"Name": "user_id", "Type": "int", "Comment": "用户ID"},
{"Name": "user_name", "Type": "string", "Comment": "用户名"}
]
}
}
]
}
API 采集的好处很明显:
- 跨平台:不管底层是 MySQL 还是 PostgreSQL,API 返回的 JSON 结构是统一的
- 权限控制:API 本身就有认证和授权,不用暴露数据库密码
- 增量采集:很多 API 支持按时间戳过滤,只拉取变更的部分
但 API 采集也有坑。我遇到过最头疼的问题就是限流。有一次对接某个云厂商的元数据 API,每分钟只能调 100 次。我那个数据目录里有 5000 多张表,按这个速度得跑将近一个小时。后来我加了本地缓存和重试机制,才勉强跑通。
三种采集方式的选型建议
你可能会问:那我到底该用哪种?我个人的经验是:
- 内部数据库(MySQL、PostgreSQL、Oracle):优先 JDBC,性能好,信息全
- 云数据库(AWS RDS、阿里云 RDS):优先 API,避免直连数据库
- SaaS 平台(Salesforce、Snowflake):只能用 API,没得选
- 自研系统:如果系统有元数据管理模块,优先 API;没有的话,退而求其次用 JDBC
下面这张图,是我在项目中总结的采集流程,你可以参考:
最后说一句,不管选哪种方式,元数据采集的最终目标不是「采到」,而是「采对」。我见过太多项目,采集脚本跑得飞起,但采回来的字段注释全是空的,或者类型映射错了。所以,每次上线前,一定要做一次人工抽检,看看采集结果和实际数据库是否一致。