Power BI学习笔记第11篇:高级数据建模与关系设计
第11篇:高级数据建模与关系设计
1. 数据建模的核心原则
Power BI 的数据建模直接影响报表性能和计算逻辑。一个优秀的数据模型应该遵循以下原则:
| 原则 | 说明 |
|---|---|
| 星型模型优先 | 事实表在中心,维度表环绕 |
| 关系方向正确 | 从维度表指向事实表(一对多) |
| 避免双向关系 | 除非必要,尽量使用单向关系 |
| 合理命名 | 表名、字段名清晰易懂 |
2. 星型模型 vs 雪花模型
2.1 星型模型
┌─────────┐
│ 维度-日期 │
└────┬────┘
│
┌────────┐ │ ┌────────┐
│维度-产品-产品├───┼───┤维度-客户│
└────┬───┘ │ └────┬───┘
│ ↓ │
│ ┌──────────┐ │
└──→│ 事实-销售 │←┘
└──────────┘
优点:
- 查询性能最优
- DAX 计算简洁
- 易于理解和维护
2.2 雪花模型
┌────────┐ ┌────────┐
│子类别表│←────│ 产品表 │
└────────┘ └────┬───┘
│
┌───↓────┐
│事实-销售│
└────────┘
问题:
- 增加关联层级
- DAX 计算复杂化
- 性能可能下降
建议: 将雪花模型扁平化为星型模型。
3. 关系类型详解
3.1 一对多关系(最常用)
维度表(一端)────→ 事实表(多端)
// 从事实表计算维度值
CALCULATE(
SUM(Sales[Amount]),
Product[Category] = "电子产品"
)
3.2 多对多关系
当两表都有重复键时,需要中间桥接表:
表A ──→ 桥接表 ←── 表B
示例场景: 多个销售员可以负责多个客户
销售员表 ──→ 销售员-客户桥接表 ←── 客户表
关键配置:
- 桥接表与两端都是多对一关系
- 关系方向从桥接表指向两表
- 使用
MANYTOMANY关系时需谨慎
3.3 一对一关系
极少使用,通常可以合并为一个表:
员工表 ←──→ 员工详细信息表 // 建议:合并
4. 关系方向与交叉筛选
4.1 单向筛选
维度 ──→ 事实
筛选从维度传递到事实,不反向传递。
// 正常工作
CALCULATE(
SUM(Sales[Amount]),
Product[Category] = "电子产品"
)
4.2 双向筛选
维度 ←──→ 事实
使用场景:
- 复杂的多对多关系
- 需要"向下钻取"筛选
风险:
- 可能导致歧义计算
- 影响性能
- 调试困难
最佳实践: 默认使用单向,仅在必要时开启双向。
5. 不活跃关系
当两表间存在多个关系时,只有一个处于活跃状态:
销售表 ──[订单日期]──→ 日期表(活跃)
│
└──[发货日期]──→ 日期表(不活跃)
使用 USERELATIONSHIP 激活:
// 按订单日期计算销售额
销售额 = SUM(Sales[Amount])
// 按发货日期计算销售额
发货销售额 =
CALCULATE(
SUM(Sales[Amount]),
USERELATIONSHIP(Sales[ShipDate], Date[Date])
)
6. 计算组与计算表
6.1 计算表
从现有数据创建新表:
// 创建聚合汇总表
汇总表 =
SUMMARIZE(
Sales,
Product[Category],
"销售额", SUM(Sales[Amount]),
"订单数", COUNTROWS(Sales)
)
// 创建日历表
日历表 =
CALENDARS(
MIN(Sales[OrderDate]),
MAX(Sales[OrderDate])
)
6.2 计算组(外部工具)
需要使用 Tabular Editor 创建:
计算组:时间智能
├── 计算项:本月
├── 计算项:上月
├── 计算项:年初至今
└── 计算项:去年同期
优势: 减少重复度量值,统一时间智能逻辑。
7. 高级建模技巧
7.1 角色扮演维度
同一维度表扮演多个角色:
// 创建订单日期角色
订单日期 =
CALCULATETABLE(
VALUES(Date),
ALL(Date),
USERELATIONSHIP(Sales[OrderDate], Date[Date])
)
// 创建发货日期角色
发货日期 =
CALCULATETABLE(
VALUES(Date),
ALL(Date),
USERELATIONSHIP(Sales[ShipDate], Date[Date])
)
7.2 快照事实表
处理余额类数据(库存、账户余额):
库存快照表
├── 产品ID
├── 快照日期
└── 库存数量
关键: 避免用 SUM,使用 LASTNONBLANK:
期末库存 =
CALCULATE(
LASTNONBLANK(Inventory[Quantity], 1),
DATESINPERIOD(
Date[Date],
MAX(Date[Date]),
-1,
DAY
)
)
7.3 渐变维度(SCD)
处理维度历史变更:
| 版本 | 字段 | 值 |
|---|---|---|
| v1 | 客户名称 | 张三 |
| v2 | 客户名称 | 张三(已更名) |
// 获取当前有效版本
当前客户名 =
CALCULATE(
MAX(Customer[Name]),
Customer[ValidFrom] <= MAX(Date[Date]),
Customer[ValidTo] >= MAX(Date[Date])
)
8. 性能优化检查清单
| 检查项 | 工具 | 建议 |
|---|---|---|
| 表行数 | DAX Studio | 事实表 > 1000万行需分区 |
| 列基数 | VertiPaq Analyzer | 高基数列考虑移除 |
| 关系数量 | Power BI Desktop | 避免 > 10 个关系 |
| 双向关系 | 模型视图 | 减少使用 |
| 计算列 | 模型视图 | 改为 Power Query 处理 |
9. 最佳实践总结
✅ 使用星型模型
✅ 事实表细长,维度表宽短
✅ 关系从维度指向事实
✅ 默认单向筛选
✅ 不活跃关系 + USERELATIONSHIP
✅ 时间维度使用独立日期表
✅ 避免计算列,优先 Power Query
❌ 避免双向关系滥用
❌ 避免多对多直接关系
❌ 避免计算列用于计算
❌ 避免高基数列用于关系
10. 小结
本篇介绍了高级数据建模:
| 主题 | 要点 |
|---|---|
| 模型设计 | 星型优先,雪花扁平化 |
| 关系类型 | 一对多为主,多对多用桥接表 |
| 筛选方向 | 单向默认,双向慎用 |
| 角色扮演 | 不活跃关系 + USERELATIONSHIP |
| 特殊场景 | 快照表、渐变维度 |
下一篇,我们将深入 DAX 高级计算与性能优化。
posted on 2026-04-25 13:05 哥本哈士奇(aspnetx) 阅读(22) 评论(0) 收藏 举报
浙公网安备 33010602011771号