第16部分。Customer 360 数据集市
mart_customer_360 是第一个最终数据集市。它汇集了客户属性、账户余额和卡片活动。这是一个主要的学习示例:从中可以看到产品规格、ODCS、模型规范、dbt 测试和验证事实应该如何协同工作。
验收事实
- 每个
customer_id一行; customer_id不为空且唯一;- 无直接 PII;
total_balance_rub不为空;risk_event_count_7d不为空;- 合约必备字段均存在;
- 通过
ref()读取血缘关系。
实现
请打开:
models/marts/mart_customer_360.sql
models/schema.yml
specs/models/mart_customer_360.md
specs/validation/customer_360.md
检查 SQL 是否遵循规范,且测试是否覆盖关键事实。不要仅限于阅读 SQL:PII 泄露和合约漂移必须有单独的检查。
验收矩阵
| 事实 | 证据 |
|---|---|
每个 customer_id 一行 | dbt 测试 unique |
customer_id 不为空 | dbt 测试 not_null |
| 无直接 PII | schema singular 测试 |
| 总余额存在 | dbt 测试 not_null |
| 风险计数器存在 | dbt 测试 not_null |
| 合约字段存在 | 合约列 singular 测试 |
如果证据行为空,这不是已就绪,而是存在空白。
Qwen 查询
比较 models/marts/mart_customer_360.sql、models/schema.yml、specs/customer_360_contract.odcs.yaml 和 specs/validation/customer_360.md。说明哪些验收事实已被覆盖,哪些是手动的,哪些缺失。不要修改文件。
最小输出
请准备审阅者备注:
粒度:每个 `customer_id` 一行。
PII:无直接 PII。
合约字段:`customer_id`、`total_balance_rub`、`risk_event_count_7d`。
检查:`dbt build`、mart 测试、禁止的 PII 列表、合约列。
待解决问题:`risk_event_count_7d` 的定义依赖于输入的风险标志。
为读者解读
Customer 360 是一个很好的第一个 mart,因为它的名称很熟悉,因此也很危险。几乎每个项目参与者都认为自己理解它的含义,但对不同的人来说,这是不同的表。对于分析师来说,它可以是客户切片。对于营销来说,是带分群的档案。对于风险来说,是行为聚合。对于运营团队来说,是一组标识符。SDD 强制要求在编写 SQL 之前选择一个版本的承诺并将其记录下来。
在本书中,Customer 360 是有意受限的。每个客户一行。不公开直接 PII。余额根据账户计算。风险事件取自合成活动窗口。这样的限制看似贫乏,但使示例变得诚实:每个字段都可以与规范和检查相关联。如果一次性添加所有内容,学生将看到一张大表,但看不到产品纪律。
需要特别关注 risk_event_count_7d。其名称本身就承诺了一个七天窗口。如果 SQL 只是简单计算所有风险事件,该字段看起来似乎合理,但会误导使用者。因此窗口必须被单独描述和单独测试。这是一个大思想的小例子:字段名称成为合约的一部分。如果名称包含期限、币种、状态或聚合级别,则检查必须确认这一点。
Customer 360 还展示了为什么 PII 政策不能只停留在笼统的措辞上。在 raw 和 staging 中可以有 pii_email,以便学生看到风险。在 mart 中不应出现该字段。这不是模式美学的问题,而是产品边界。审阅者不仅应查看最终的 select,还应查看证明不存在直接 PII 字段的测试。
练习
仅运行 Customer 360 的检查,并将输出的每一行与验收矩阵进行对照。如果事实仅通过人工审阅确认,也请如实记录。
典型错误
仅凭肉眼检查 SQL。在 SDD 中需要证据:dbt 测试、模式审阅、明确的验证事实或审阅者报告。
思考题
- 为什么
pii_email不应进入 mart? - 哪些字段使数据集市处于客户级别?
- 如果按产品添加明细,会发生什么变化?