学习指南: 第19部分. 语义层、指标和exposures

模块「第19部分. 语义层、指标和exposures」中第 3 / 5 节课
您正在未登录状态下查看课程。 请登录,以保存进度并参加测试。

主题: 第 19 部分 语义层、指标与 exposures

难度等级: 中级

预计学习时间: 3-4 小时

前置要求: 理解数据集市(data marts)的架构

具备 dbt 或类似转换工具的使用经验

了解数据质量(Data Quality)原则和校验事实

具备使用 YAML 和 Markdown 进行文档编写的基础知识

具有 BI 工具和报表相关的工作经验

学习目标: 区分作为列的指标与作为语义契约的指标(后者包含公式、粒度、负责人和使用方)

判断团队真正需要语义层的时机,并将其与官僚式数据治理层区分开来

在 Markdown 中创建语义注册表,用于记录公共指标

使用 exposures 来记录数据产品的使用方,并管理破坏性变更

应用 Qwen 提示词来查找和校验数据集中的公共指标

概述: 课程第 19 部分聚焦于语义层、指标和 exposures —— 这些概念在同一个指标开始被多个报表、应用或团队使用时变得至关重要。在出现重复消费之前,清晰的数据集市和校验事实就足够了。但当 total_balance_rub、active_consent 或 risk_event_count 这样的字段开始在不同上下文中重复出现时,就有必要将它们的定义集中化。指标不仅仅是列,而是一份完整的契约:名称、公式、粒度、过滤器、时效、负责人和使用方列表。dbt 支持 semantic models 和 metrics,但在教学环节中,更重要的是在增加技术层之前先固定语义意图。Exposures 补充了这一图景,展示谁真正在读取数据产品 —— 仪表板、API、notebook 还是报表 —— 这对于管理契约漂移和破坏性变更至关重要。

关键概念: 语义层:集中化的指标定义层,用于消除团队之间的歧义。只有当同一指标开始在多个上下文中被使用时才引入;并非目的本身,而是防止定义漂移的工具。

指标作为契约:指标不是简单重命名的列,而是一份完整的语义契约,包含:名称、计算公式、粒度(grain)、应用的过滤器、期望的数据时效、定义的负责人以及使用方列表。

粒度(grain):指标的细节层级:按行、按客户、按 scope、按产品、按天等。没有明确的粒度,就无法保证不同报表对指标的解释一致。

dbt semantic models:dbt 内置的通过 YAML 配置描述指标的机制。包括 entities、measures、dimensions。用于成熟的数仓栈,但需要预先对齐指标的语义。

Exposure:数据产品(数据集市)与其使用方(仪表板、API、notebook、定期报表)之间文档化的关联关系。可以让你看到模式或 grain 的变更会影响哪些下游。

语义注册表:Markdown 文档或 YAML 文件,用于以以下形式记录公共指标的定义:名称、定义、粒度、负责人、使用方、校验事实。是完整语义层的最小可行替代方案。

契约漂移:同一指标名称在不同团队中具有不同定义或公式的情况。例如,一个团队按 revoked_at 为 null 来统计 active_consent,另一个团队按日期排除旧的 consent —— 这是同名但实际不同的两个指标。

指标的校验事实:用于校验指标计算正确性的具体 assertion 或测试。例如,所有 positive 值的总和应与来源聚合一致。

破坏性变更(breaking change):对数据集市或指标的更改,会影响下游使用方:字段重命名、grain 变更、公式变更。Exposures 有助于提前发现这些受影响的使用方。

指标的 Qwen 提示词:向 LLM 发出的标准化请求,它读取数据集市和 specs,找出看起来像公共指标的字段,并为它们提议定义、grain、负责人、使用方和校验事实 —— 而不会自动创建 semantic models。

重要日期: 阶段 1:复用之前:数据集市和校验事实就足够了。指标定义可以放在数据集市旁边。

阶段 2:出现第二个使用方:是时候考虑语义注册表了。如果定义没有被明确记录,使用方之间就会产生分歧。

阶段 3:多个团队共用同一个指标:缺失语义层会造成漂移,而拥有语义层是建立数据信任的必要条件。

练习题: 名称: 为 active_consent_count 填写语义注册表

问题: 数据集市 mart_open_api_consents 中有一个反映 active consent 的字段。请填写语义注册表:给出定义、粒度、负责人、使用方和校验事实。如果负责人或使用方未知,则不要添加 semantic model。

解决方案: 1. 打开数据集市 mart_open_api_consents 的 spec,找到该字段的描述。2. 给出定义:'满足 revoked_at is null 的 consent 数量'。3. 确定 grain:在 scope(例如 consent 类型)级别。4. 询问 Open API 产品的负责人,谁负责该定义。5. 询问 Open API 监控团队,他们是否是使用方。6. 给出校验事实:'在某周期内 active_consent_count 的总和等于来源中 revoked_at is null 的行数'。7. 如果步骤 4-5 中的任何一步无法确认,就停下来并澄清产品承诺。

