返回 Blog

技术分享

从只读数据库到语义层:一次可复核的解析过程

结构扫描能得到表名、字段和类型,却得不到业务含义。本文说明源宜如何把一个只读数据库逐步解析成可复用的语义层:授权范围如何界定、结构如何映射、口径如何用真实数据核对,并给出一次完整的运行记录。

12 分钟阅读

把数据库接入分析工具通常只需要一串连接串。真正困难的部分在后面:扫描得到的是表名、字段名和数据类型,而分析需要的是业务对象、对象之间的关系,以及每个指标的计算口径。这两者之间的距离,不会因为换一个模型或多做一次扫描而自动消失。

以一张报验日报表为例。扫描可以确认它有八个字段、其中两个是整数、一个是时间戳;但扫描无法回答“一行代表什么”——是一个班组一天一条,还是一个生产节点一条。这个问题答错,后续所有按班组汇总的比例都会偏移。字段注释、主键和外键是判断它的主要线索,因此这些结构事实能否被完整取到,直接决定语义层的起点质量。

下面按四个部分说明:先界定这套解析要解决的问题,再说明工程实现如何组织,然后给出一次完整运行的过程记录,最后说明从语义层继续走向本体层的计划。文中数据库为演示环境,表名、字段与数值均为示例,不对应任何一家企业的实际生产数据。

问数会话中返回的各责任单位报验合格率表格,并附带取数工具与语义层口径的对应说明查看原图
真实产品演示图 · 源宜 0.8.0,装备制造示例数据。表格右侧标注了指标口径的来源,下方给出本次取数所用的结构化查询与核对结论;展示值不代表客户实绩。

问题界定:结构扫描给出的不是业务含义

一个可用于分析的语义层,至少要说明四件事:有哪些业务对象、每个对象一行代表什么、对象之间按什么字段关联、每个指标怎么算。数据库本身只直接提供其中一部分。表名和字段名提供线索,数据类型限定取值范围,主键和外键则是判断记录粒度与关联路径的直接依据。

因此结构事实的完整性,决定了语义层能不能从一个可靠的起点开始。这里有一个容易被忽略的细节:产品建议用只读账号接入生产库,而 PostgreSQL 的 information_schema 约束视图按权限过滤——一个只有 SELECT 权限的账号在其中读不到任何主键与唯一约束,外键却仍可从系统目录读到。若解析程序从前者取约束,真实部署下拿到的主键会长期为空,而开发环境用属主账号连接时一切正常。

这类差异不会报错,只会让语义层缺少判断粒度的依据,进而由模型自行推断。改用系统目录读取约束后,同一个只读账号可以完整取到主键与唯一约束,其中包含由三个字段构成的复合主键——这正是判断“一行代表什么”的关键证据。

工程实现:把授权、结构与取数分成三层

解析过程按三层组织,各自回答不同的问题。第一层是接入与授权:连接凭据保存在本地设备,不上传云端;每次问数由云端签发一份限定范围的只读授权,写明本轮可访问的关系清单、行数与字节上限、有效期,并绑定当前会话。授权到期后需要重新确认,界面会在发送前拦下并说明原因。

第二层是结构映射与版本管理。扫描只读取数据库目录,不读取样本行;结果整理为一份结构快照,包含每张关系的字段、类型、注释、主键、唯一约束和经过范围过滤的外键,并计算内容哈希后发布为一个版本。重新扫描时按上一版本做条件更新,因此并发或重复操作不会覆盖已发布的结果。

第三层是取数与沉淀。模型不编写 SQL,而是填写一份结构化查询:关系名、字段、聚合方式、筛选条件、分组与排序都是受约束的字段,由端侧编译为参数化语句并在本机执行。语义层本身是一份可读文件,包含业务对象、关系、指标、代码值与业务术语,每一条都标注证据来源与确认状态;人工确认过的条目不会被后续运行改写。

过程图解

一次问数的执行顺序

  1. 01

    界定范围

    云端按已发布的结构版本签发只读授权,写明本轮可访问的关系与上限。

    得到什么

    9 张关系 · 5000 行 / 2000000 字节 · 绑定当前会话

  2. 02

    建立语义

    按结构事实整理业务对象与指标,逐条用真实数据核对,不确定的记为待确认。

    得到什么

    业务对象、指标、代码值与术语,各带证据与确认状态

  3. 03

    执行取数

    填写受约束的结构化查询,由端侧编译为参数化语句并在本机执行。

    得到什么

    按责任单位分组的报验总数与合格数

  4. 04

    核对沉淀

    把结果与语义层写下的口径逐项对照,一致后将语义层文件存入资料库待审核。

    得到什么

    语义层文件 · 状态为待审核

每个指标的计算口径,都能对应到具体字段与一次可重跑的查询?

