
简介中电金信数据资产管理平台PDF文档面向企业数据管理者、数字化转型负责人及数据运营从业者聚焦数据资产与业务粘合度低、使用情况难追踪、服务需求响应慢等痛点。文档系统阐述平台如何打通数据资产管理到运营的闭环涵盖实时采集、治理、存储、查询、展示全链路并搭载数据智能引擎通过资产内容服务、接口服务、运营分析、消费监控及资产地图五大支柱降低数据使用门槛。资源包共1个PDF文件约2.01MB内容完整呈现产品亮点、客户背景、解决方案与某银行落地案例便于快速理解平台架构与实施路径。目前已有425人学习下载适合需要构建数据中台、推进数据驱动决策的读者参考可从中获取数据资产盘点、API统一管理、资产注册与需求服务闭环的实操思路为数字化经营提供可借鉴的落地框架。1. 数据资产管理平台到底管什么从一份 PDF 文档说起很多团队第一次接触「数据资产管理平台」这个词是因为拿到了一份 PDF 格式的方案文档里面画着数据目录、血缘图谱、质量规则、资产盘点几大模块看完觉得都对但落到自己环境里就不知道从哪下手。我见过不止一个团队把这份 PDF 打印出来贴在工位上三个月后系统还是没跑起来。问题不在文档在于数据资产管理平台本质是一套「元数据驱动的治理系统」它管的是数据在哪、谁在用、质量如何、值多少钱而不是一个装完就能用的软件。这篇笔记就按一线落地的顺序把这类平台从概念到最小可运行版本讲清楚适合正在做数据治理选型的数据工程师、刚接手元数据模块的后端以及需要给团队搭一套资产目录的技术负责人。读完你应该能判断自己团队该不该上、先上哪块、以及第一版怎么跑通。2. 拆解数据资产管理平台的四个核心模块与选型逻辑数据资产管理平台这个词听起来大拆开看其实就四件事把数据登记成资产、把资产之间的关系画出来、给资产定质量规则、把资产的使用情况量化。这四件事对应四个模块落地顺序不能乱乱了就会做成一个没人用的花架子。2.1 元数据采集资产目录的地基怎么打元数据采集是整个平台的地基。没有元数据后面的血缘、质量、盘点全是空中楼阁。采集分两类技术元数据和业务元数据。技术元数据从数据库、数仓、消息队列的系统表里抽业务元数据靠人工录入或从指标平台同步。常见做法是先用 JDBC 连到各类数据源的 information_schema把库、表、字段、类型、注释拉下来。下面是一个最小可用的采集脚本用 Python 写跑在调度系统里每天一次。import pymysql import json from datetime import datetime # 数据源配置实际项目里从配置中心读取 SOURCE_CONFIG { host: 10.0.0.10, port: 3306, user: meta_reader, password: ******, database: information_schema } def collect_technical_meta(schema_name): 采集指定库的技术元数据返回表级和字段级信息 conn pymysql.connect(**SOURCE_CONFIG) cursor conn.cursor(pymysql.cursors.DictCursor) # 表级元数据表名、注释、引擎、行数估算 cursor.execute( SELECT TABLE_NAME, TABLE_COMMENT, ENGINE, TABLE_ROWS FROM TABLES WHERE TABLE_SCHEMA %s , (schema_name,)) tables cursor.fetchall() result [] for t in tables: # 字段级元数据字段名、类型、是否可空、注释 cursor.execute( SELECT COLUMN_NAME, DATA_TYPE, IS_NULLABLE, COLUMN_COMMENT FROM COLUMNS WHERE TABLE_SCHEMA %s AND TABLE_NAME %s , (schema_name, t[TABLE_NAME])) columns cursor.fetchall() result.append({ table: t[TABLE_NAME], comment: t[TABLE_COMMENT], engine: t[ENGINE], row_estimate: t[TABLE_ROWS], columns: columns, collected_at: datetime.now().isoformat() }) cursor.close() conn.close() return result if __name__ __main__: meta collect_technical_meta(ods) # 写入元数据存储这里简化为打印 print(json.dumps(meta, ensure_asciiFalse, indent2))这段代码的逻辑很直白连 information_schema先拿表清单再逐表拿字段清单拼成一个嵌套结构。参数上要注意三个点。第一meta_reader账号只给 SELECT 权限别用业务账号否则采集脚本一旦写错会污染生产库。第二TABLE_ROWS在 InnoDB 里是估算值误差可能到 50%做资产盘点时不能直接当准确行数用要配合ANALYZE TABLE或采样。第三采集频率别太高一天一次足够高频采集会让源库的 information_schema 查询堆积我见过一个团队设成五分钟一次结果源库 CPU 常年 30% 花在元数据查询上。业务元数据的采集没有通用脚本因为每家的指标定义方式不同。常见做法是建一张业务元数据表字段包括资产 ID、业务名称、负责人、所属域、更新频率、SLA 等级由数据 owner 在平台上手工维护或通过 Excel 批量导入。这里的关键是资产 ID 必须和技术元数据的表名做映射映射关系一旦断了后面血缘就串不起来。2.2 血缘解析从 SQL 日志里还原表级依赖血缘是数据资产管理平台里最容易被低估的模块。很多人以为血缘就是画个图实际上血缘的准确性直接决定了故障排查效率。血缘分表级和字段级表级血缘靠解析 SQL 就能拿到字段级血缘需要解析执行计划或做 AST 分析成本高很多。第一版建议只做表级。表级血缘的数据来源有三个调度系统的任务配置、数据库的慢查询日志、数仓的查询历史表。最可靠的是调度系统配置因为任务和上下游关系是显式声明的。下面是一个从 SQL 文本里提取表级血缘的简化实现用正则做适合 SQL 风格统一的团队。import re # 匹配 FROM 和 JOIN 后面的表名支持 schema.table 格式 TABLE_PATTERN re.compile( r\b(?:FROM|JOIN)\s([a-zA-Z_][\w]*\.[a-zA-Z_][\w]*), re.IGNORECASE ) # 匹配 INSERT INTO 或 INSERT OVERWRITE 的目标表 TARGET_PATTERN re.compile( r\bINSERT\s(?:INTO|OVERWRITE)\s(?:TABLE\s)?([a-zA-Z_][\w]*\.[a-zA-Z_][\w]*), re.IGNORECASE ) def parse_lineage(sql_text): 从单条 SQL 中提取源表和目标表返回血缘边列表 sources set(TABLE_PATTERN.findall(sql_text)) targets set(TARGET_PATTERN.findall(sql_text)) edges [] for t in targets: for s in sources: if s ! t: # 排除自引用 edges.append({source: s, target: t}) return edges if __name__ __main__: sql INSERT OVERWRITE TABLE dwd.user_order SELECT o.order_id, o.user_id, u.user_name FROM ods.order_info o JOIN ods.user_info u ON o.user_id u.user_id WHERE o.dt 2024-01-01 for edge in parse_lineage(sql): print(f{edge[source]} - {edge[target]})这段代码能跑通但只适合 SQL 写法规范的场景。参数和边界上有几个坑要提前说。第一正则匹配不了子查询里的表比如FROM (SELECT ... FROM ods.xxx)这种源表会漏掉。要覆盖子查询得用 SQL 解析器比如 sqlparse 或 calcite成本高一个量级。第二CTEWITH 子句里的表名会被当成源表实际上它是中间结果需要在解析前把 CTE 名字排除掉。第三大小写和反引号不同数据库的 SQL 方言不一样正则要按方言调整。我一般建议第一版先接受 80% 的准确率把明显错的边人工修掉等 SQL 规范统一了再上解析器。血缘数据存下来之后要提供一个查询接口输入一张表返回它的上游和下游。这个接口是后面故障排查的核心工具。我见过一个团队没做血缘一次上游表字段变更导致下游二十张报表出错排查花了两天如果有血缘图五分钟就能定位影响范围。2.3 质量规则把「数据对不对」变成可执行的检查项质量规则模块解决的是「数据对不对」的问题。规则分四类完整性、唯一性、有效性、一致性。完整性查空值率唯一性查主键重复有效性查枚举值和范围一致性查跨表对账。每类规则对应一段可执行的 SQL跑完返回通过或不通过。规则的定义要落到配置表里不能硬编码在脚本里。下面是一张质量规则配置表的结构用 SQL 建表。CREATE TABLE dq_rule_config ( rule_id BIGINT PRIMARY KEY AUTO_INCREMENT, rule_name VARCHAR(128) NOT NULL COMMENT 规则名称, target_table VARCHAR(128) NOT NULL COMMENT 目标表schema.table, rule_type VARCHAR(32) NOT NULL COMMENT 规则类型completeness/uniqueness/validity/consistency, rule_sql TEXT NOT NULL COMMENT 规则检查 SQL返回一个数值, threshold DECIMAL(10,4) NOT NULL COMMENT 阈值超过则告警, compare_op VARCHAR(8) NOT NULL DEFAULT COMMENT 比较符 , owner VARCHAR(64) NOT NULL COMMENT 规则负责人, schedule_cron VARCHAR(64) NOT NULL COMMENT 调度表达式, enabled TINYINT NOT NULL DEFAULT 1 COMMENT 是否启用, created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ) COMMENT 质量规则配置表;这张表的设计要点在于rule_sql字段。它存的是一段返回单个数值的 SQL比如查空值率就是SELECT COUNT(*) FROM t WHERE col IS NULL查重复就是SELECT COUNT(*) - COUNT(DISTINCT pk) FROM t。调度系统按schedule_cron拉起任务执行rule_sql拿返回值跟threshold按compare_op比较超了就告警。参数上要注意threshold的设定。空值率阈值不能一刀切设成 0因为很多表在 T1 凌晨跑批时中间状态本来就有空值设成 0 会天天误报。常见做法是按历史均值加三倍标准差动态算阈值或者按业务容忍度设比如用户表手机号空值率容忍 1%订单表金额空值率容忍 0。compare_op也要注意方向空值率是越小越好用对账一致率是越大越好用配反了告警逻辑就完全错了。规则跑完的结果要存历史不能只存最新一次。存历史才能看趋势才能判断是偶发还是持续恶化。结果表至少要有 rule_id、执行时间、实际值、是否通过四个字段。2.4 资产盘点把元数据变成可量化的资产台账资产盘点是数据资产管理平台的输出层。它把前面采集的元数据、血缘、质量结果汇总成一张资产台账回答「我们有多少张表、多少字段、多少有负责人、多少有质量规则、多少被下游使用」这些问题。盘点的核心指标有五个资产总数、有 owner 的资产占比、有质量规则的资产占比、有下游使用的资产占比、近三十天被查询过的资产占比。这五个指标能反映治理成熟度。我一般建议团队先盯「有 owner 占比」和「有下游使用占比」这两个低于 60% 说明资产目录还没真正用起来。盘点结果要能按域、按负责人、按存储大小下钻。存储大小从源库的 information_schema 拿或者从 HDFS 的 fsimage 拿。下钻维度决定了盘点能不能指导行动只能看总数的盘点报告没人会看。3. 用最小可运行版本跑通资产目录从建表到出报告概念讲完这一章讲怎么把上面四个模块串成一个能跑的最小版本。目标不是做一个完整平台而是让资产目录先转起来有数据、有页面、有人用。技术栈选 Python MySQL 一个轻量 Web 框架不引入大数据组件单机就能跑。3.1 元数据存储表设计五张表撑起资产目录最小版本的元数据存储只需要五张表数据源表、表元数据表、字段元数据表、血缘边表、质量结果表。建表语句如下。-- 数据源注册表 CREATE TABLE meta_datasource ( ds_id INT PRIMARY KEY AUTO_INCREMENT, ds_name VARCHAR(64) NOT NULL COMMENT 数据源名称, ds_type VARCHAR(32) NOT NULL COMMENT 类型mysql/hive/pg, host VARCHAR(128) NOT NULL, port INT NOT NULL, db_name VARCHAR(64) NOT NULL, owner VARCHAR(64) NOT NULL, created_at DATETIME DEFAULT CURRENT_TIMESTAMP ); -- 表级元数据 CREATE TABLE meta_table ( table_id BIGINT PRIMARY KEY AUTO_INCREMENT, ds_id INT NOT NULL, schema_name VARCHAR(64) NOT NULL, table_name VARCHAR(128) NOT NULL, table_comment VARCHAR(512), row_estimate BIGINT DEFAULT 0, biz_domain VARCHAR(64) COMMENT 业务域, biz_owner VARCHAR(64) COMMENT 业务负责人, sla_level VARCHAR(8) COMMENT SLA等级P0/P1/P2, collected_at DATETIME NOT NULL, UNIQUE KEY uk_ds_table (ds_id, schema_name, table_name) ); -- 字段级元数据 CREATE TABLE meta_column ( col_id BIGINT PRIMARY KEY AUTO_INCREMENT, table_id BIGINT NOT NULL, col_name VARCHAR(128) NOT NULL, data_type VARCHAR(64) NOT NULL, is_nullable VARCHAR(4) NOT NULL, col_comment VARCHAR(512), is_primary TINYINT DEFAULT 0, UNIQUE KEY uk_table_col (table_id, col_name) ); -- 血缘边 CREATE TABLE meta_lineage ( edge_id BIGINT PRIMARY KEY AUTO_INCREMENT, src_table_id BIGINT NOT NULL, dst_table_id BIGINT NOT NULL, task_name VARCHAR(128) COMMENT 产生该血缘的任务, confidence DECIMAL(3,2) DEFAULT 1.00 COMMENT 置信度, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, UNIQUE KEY uk_edge (src_table_id, dst_table_id, task_name) ); -- 质量检查结果 CREATE TABLE dq_result ( result_id BIGINT PRIMARY KEY AUTO_INCREMENT, rule_id BIGINT NOT NULL, exec_time DATETIME NOT NULL, actual_value DECIMAL(18,4) NOT NULL, passed TINYINT NOT NULL, detail VARCHAR(512), KEY idx_rule_time (rule_id, exec_time) );五张表的关系是数据源下面挂表表下面挂字段表和表之间通过血缘边连接质量结果挂在规则上。meta_table里的biz_domain、biz_owner、sla_level是业务元数据采集脚本不写靠人工维护。meta_lineage的confidence字段用来标记血缘的可靠程度正则解析出来的设 0.8调度配置里显式声明的设 1.0查询时按置信度过滤。3.2 采集任务编排用 cron 串起采集、解析、检查三步采集任务用 cron 编排每天凌晨跑。顺序是先采集技术元数据再解析血缘最后跑质量检查。三步之间有依赖血缘解析依赖表元数据已经入库质量检查依赖规则配置已经就绪。# crontab 配置每天凌晨 2 点开始 0 2 * * * /usr/bin/python3 /opt/dam/collect_meta.py /var/log/dam/collect.log 21 30 2 * * * /usr/bin/python3 /opt/dam/parse_lineage.py /var/log/dam/lineage.log 21 0 3 * * * /usr/bin/python3 /opt/dam/run_dq.py /var/log/dam/dq.log 21三个任务错开半小时给前一步留出写入和索引重建的时间。collect_meta.py遍历meta_datasource里注册的所有数据源逐个采集。parse_lineage.py从调度系统的任务表里拉当天的 SQL解析后写入meta_lineage。run_dq.py从dq_rule_config拉启用的规则逐条执行结果写dq_result。参数上要注意日志切割这三个日志文件不切割的话半年就能涨到几十 G。用 logrotate 配一下按天切保留三十天。另外采集任务要加超时单个数据源超过十分钟没采完就跳过并告警否则一个卡住的源会拖垮整个采集链路。3.3 资产目录查询接口三个 SQL 回答「这张表能不能用」资产目录的价值在于查询。最常用的查询是「这张表能不能用」回答这个问题需要三个信息表的负责人是谁、有没有质量规则、下游有哪些任务依赖。下面是一个查询接口的实现用 Flask 写。from flask import Flask, jsonify, request import pymysql app Flask(__name__) def get_conn(): return pymysql.connect( host127.0.0.1, userdam, password******, databasedam, cursorclasspymysql.cursors.DictCursor ) app.route(/api/table/int:table_id) def table_detail(table_id): conn get_conn() cur conn.cursor() # 基本信息 cur.execute( SELECT t.*, d.ds_name FROM meta_table t JOIN meta_datasource d ON t.ds_id d.ds_id WHERE t.table_id %s , (table_id,)) table cur.fetchone() # 质量规则覆盖情况 cur.execute( SELECT COUNT(*) AS rule_cnt, SUM(CASE WHEN r.passed 1 THEN 1 ELSE 0 END) AS passed_cnt FROM dq_rule_config c LEFT JOIN dq_result r ON c.rule_id r.rule_id AND r.exec_time (SELECT MAX(exec_time) FROM dq_result WHERE rule_id c.rule_id) WHERE c.target_table %s AND c.enabled 1 , (f{table[schema_name]}.{table[table_name]},)) quality cur.fetchone() # 下游依赖 cur.execute( SELECT t2.table_name, l.task_name, l.confidence FROM meta_lineage l JOIN meta_table t2 ON l.dst_table_id t2.table_id WHERE l.src_table_id %s , (table_id,)) downstream cur.fetchall() cur.close() conn.close() return jsonify({ table: table, quality: quality, downstream: downstream }) if __name__ __main__: app.run(host0.0.0.0, port5000)这个接口返回三块数据前端拼成一个详情页。参数上要注意target_table的匹配方式质量规则配置里存的是schema.table格式查询时要拼对。下游依赖查询里confidence字段要透出给用户低于 0.8 的血缘标灰提示用户人工确认。接口性能上meta_lineage表在表数量上万后会变慢src_table_id上要建索引。质量结果的子查询MAX(exec_time)在结果表大了之后也慢常见做法是单独维护一张最新结果表每次跑完更新查询直接读最新表。4. 落地数据资产管理平台最容易翻车的五个地方这一章讲踩坑。下面五条都是我在实际项目里见过或踩过的每条按现象、原因、解决写。4.1 元数据采集把源库拖垮现象采集任务上线后源库的 CPU 使用率明显上升业务查询变慢DBA 找上门。原因采集脚本用information_schema查表清单时MySQL 8.0 之前会打开所有表文件表多的时候 IO 很高。另外采集频率设太高或者采集账号权限过大导致锁竞争。解决采集账号只给SELECT权限且只授information_schema的读权限。采集频率降到一天一次放在业务低峰期。MySQL 8.0 以上用information_schema.tables的DATA_LENGTH替代TABLE_ROWS做估算减少全表扫描。如果源库表超过五千张改用SHOW TABLE STATUS分批拉每批一百张批间 sleep 一秒。4.2 血缘解析把 CTE 当成源表现象血缘图里出现一堆tmp_xxx、cte_xxx这样的节点下游依赖看起来比实际多很多。原因正则解析 SQL 时WITH tmp AS (SELECT ...)里的tmp被FROM tmp匹配到当成了一张真实源表。解决解析前先提取所有 CTE 名字从源表集合里排除。提取 CTE 的正则是WITH\s([\w])\sAS\s*\(支持多个 CTE 用逗号分隔的情况。排除之后血缘边数量会降下来准确率提升明显。如果 CTE 嵌套复杂正则搞不定就上 sqlparse 做 AST 遍历。4.3 质量规则阈值设成 0 导致天天误报现象质量告警群每天凌晨响几十条值班同学看多了直接屏蔽真正的问题反而漏掉。原因空值率、重复率这类规则的阈值设成了 0但跑批中间状态本来就有空值或者上游延迟导致当天数据不全。解决阈值分两档硬阈值和软阈值。硬阈值设业务不可容忍的线比如主键重复率超过 0.1% 才告警。软阈值设趋势线比如空值率比过去七天均值高 50% 才告警。另外告警要分级P0 规则发电话P1 发群消息P2 只记录不通知。告警收敛也要做同一规则连续失败只发第一条恢复时发一条恢复通知。4.4 资产目录没人维护业务元数据现象平台上线三个月技术元数据采集了几万张表但biz_owner字段 90% 是空的资产目录变成一张纯技术清单业务方不看。原因业务元数据靠人工录入没有激励也没有约束数据 owner 没动力填。解决把业务元数据的完整度和数据 owner 的考核挂钩比如 owner 名下资产完整度低于 80% 影响季度评分。同时降低录入成本支持 Excel 批量导入支持从指标平台自动同步。另外做排行榜按域公示完整度利用同侪压力推动。我见过最有效的做法是把「有 owner」作为资产对外共享的前置条件没 owner 的表不允许被下游引用倒逼填写。4.5 血缘置信度不透明导致误判影响范围现象一次上游变更按血缘图通知了下游二十个任务结果其中五个任务其实不依赖这张表白通知另外三个真正依赖的任务反而没通知到。原因血缘边没有区分置信度正则解析出来的边和调度配置里声明的边混在一起用户无法判断哪些可信。解决血缘边加confidence字段调度配置声明的设 1.0正则解析的设 0.8字段级血缘设 0.6。查询时默认只展示 0.8 以上的边低于阈值的折叠起来标注「待确认」。同时提供人工确认入口确认后的边置信度提到 1.0。影响范围通知时只通知置信度 1.0 的下游0.8 的作为参考列出。5. 让资产目录真正被用起来的一个技巧把血缘查询嵌进故障排查流程平台建好了怎么让人用这是最后一公里。我试过做培训、发文档、拉群推广效果都一般。真正让资产目录用起来的是一个很小的改动把血缘查询嵌进故障排查流程。具体做法是在监控告警的每条消息里自动附上相关表的资产目录链接。比如一张表的数据延迟告警消息里除了表名和延迟时间再加一行「影响下游任务点击查看」。值班同学点进去直接看到这张表的下游任务列表、负责人、最近一次质量检查结果。排查从「先查血缘再找人」变成「一步到位」。实现上在告警发送模块里加一个钩子调资产目录的查询接口把下游任务拼成链接。代码大概长这样。import requests def enrich_alert(alert): 给告警消息补充资产目录信息 table_name alert[table] # 调资产目录接口拿下游 resp requests.get( fhttp://dam.internal/api/table/by_name, params{name: table_name}, timeout3 ) if resp.status_code ! 200: return alert # 接口失败不影响告警发送 data resp.json() downstream data.get(downstream, []) if downstream: names , .join([d[table_name] for d in downstream[:5]]) alert[message] f\n影响下游{names} alert[message] f\n详情http://dam.internal/table/{data[table][table_id]} return alert这个钩子的关键参数是超时时间设 3 秒。资产目录接口挂了不能阻塞告警发送所以超时后直接返回原消息。另外下游任务只列前五个多了刷屏剩下的让用户点链接看。这个改动上线两周后资产目录的日活从个位数涨到几十因为值班同学每天都要处理告警每次处理都会点进去看。用起来之后业务元数据的维护也有了动力因为 owner 发现自己的表被频繁查看会主动去补全信息。我自己的习惯是任何治理工具上线先找一条已有的、高频的、必须走的流程把工具嵌进去而不是指望用户主动来用。数据资产管理平台尤其如此它不是一个用户会主动打开的网站而是一个应该在别人流程里被动触发的服务。这个思路我踩过坑才明白早期版本做了很漂亮的资产门户首页大屏、搜索框、排行榜都有结果日活一直上不去后来把血缘查询嵌进告警和调度失败通知才真正转起来。希望帮到你。本文还有配套的精品资源点击获取