难度: intermediate

名称: 识别指标 total_balance_rub 的漂移

问题: 两个报表使用 total_balance_rub 字段,但给出的总数不同。请确定漂移发生在哪一步,并提出如何通过语义注册表解决它。

解决方案: 1. 比较两个报表对数据集市的 SQL 查询。2. 找出差异:例如,一个按 client_status='active' 过滤,另一个包含已关闭账户。3. 明确 total_balance_rub 是一个列名而不是指标。4. 在注册表中创建两个独立条目:'total_balance_rub_active'(仅活跃客户)和 'total_balance_rub_all'(所有客户),并标注明确的 grain 和定义。5. 与各团队协商采用新名称。6. 记录校验事实:在相同过滤条件下,新指标的合计应与来源中的聚合一致。

难度: intermediate

名称: 应用 Qwen 提示词查找公共指标

问题: 使用 Qwen 请求模板分析项目的三个数据集市,找出可能成为公共指标的字段。不要创建 semantic models —— 只给出候选。

解决方案: 1. 构造请求:'阅读数据集市和 specs。找出看起来像公共指标的字段。对每个字段给出定义、grain、负责人、使用方和校验事实。在没有确认前不要创建 semantic models。' 2. 将三个数据集市的描述(例如 mart_clients、mart_accounts、mart_transactions)传给请求。3. 获取候选列表:total_balance_rub、active_client_count、transaction_volume、avg_transaction_amount。4. 对每个候选进行检查:该字段是否出现在多个数据集市或报表中?若是 —— 则为指标候选。5. 将结果写入注册表草稿,将每条记录标记为 '待负责人确认' 状态。

难度: intermediate

名称: 决策:是否引入语义层

问题: 一个由 3 名分析师组成的团队使用 5 个数据集市。每个数据集市仅被一个报表使用。是否应该引入完整的 dbt 语义层?请给出理由。

解决方案: 1. 检查是否存在公共指标:取出所有 5 个数据集市的字段列表,与所有报表的字段列表进行比对。2. 如果没有公共指标(每个数据集市只为一个报表服务),那么语义层将成为官僚流程。3. 建议:将定义保留在数据集市旁边,以 dbt 的 doc 块或 spec 中的注释形式呈现。4. 明确触发条件:一旦任何指标出现第二个使用方 —— 立即在语义注册表中创建记录。5. 当使用方数量超过 3-4 个团队时,重新评估该决定。

难度: beginner

案例研究: 名称: 金融科技初创公司中 '活跃客户' 指标的漂移

场景: 一家拥有 4 个分析师团队的金融科技初创公司。风险团队按 '过去 90 天内至少完成一笔交易' 来定义活跃客户。市场团队按 '未销户且过去 30 天内登录过 App' 来定义。两支团队都将该指标命名为 active_client_count 并发布到仪表板。管理层看到报表之间存在 18% 的差异,因此对数据失去信任。

挑战: 同一指标缺少统一的语义契约。不同团队应用不同的过滤器、grain 和公式,但使用同一名称。问题无法在 BI 工具中解决,因为它发生在定义层面而非可视化层面。

解决方案: 1. Data Lead 进行审计:收集所有团队对 active_client_count 的定义。2. 在语义注册表中记录三个独立指标:active_client_90d(基于交易)、active_client_30d(基于登录)、active_client_strict(两个条件都满足)。3. 为每个指标指定负责人:风险、市场、产品。4. 在 dbt 中添加 exposures:风险仪表板 → active_client_90d,市场仪表板 → active_client_30d。5. 为每个指标记录校验事实:在相同过滤条件下,按 grain 的合计与来源的聚合一致。6. 没有引入完整的 dbt semantic layer —— 限于 Markdown 注册表,因为公共指标当时还不到 10 个。

结果: 6 周后漂移被消除:各团队的报表变得一致,管理层对每个指标的含义获得了统一理解。风险团队和市场团队开始通过负责人协商指标变更,而不是在群里争论。数据信任得以恢复。4 个月后,当公共指标数量增长到 12 个时,团队决定迁移到 dbt semantic models —— 但这正是因为出现了真实的使用方和可复用的定义。

经验教训: 语义层的引入不是为了栈的完整性,而是当一个指标存在多个使用方时才有必要

漂移不是发生在 BI 中,而是发生在定义层面缺少显式契约

Exposures 是一种方法,用来查看哪些人会受到指标变更的影响并提前预警

首先固定意图(Markdown 注册表),然后再选择工具(dbt semantic layer)

相关概念: 语义注册表

契约漂移

Exposure

粒度

指标的校验事实

名称: 某银行从 ad-hoc 数据集市过渡到语义层

