跳转至

业务术语表

业务术语表是覆盖在你的数据模型之上的一套活的词汇。语义层中的每一个物理列都会解析到一个术语——只要多个列承载同一个概念,无论拼写差别多大,它们都归到同一个共享术语。每个术语可以持有一条定义、一组指向其他术语的带类型关系,以及一份掌握该含义的主题专家名单。

那套共享词汇就是业务语言与物理数据之间的桥梁。一个知道"customer"命名了每一个承载客户标识符的列的 AI 智能体,无需猜测 cust_idcustomerIdCUSTOMER_KEY 中哪一个才对——它们全都解析到同一个术语,而术语带着定义。

术语如何推导

Provisa 使用一条确定性的规范化规则(REQ-1387),自动从每个列名推导出一个术语:大小写折叠、分隔符与 camelCase 分词、缩写展开,以及尾部代理令牌的剥除。

缩写展开把常见的企业简写映射为完整形式:custcustomertxntransactionqtyquantity,依此类推。idkey 都展开为 identifier。该对照表是固定且保守的——像 stminno 这类含义不明的简写保持原样,而不是猜错。

代理令牌剥除会移除尾部的 identifiercodeindexreference 令牌。名为 cust_id 的列并不是在命名标识符本身;它是在通过一个代理值命名一位客户。剥掉代理后,cust_idcustomerId 都落到术语 customer 上。只有尾部令牌会被剥除,并且绝不剥掉最后剩下的那个令牌:一个光秃秃的 id 列展开为 identifier 并就此打住。

去重才是关键。规范化规则是确定性的,因此 cust_idcustomerIdCUSTOMER_KEY 全都产出 customer。每个列在唯一得出的那个术语上获得一条 ref,而不是产生三个各自独立的术语。这样一来,人工整理只需在一个地方补上定义,而不是三个。

通用短语

有些规范化后的短语过于通用,本身构不成一个概念。一个光秃秃的 namedateidentifier 列命名的是其所在表那个概念的一项属性,而不是独立于该表的概念。员工有名字;产品也有名字;它们不是一回事。

当某个短语落入通用集合且存在可用的表上下文时,术语会被限定为 <表概念> <短语>employees.first_name 规范化为 employee first name,而 orders.id 规范化为 order,因为随后的代理剥除把被限定的短语坍缩到它所标识的那个概念上。最后这种情形很重要:orders 的主键以及其他表上的每一个外键 order_id 全都落到 order 上,无需任何额外的人工整理。

通用集合涵盖属性名词(namedatestatustypeamountquantity)、审计轨迹短语(created_atmodified_bysubmitted_timestamp),以及另外几个几乎出现在每张表上的短语。

业务名称,而非物理名称

推导出的术语沿用列的业务名称——建模者设置了别名时用别名,没设置时用物理名称(REQ-1581)。当 usr_nm 被取别名为 user name 时,推导出的术语就是 user name,而不是 user number 或对 usr_nm 的某种展开。

给列取别名是更有力的更正。别名会传到读取该列的每一个界面——SQL、GraphQL、AI 智能体、目录——因此模型在各处都能正确地自我描述。而重命名术语只修好一条目录条目,把仍写着 usr_nm 的列留给下一个读者。UI 中的提议术语横幅直接这么说:先给列取别名;只有当列名没问题、有问题的是词汇时,才重命名术语。

给列重新取别名会重新推导它的提议术语,因此术语表跟着模型走,而不是要求你把同一处更正做两遍。一旦整理者为某个术语补上了定义、关系或专家,别名的改动就不会再移动那条 ref——那份工作属于整理者,会被保留。

访问路径式的表名

有些表名描述的是一条访问路径而非一个概念:user_by_name 是通过名称查找到达的用户,而不是另一种实体。当 Provisa 为通用短语的限定推导表概念时,会在连接词处切断表名(REQ-1582)。user_by_name 变成 userorders_by_customer 变成 order

不做这个切断的话,user_by_name 上的代理键会规范化为 user name,并与真正的 users.name 属性相撞——一个术语同时装着一个事物和它自己的一个字段。该切断只作用于表概念。在列名中,by 是复合名词的一部分:pet_by_namepet_name 规范化到同一个术语 pet name

什么样的术语算已整理

由列名规范化而生的术语一开始是空白的——是一项提议,还算不上词汇。只要满足以下任意一条,它就成为已整理:

  • 已保存一条定义。
  • 已添加一条关系边。
  • 已指派一位主题专家。
  • 整理者已手动将其停用。

整理与否关系到术语的生命周期。当一个已整理术语的最后一个物理列从模型中移除时,该术语会被弃用而不是删除:它退出服务,保留编辑者提供的内容,并在同一个列重新出现时自动复活。未整理且不再有列的术语则直接被移除。

从表重新同步

每当一张表被保存或重新加载,sync_table_refs 都会把该表的列与既有的 ref 对账。新列会创建或链接术语;离开的列会撤下其 ref;而移除或弃用规则会为任何失去最后一条 ref 的术语作出裁定。

重新推导只针对未整理的术语。如果你给某个列取了别名、提议术语因而改变,ref 就会移到新术语上。如果该术语已整理,链接保持不动——别名的改动没有推翻整理者对术语的选择。

一个抽象术语,若它通往物理数据的唯一路径要穿过某个正在离开的术语,则它会被弃用而非移除,从而在重新接线之前保住概念结构。

关系

术语通过带类型的边与其他术语建立关系。受支持的关系类型有:

