第2节:数据发现基础:数据资产盘点、数据源类型
数据发现,说白了就是搞清楚你的企业到底有哪些数据。没有这一步,分类分级就是空中楼阁。我从第一次做DSPM项目开始就深有体会——你连家底都摸不清,谁敢动数据策略?
2.1 数据资产盘点:摸清家底
资产盘点不是简单的“有哪些数据库”,而是要把每个数据对象的物理位置、逻辑归属、存储体量、访问权限、敏感度都理清楚。我习惯把盘点清单分成四个维度:
- 存储层:数据库、文件服务器、云对象存储、大数据平台
- 属主层:业务系统、部门、具体维护人
- 元数据层:表名、字段名、行数、大小、创建时间
- 权限层:谁可以读、谁可以写、是否公网暴露
手动盘点?别想了。我见过一个中型金融客户,光Excel台账就做了两年,最后发现80%的数据根本不在台账里。所以一定要靠自动化扫描工具去抓。下面这张表是我常用的盘点要素模板:
| 要素 | 描述 | 示例值 |
|---|---|---|
| 数据源名称 | 系统可读的唯一标识 | prod_user_db |
| 类型 | 结构化/半结构化/非结构化 | 结构化(MySQL) |
| 存储路径 | 连接字符串或文件路径 | mysql://10.0.1.5:3306/users |
| 总条数/大小 | 数量级估计 | 2.3TB / 1.2亿行 |
| 敏感字段数 | 含身份证、卡号等字段 | 12个 |
| 最近一次扫描 | 时间戳 | 2025-03-21 14:30 |
| 责任人 | AD域账号或Email | zhangsan@corp.com |
我的小技巧:第一次盘点时,不妨先跑一个“广度扫描”——把所有能连的数据源全列出来,再逐个标记属主。这样比一开始就追着业务要清单快得多。
2.2 数据源类型:结构化、半结构化、非结构化
你想想看,DSPM面对的数据源五花八门。我通常把它们分成三大类,每一类的处理方式完全不同。
| 类型 | 定义 | 典型示例 | 存储形态 | 发现难点 |
|---|---|---|---|---|
| 结构化 | 预定义schema,行列严格 | MySQL、Oracle、SQL Server | 表、视图、索引 | 通常容易,直接查系统表 |
| 半结构化 | 自描述schema,数据与元数据混在一起 | JSON、XML、YAML、Avro | 文件、消息、文档 | 需解析嵌套,字段数可能爆炸 |
| 非结构化 | 无统一schema,内容为主 | PDF、图片、音视频、日志 | 文件系统、对象存储 | 需内容识别,处理量大 |
举个例子:关系数据库的表你随便连一下information_schema就能拿到字段清单。但半结构化的JSON呢?我上次处理一个电商的订单数据,一个JSON里嵌了七层子对象,字段名还是动态的。这时候光靠模式识别就不够了,得用flatten + 路径遍历。
非结构化更头疼。因为内容藏在文件里,你得用OCR、NLP甚至图像识别才能判断有没有敏感信息。我曾经帮一个制药公司做数据发现,他们的实验报告全是扫描版PDF,文字提取后才发现大量患者基因数据。嗯,所以分类分级的前提,是先能读懂内容。
关键区别:结构化靠元数据扫描就能完成分类;非结构化必须做内容级分析。半结构化则两头都占——既读元数据,又要解析内部结构。
2.3 数据发现的技术实现
落实到代码层面,数据发现引擎通常分两步走:
- 连接发现:通过网络探测、配置中心拉取、云API列举,找到所有可能的数据源入口。
- 元数据采集:对每个入口执行扫描,抓取表/字段/文件元数据。
下面是一个简化的Python示例,演示如何通过数据库驱动列出MySQL中的所有库和表:
# 示例:MySQL元数据扫描(仅供教学参考)
import pymysql
conn = pymysql.connect(host='10.0.1.5', user='scan_user', password='****')
cursor = conn.cursor()
# 列举所有数据库
cursor.execute("SELECT SCHEMA_NAME FROM information_schema.SCHEMATA")
databases = [row[0] for row in cursor.fetchall()]
for db in databases:
# 跳过系统库
if db in ('information_schema', 'performance_schema', 'mysql'): continue
cursor.execute(f"USE `{db}`")
cursor.execute("SHOW TABLES")
tables = [row[0] for row in cursor.fetchall()]
print(f"数据库 {db} 包含 {len(tables)} 张表")
# 实际工程中还要获取字段名、行数、注释等
cursor.close()
conn.close()
实际产品里还会做更多事情:比如检测敏感字段(身份证、手机号)的正则匹配,或者统计字段里空值比例——空值率高往往意味着字段已废弃。这类经验,不踩几次坑是学不来的。
注意:扫描时一定要遵循最小权限原则。只用只读账号,不要带where条件执行全表查询——否则可能引发生产系统性能问题。我曾经遇到过扫描时没限制连接数,把核心业务库拉垮的案例,后来被叫到老板办公室……你懂的。
2.4 资产盘点的输出物
盘点完之后,通常产出两类结果:
- 资产清单:一张大表,每行一个数据源 + 字段级元数据
- 拓扑图:数据流依赖关系(哪个系统访问了哪个表)
这两样东西是后续分类分级的输入。没有它们,后面所有分析都像在黑暗里找钥匙。
我的习惯:第一次盘点完,一定留一周时间给业务方确认。因为自动扫描无法发现影子IT——比如某个部门自己搭的Access数据库,或者员工桌面上的Excel。手动确认能补上这部分漏洞。
这张图把整个数据发现流程串起来了:从三种数据源出发,经过引擎处理后产出资产清单,最后为分类分级和治理提供基础。实际项目中,引擎层和清单层之间可能有多次迭代——比如先粗扫,再根据业务反馈精扫。记住,数据发现不是一次性工作,你必须不断更新资产清单,因为新库、新表、新文件每天都在产生。