跳转至

业务术语表

业务术语表是建立在数据模型之上的一套活的词汇。模型中的每个物理列都对应一个术语,承载同一概念的列共享一个术语,无论它们写法有多不同。每个术语都可以有定义、一组指向其他术语的类型化关系,以及一份负责其含义的领域专家名单。

术语表是一种本体:由概念、概念的定义以及概念之间的关系组成的图。Provisa 把它映射到存放数值的数据库结构上,因此能够回答关于你数据的问题。一个概念在触达数据之前(直接触达或经由其他概念)只是草稿。术语表与指标相互独立:术语说明概念是什么,指标说明数字如何计算。

这套共享词汇把业务语言和物理数据连了起来。知道“customer”指代每个带客户标识符的列的 AI 代理,不必猜测 cust_id、customerId 和 CUSTOMER_KEY 中哪个才对。它们都对应同一个术语,而定义就在这个术语上。

术语如何推导

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

缩写展开把企业常用简写映射为完整形式:cust → customer、txn → transaction、qty → quantity 等。id 和 key 都展开为 identifier。这张表是固定且保守的:st、min、no 这类有歧义的简写保持原样,以免猜错。

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

关键在于去重。规范化规则是确定性的,所以 cust_id、customerId 和 CUSTOMER_KEY 都会得到 customer。每一列都引用这同一个术语,整理时只需在一处添加定义,而不是三处。

通用短语

有些规范化短语太泛,无法单独成为一个概念。单独的 name、date 或 identifier 列指的是其所在表概念的一个属性,离开那张表就不存在。员工有名字,产品也有名字,但两者不是一回事。

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

通用集合涵盖属性名词(name、date、status、type、amount、quantity)、审计轨迹短语(created_at、modified_by、submitted_timestamp),以及另外几个几乎出现在每张表上的短语。

业务名称,而非物理名称

派生术语遵循列的业务名称:建模者设置了别名就用别名,否则用物理名称。当 usr_nm 的别名是 user name 时,派生术语就是 user name,而直接展开 usr_nm 可能会得到 user number。

给列设置别名是更彻底的修正。别名会传到每个读取该列的入口(SQL、GraphQL、AI 代理、目录),让模型在各处都正确描述自己。重命名术语只修正一条目录条目,下一个读者看到的列名仍是 usr_nm。界面中的建议术语横幅也这么说:先给列设置别名,只有在列名正确而词汇不对时才重命名术语。

重新设置列的别名会重新推导其建议术语,所以术语表始终跟随模型,从不要求同样的修正做两次。一旦管理员给某个术语添加了定义、关系或专家,修改别名就不会移动引用,因为这些工作属于管理员,会保留下来。

访问路径式的表名

有些表名描述的是访问路径而不是概念:user_by_name 是通过按名称查找得到的用户,并不是另一种实体。当 Provisa 为限定泛化短语而推导表概念时,会在连接词处截断名称,所以 user_by_name 变成 user,orders_by_customer 变成 order。

如果不截断,user_by_name 上的代理键会规范化为 user name,与真正的 users.name 属性冲突,导致一个术语同时指代一个事物及其自身的一个字段。截断只作用于表概念。在列名中,by 是复合名词的一部分,所以 pet_by_name 和 pet_name 会规范化为同一个术语 pet name。

什么样的术语算已整理

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

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

整理状态影响术语的生命周期。当已整理术语的最后一个物理列离开模型时,该术语会被弃用并保留:它停止服务,保留编辑者提供的内容,如果同一列重新出现会自动恢复。没有剩余列的未整理术语则直接删除。

从表重新同步

每当一张表被保存或重新加载,sync_table_refs 都会把该表的列与既有的 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)关系的关联表:它的 rel_type 列是判别列,因此上表中的每种类型都是两个 GlossaryTerm 节点之间独立的 Cypher 关系类型,而不是具体化节点上的一个属性。该表随元数据模式的其余部分一并置备,在图客户端中不显示为节点:它就是边。它没有任何专属于业务术语表的地方:它的声明方式与你在自己的表上声明联结完全相同,并且由同一套代码读取。

抽象术语

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

无法通过关系图连到任何物理列的抽象术语,是一个悬空的提议。它不会出现在代理的术语搜索中,也不会出现在元数据导出中,因为不指向任何数据的术语回答不了任何问题。

面向消费界面的准入规则

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

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

连通性会沿着图传播:抽象术语可以通过任何能连到数据、且仍在服务中的相邻术语连到数据。停止服务的术语不传导,所以已退役的术语不会让依赖它的术语继续存活。

元数据导出

术语表会作为元数据导出的一部分发布到外部数据目录。适用同样的准入规则,只收紧一点:判断术语是否有根,只看真正会发布的列。如果一个术语的所有列都被排除在导出之外(因为它们的表没有标记为数据产品,或被技术过滤器排除),那么即使它在控制平面中有引用,就导出而言也不算有根。

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

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

把术语排除在导出之外

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

关键在于业务是否使用这个词,定义写得好不好并不决定这一点。ETL 批次标识符的含义很清楚,应该放在面向工程师的术语表里,但不该出现在业务目录中,与 customer 和 revenue 并列。

使用术语表

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

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

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

另请参阅

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