类型 含义
KIND_OF 源术语是目标术语的一种。
PART_OF 源术语是目标术语的一个组成部分。
SYNONYM_OF 这两个术语在本领域中可以互换。
RELATED_TO 一种松散的关联——没有更强的说法适用。
VALID_VALUE_OF 源是目标枚举或域的一个允许值。
DERIVED_FROM 源是由目标计算或取得的。
REPLACES 源取代了已弃用的目标。
PREFERRED_TERM_FOR 相对于不推荐的目标,源是首选术语。
TRANSLATION_OF 源是目标的某个区域或语言的译法。
ANTONYM_OF 源在语义上与目标相反。

关系是有方向的。UI 会同时展示出边(本术语 → 另一术语)和入边(另一术语 → 本术语),并为每个方向标注各自的白话短语。

这些边存放在 glossary_term_edges 中,这是一张声明为联结(junction)关系的关联表(REQ-1586):它的 rel_type 列是判别列,因此上表中的每种类型都是两个 GlossaryTerm 节点之间独立的 Cypher 关系类型,而不是具体化节点上的一个属性。该表随元数据模式的其余部分一并置备,在图客户端中不显示为节点——它就是边。它没有任何专属于业务术语表的地方:它的声明方式与你在自己的表上声明联结完全相同,并且由同一套代码读取。 [tool-verified: provisa/cypher/label_map.py:378-397, provisa/api/startup_seed.py:508-550]

抽象术语

抽象术语自身没有物理列 ref。当一个业务概念横跨多个具体术语时,就用一个抽象术语——一把伞,你随后把它接到那些确实持有列的具体术语上。举例来说,revenue 可以是抽象的,由 order amountadjustment amountrefund amount 发出的 PART_OF 边指向它。

一个通过关系图无法到达任何物理列的抽象术语,是一项悬空的提议。它不会出现在智能体的术语搜索中,也不会出现在元数据导出里——一个没有命名任何数据的术语回答不了任何问题。

面向消费界面的准入规则

消费界面可以提供的术语必须满足三个条件(REQ-1387):

  1. 在役——未被停用(整理者将其撤出服务)且未被弃用(它失去了最后一个列,只是因为删掉它会留下悬空的东西才被保留)。
  2. 有定义——它带着一条定义。由列名推导出的术语是一个令牌,而不是一层含义。没有定义,它就是一项等待整理者的提议,绝不是智能体可以据以立论的词汇。
  3. 落地——经由在役术语,连通到至少一个持有物理列 ref 的术语。术语表是进入数据的入口,因此每条链条都必须终结于某个列。

连通性会在图中传播:抽象术语通过任何一个已到达数据的在役邻居到达数据。退役的术语不导通——一个已停用的术语不会让依赖它的术语继续存活。

元数据导出

作为元数据导出的一部分,术语表会发布到外部数据目录。同一条准入规则适用,只是收窄了一处:术语是否落地,仅对照那些确实会发布的列来判定。若某个术语的列全部被排除在导出之外——因为它们所在的表未被标记为数据产品,或因为技术性过滤器将其排除——那么就导出而言它不算落地,即便它在控制平面中持有 ref。

关系边只在两个端点术语都发布时才发布。

列资产是独立导出的。某个术语被排除,并不会隐藏其底层数据。

把术语排除在导出之外

有些列承载的是管道设施而非业务数据:ETL 批次标识符、行版本、摄取时间戳。由这类列推导出的术语可能有一条完全准确、却根本算不上业务词汇的定义(REQ-1583)。从元数据导出中排除这一控件会把该术语,以及任何以它为终点的关系边,从 Provisa 发布的目标目录中扣下,而列本身仍会作为资产导出。

判据是业务是否说这个词,而不是定义好不好。ETL 批次标识符有明确的含义,属于给工程师看的术语表;它不属于业务目录里 customerrevenue 的旁边。

使用术语表

在 UI 中打开管理 → 术语表。左侧面板列出每一个术语;点击其中一个即可打开它的详情视图。从那里你可以:

  • 重命名术语,在不移动其列的前提下改变措辞。
  • 添加定义,可以自己敲一条,也可以点击 AI 起草按钮,依据术语的名称、它的物理列及其关系生成一个起点。草稿在你确认之前不会保存。
  • 移动 ref以合并两个术语:在任一物理 ref 旁的下拉菜单中挑选目标术语。若源术语因此失去最后一条 ref,会自动按移除或弃用规则作出裁定。
  • 添加关系,在本术语与另一术语之间建立关系,类型从封闭集合中选取。对既有的边应就地改类型,而不是删掉再加一遍。
  • 指派专家,按用户 ID 指派,种类为 expertauthor
  • 停用术语,使其退出服务。它保留自己的列,在这里仍可编辑,但智能体的术语搜索和元数据导出都会跳过它。若该概念日后回归,可以再恢复它。
  • 批量生成定义,一次性填满所有空白定义。只写入空的定义;人写的文字绝不会被覆盖。
  • 批量生成关系,在完整术语列表上提议带类型的边。格式不合规的提议——未知的术语名、自环边、无法识别的类型——会被自动丢弃。

没有定义的术语上的提议横幅会告诉你,该术语是未定义(去给列取别名或补一条定义)还是未落地(把它关联到一个有列的术语)。当你看到它时,该术语尚不能被智能体或目录触达。

另请参阅

  • 元数据导出 —— 术语和关系如何发布到外部数据目录,包括导出准入规则会放行哪些术语。
  • 列级血缘 —— 血缘浏览器,以及 columnDependents 如何把术语表绑定作为物理列的依赖方报告出来。