确认后继续是:给出结果,并附口径来源与本次所用查询。
需要调整否:标注为待确认,说明缺少哪一项依据,不代为假设。
四个步骤各自产出可检查的中间结果。任一步骤的结论无法核对时,流程停在该步并说明原因,而不是继续给出一个无法追溯的数字。

过程记录:一次完整运行的六个步骤

下面是一次完整运行的记录,环境为演示数据库,共 9 张表、1303 行示例数据,接入账号仅有查询权限。第一步是接入:填写主机、库名、Schema 与只读账号,先做连接校验,再保存到本地设备。密码与物理连接详情不会离开这台设备。

第二步是结构扫描。扫描完成后可以逐张查看识别出的关系及其字段数、行数估算与占用空间。这一步只读取数据库目录,界面上标注的行数来自统计信息估算,不是逐行统计的结果。

第三步是授权。点击开始问数后,界面给出本轮授权的范围与上限,并说明仅查询、不修改数据;确认后才可发送。第四步是建立语义并取数:按结构事实整理业务对象与指标,用真实数据核对每一条口径,再以结构化查询取回分组结果。

第五步是核对。返回的四个责任单位的报验合格率,与直接对同一张表执行分组聚合得到的结果逐行一致,其中一个班组的合格率低于其余三个。第六步是沉淀:语义层文件写入资料库,状态为待审核,等待业务人员确认后再作为后续问数的复用依据。

第五步的核对结果:语义层写下的口径为“合格数合计 ÷ 报验总数合计”,下表按该口径分组计算,与直接对同一张表执行分组聚合逐行一致。
责任单位报验总数合格数合格率
调试组1,1701,1701,170 ÷ 1,170 = 100.00%
电气组1,2301,2301,230 ÷ 1,230 = 100.00%
结构组1,2001,2001,200 ÷ 1,200 = 100.00%
工艺组1,2601,1941,194 ÷ 1,260 = 94.76%
数据源详情中的数据结构页签,逐张列出识别到的表、字段数量、行数估算与占用空间查看原图
真实产品演示图 · 源宜 0.8.0,装备制造示例数据。左侧为识别出的关系名与类型,右侧依次为行数估算、字段数、分区数与占用空间;行数来自统计信息估算。展示值不代表客户实绩。

后续规划:从语义层走向本体层

当前的语义层解决的是单张关系上的口径一致问题。工业场景的多数问题需要跨表回答——从销售订单追到生产任务,再追到质量检验记录。因此下一步是受控关联:只允许沿已发布的外键与唯一约束连接,关联路径由结构版本决定,而不是由模型临时判断。主键与唯一约束能被完整读到,是这一步的前提。

第二步是命名指标。把合格率、按期完成率这类口径写进语义层并在查询时解析,可以避免每次分析各自重算。第三步是按语义层收窄授权范围:目前一次授权包含全部已扫描关系,按业务对象收窄后,授权范围会更贴近实际问题。

再往后是本体层。语义层描述的是一个数据源内部的对象与口径;本体层需要跨数据源描述同一业务实体,说明同一台设备在生产系统、质量系统和运维系统中的对应关系,以及这些关系随时间的变化。这一步的难点不在查询构造,而在如何让跨系统的实体对应关系被确认、被记录、并在源系统变化时保持有效。

需要说明当前的边界:语义层已经可以在演示环境中完整跑通并复核,但尚未在多个生产环境中长期运行;跨表关联、命名指标与本体层均在规划中。产品能力的推进以可核对的运行记录为准,而不是以功能清单为准。

资料库内容列表中新增的语义层文件,状态标注为待审核,作者为数字员工查看原图
真实产品演示图 · 源宜 0.8.0,装备制造示例数据。语义层以文件形式存入资料库并标注为待审核,业务人员确认后才作为后续问数的复用依据。图中演示环境的数据源名称按保密要求于截图后匿名化,其余界面内容与数值均为实机原貌;展示值不代表客户实绩。

要点回顾

  • 结构事实的读取方式决定语义层的起点。只读账号在 information_schema 中读不到主键与唯一约束,应改从系统目录读取,否则记录粒度只能由模型推断。
  • 把授权、结构版本与取数分成三层。凭据留在本地设备,每轮问数按已发布的结构版本签发限定范围的只读授权,模型填写受约束的结构化查询而不编写 SQL。
  • 语义层的每一条口径都应附带证据与确认状态,并以文件形式存入资料库待审核。人工确认过的条目不被后续运行改写,指标才具备复用价值。
  • 跨表关联、命名指标与本体层仍在规划中。当前可复核的范围是单数据源内的口径一致与一次完整的取数过程。

延伸阅读

想从自己的业务开始?带上一份常用报表和一个最想解决的问题,我们一起看看资料是否够用、第一版应该做到哪一步。

交流您的场景