场景: 一家中型银行,拥有 15 个分析团队,dbt 中有 40+ 个数据集市。指标 risk_event_count 被用于 8 个报表:监管报表、反欺诈、操作风险、评分。定义各异:部分团队按 events 表统计,部分按 alerts 表统计,部分包含人工复核,部分仅包含自动触发。

挑战: 监管机构要求提交关于 risk_event_count 的报表,银行无法快速给出统一的数字:不同团队的数值相差 40%。声誉和监管期限都面临风险。引入完整的 dbt semantic layer 看起来过度,但缺少契约造成了操作风险。

解决方案: 1. 成立工作组:Data Steward + 4 个消费团队的负责人。2. 召开一系列会议对齐 risk_event_count 的定义:来源(events)、过滤器(event_type in scope)、grain(client_id, date)、公式(count distinct)。3. 在语义注册表中记录:定义、grain、负责人(操作风险团队)、通过 exposures 记录 8 个使用方、校验事实(按 grain 在某周期内的合计等于 source.events 中的聚合)。4. 推行实践:任何对 risk_event_count 的变更都必须与负责人协商,并向所有 exposure 使用方发送通知。5. 仅在 3 个月后,当此类 '公共' 指标达到 7 个时,银行才开始针对它们试点 dbt semantic models,其余仍保留在 Markdown 注册表中。

结果: 监管报表按时提交,并给出统一的数字。银行避免了罚款。半年后,'语义' 指标数量增长到 15 个,银行标准化了方法:每个公共指标先出现在注册表中,只有当使用方达到 3 个以上时才迁移到 dbt semantic layer。破坏性变更现在会自动通知所有 exposure 使用方。

经验教训: 语义层的关键不在技术(dbt vs Markdown),而在于团队之间语义的对齐

Exposures 提供了查看变更影响半径(blast radius)并降低操作风险的能力

完整的 dbt semantic layer 只有在出现真实公共指标后才值得引入,否则就是官僚主义

指标的负责人不是计算出它的分析师,而是对定义负责的产品利益相关方

相关概念: Exposure

破坏性变更

dbt semantic models

指标负责人

语义注册表

学习建议: 从一个检查开始:拿出你项目的 2-3 个数据集市,找出出现在多个报表中的字段 —— 它们是公共指标的候选

不要急于引入 dbt semantic layer:先在 Markdown 注册表中固定意图,只有在使用方达到 3 个以上时才考虑自动化

对每个指标提出 5 个问题:名称、公式、grain、负责人、使用方 —— 只要有一个问题没有答案,该指标就没有准备好

将 Qwen 提示词作为注册表草稿的助手,但不要让它自动创建 semantic models —— 始终确认负责人

把 exposures 视为依赖关系地图:每个 exposure 都是一项在破坏性变更前预警使用方的承诺

区分 '指标' 与 '列':列是物理字段,指标是关于其解释的契约

漂移的迹象:一个团队说 '指标上升了',另一个说 '下降了',但数据是相同的 —— 这意味着定义已经分叉

不要将语义层与名称目录混淆:指标注册表关注的是含义和公式,而非列重命名

附加资源: Dbt semantic layer(官方文档):https://docs.getdbt.com/docs/build/dimensions —— 关于 dbt 中 entities、dimensions、measures 的官方指南

Dbt metrics(已废弃,但对理解演进有帮助):https://docs.getdbt.com/docs/build/metrics —— dbt 中 semantic layer 的历史背景

《fundamentals of data engineering》(O'Reilly):Joe Reis 与 Matt Housley —— 关于现代栈中语义层与指标的章节

文章 'what is a semantic layer?'(Towards Data Science):用真实公司案例对概念进行实践性解释

Cube.dev —— 另一种语义层方案:https://cube.dev/docs —— 与 dbt semantic layer 不同的思路

dbt labs 博客:'the rise of the semantic layer':https://blog.getdbt.com —— dbt 团队关于该方法演进的系列文章

课程资料:第 18 部分(数据集市与校验事实):课程的前一部分,是理解语义层上下文所必需的

摘要: 课程第 19 部分引入语义层、指标和 exposures 的概念,作为数据复用时定义漂移的应对方案。核心思想:指标不是列,而是带有公式、粒度、负责人和使用方的语义契约。只有在公共指标存在多个使用方时引入语义层才有意义,否则它会变成官僚流程。在教学项目中,Markdown 注册表足以固定意图,之后再考虑迁移到 dbt semantic models。Exposures 显示谁在读取数据产品,并通过通知使用方帮助管理破坏性变更。最重要的实践结论:先记录定义、grain、负责人、使用方和校验事实 —— 然后再决定是否需要正式的语义层。

我的笔记
0 / 10000

笔记保存在当前浏览器中。在其他设备上将不会显示。

课程菜单

课程

SDD Data. 使用 Qwen Code 和 dbt 构建银行数据平台
进度 0 / 110