文章
大数据建模体系补充
建模层级依赖问题:
有没有可能 dwd -> dwt -> dws -> 然后需要在dwt上按照企业状态绘制某个区域或者省份的画像,那么整体流程就变成了dwd -> dwt -> dws -> dwt -> ads。可能原因就是每个属性都可以再衍生出不同维度的新的指标,就导致了当前表,成了下游的依赖表。
当一个属性(如企业状态)既是画像特征,又能作为聚合维度时,是否会导致 DWT → DWS → DWT 的循环依赖?
🔍 一、问题本质:特征 vs 维度的双重身份
你描述的场景是典型的:
- DWT 中定义了
is_claimed
(是否被领取) → 画像特征 - 业务需要 “各省已领取企业数量” → 这是一个 按画像特征分组的聚合指标
- 于是你可能:
- 先在 DWT 打标
is_claimed
- 再在 DWS 聚合
COUNT BY province, is_claimed
- 然后又想在 DWT 中加入“所在省份的领取率”(如:该企业所在省有 1000 家企业,800 家已领取 → 领取率 80%)
- 先在 DWT 打标
这就形成了:
DWD → DWT(打标) → DWS(聚合) → DWT(加群体特征) → ADS
看起来像是 DWT 依赖了 DWS,又反过来被 DWS 依赖,容易引发循环依赖或逻辑混乱。
✅ 二、正确解法:区分“个体特征”与“群体特征”
🧩 原则:
WT 只应包含两类特征:
- 个体静态/行为特征(来自 DWD):如
is_claimed
,patent_count > 5
- 明确标注的群体衍生特征(来自 DWS):如
province_claim_rate
,industry_avg_score
但必须避免隐式循环,且要显式声明依赖关系。
🛠 三、推荐架构设计(解决你的场景)
场景:销售想看“某省高潜客户中,已被领取的比例”
步骤分解:
- DWD
- 提供企业明细:
company_id, province_code, is_high_potential
(来自清洗)
- 提供企业明细:
- DWT(个体画像)
-- dwt_company_profile_v1
SELECT
company_id,
province_code,
is_claimed, -- 个体状态
is_high_potential -- 个体标签
FROM dwd_company_base_full;
3.DWS(轻度聚合)
-- dws_province_claim_summary
SELECT
province_code,
COUNT(*) AS total_companies,
SUM(is_claimed) AS claimed_companies,
SUM(is_claimed) / COUNT(*) AS province_claim_rate
FROM dwt_company_profile_v1
WHERE is_high_potential = 1
GROUP BY province_code;
4.DWT(增强画像,含群体特征) ← 关键!这是新表,不是原表更新
-- dwt_company_profile_v2 (或 dwt_company_profile_enhanced)
SELECT
p.*,
s.province_claim_rate -- 来自 DWS 的群体特征
FROM dwt_company_profile_v1 p
LEFT JOIN dws_province_claim_summary s
ON p.province_code = s.province_code;
5.ADS
SELECT
company_name,
province_name,
is_claimed_desc,
province_claim_rate -- 用于“该企业所在省整体领取情况”对比
FROM dwd_company_base_full dwd
JOIN dwt_company_profile_v2 dwt ON ...
✅ 四、关键设计原则(写入你的《建模体系》)
原则 | 说明 |
---|---|
DWT 可依赖 DWS,但必须是单向、显式、版本化 | 如dwt_v2 ← dws ← dwt_v1 ,避免原地更新 |
禁止 DWS 依赖“含群体特征的 DWT” | 防止循环:DWS 聚合必须基于基础 DWT(v1) |
群体特征需明确命名 | 如province_xxx_rate ,industry_xxx_rank ,避免混淆个体/群体 |
用“版本”或“后缀”区分画像层级 | dwt_company_profile (基础) vsdwt_company_profile_enhanced (含群体) |
💡 口诀补充:
“个体打标走 DWT,群体聚合归 DWS;
若需特征再增强,新表承接不循环。
🚫 五、什么情况下要警惕?
- 如果发现 DWS 聚合时用了
dwt_enhanced
,而dwt_enhanced
又依赖该 DWS → 循环! - 如果频繁在 DWT 中加入“XX 省平均值”“XX 行业排名”,但未拆分基础/增强层 → 职责混乱
✅ 六、结论
你的直觉是对的:属性可以衍生新指标,导致依赖链变长。
但这不是分层失效,而是需要更精细的分层策略:
- 允许 DWT → DWS → DWT_enhanced,但必须:
- 显式拆分为不同表(或逻辑版本)
- 保证依赖链为 DAG(有向无环)
- 在文档中标注“此 DWT 依赖 DWS,用于群体特征”
这样既能支持复杂业务需求,又不破坏“上游稳定、下游灵活”的核心原则。
建议在《大数据数仓建模体系》的 DWT 层说明 中增加一段:
“DWT 可引入来自 DWS 的群体特征,但应通过新表(如 _enhanced
后缀)实现,避免与基础画像混用,确保依赖链清晰无环。
这样,你的体系就既能应对简单场景,也能支撑高级特征工程。
问题:建模都是基于当前需求,后期新增的需求可能就会出现用当前dwt中的指标做聚合出指标
这确实是数仓建模中一个根本性挑战,也是很多团队在演进过程中遇到“架构僵化”或“依赖混乱”的核心原因。
我们可以把这个根因拆解为两个层面:
🔍 一、根因本质:建模的“静态性” vs 需求的“动态演进性”
- 建模时:我们基于当前已知需求,设计 DWD → DWS/DWT → ADS 的清晰链路;
- 上线后:业务不断提出新问题,例如:
- “能不能看各省高潜客户的平均专利数?”
- “已领取客户中,有多少是 A 类客户?”
- “每个销售负责的企业里,未触达比例是多少?”
这些新需求往往需要:
把之前 DWT 中定义的“个体标签”(如 is_high_potential)当作聚合维度,再产出新的“群体指标”。
这就导致:
- 原本只用于“打标”的 DWT 字段,变成了 DWS 聚合的输入;
- 而新聚合结果又可能反哺回 DWT(如“所在区域高潜密度”),形成 DWT → DWS → DWT_enhanced 的链路。
✅ 二、这不是错误,而是数仓成熟度提升的自然过程
关键不在于“是否允许”,而在于如何规范地支持这种演进,避免陷入混乱。
✅ 正确应对策略(建议写入你的《建模体系》):
原则:允许衍生,但必须分层、版本化、显式依赖
用 DWT 的标签做聚合 | ✅ 在 DWS 中基于基础 DWT(v1)聚合 | ❌ 在 DWS 中直接 JOIN ADS 或临时表 |
聚合结果反哺画像 | ✅ 创建增强型 DWT(如 _enhanced 或 _v2 ),明确依赖 DWS | ❌ 直接修改原 DWT 表结构或逻辑 |
多轮衍生 | ✅ 用 DAG 图管理依赖(如:dwt_v1 → dws_group → dwt_v2) | ❌ 循环依赖(dwt_v2 → dws → dwt_v2) |
🛠 三、具体落地建议(结合你的文档)
1. 在《大数据数仓建模体系》中补充“演进型建模”章节:
4.5 支持需求演进的扩展机制
数仓模型需支持业务需求的持续演进。当新需求需基于 DWT 标签进行聚合时:
- 应在 DWS 层新增聚合表,输入源为 基础 DWT(不含群体特征);
- 若需将聚合结果作为新特征加入画像,应创建 增强型 DWT 表(如
dwt_company_profile_enhanced
),而非修改原表; - 所有跨层依赖必须在元数据中显式记录,确保血缘可追溯。
2. 在《实施流程方案》阶段3中增加“衍生路径评估”步骤:
在构建 DWS/DWT 前,评估:
- 该标签/指标是否可能成为未来聚合维度?
- 是否需要预留“群体特征”扩展位?
- 是否应拆分为基础版 + 增强版?
3. 在《工具包》中增加“依赖关系图模板”:
提供 Mermaid 或 Excel 模板,强制要求在建模时画出:
dwd_company_base_full
├─→ dwt_company_profile_v1
│ └─→ dws_province_high_potential_summary
│ └─→ dwt_company_profile_v2 (enhanced)
└─→ dws_company_summary
💡 四、一句话总结
建模不是一次性设计,而是一个可演进的生态。允许 DWT → DWS → DWT_enhanced,但必须通过分层、版本、显式依赖来守住架构底线。