Power BI Desktop 中的模型关系
本文面向使用 Power BI Desktop 的导入数据建模者。 这是一个重要的模型设计主题,对于提供直观、准确和最佳的模型至关重要。
有关最佳模型设计(包括表角色和关系)的更深入讨论,请参阅 了解星型架构以及 Power BI的重要性。
关系目的
模型关系会将应用于模型表列的筛选器传播到其他模型表。 只要有关系路径可循,筛选器就会进行传播,这可能涉及传播到多个表。
关系路径是确定性的,这意味着筛选器始终以相同的方式传播,且没有随机变化。 但是,可以禁用关系,或通过使用特定 DAX 函数的模型计算来修改筛选器上下文。 有关详细信息,请参阅本文后面的 相关 DAX 函数 主题。
重要
模型关系不会强制实施数据完整性。 有关详细信息,请参阅本文后面的 关系评估 主题,其中介绍了当数据存在数据完整性问题时模型关系的行为方式。
下面通过一个动画示例演示了关系如何传播筛选器。
在此示例中,模型由四个表组成:Category、Product、Year和 Sales。 Category 表与 Product 表相关,Product 表与 Sales 表相关。 Year 表也关联到 Sales 表。 所有关系均为一对多(本文后面将对此进行详细介绍)。
一个查询(可能是由 Power BI 卡片视觉对象生成的)请求获取单个类别 Cat-A和单个年份 CY2018的销售订单的总销售数量。 正因为此,可以看到 Category 和 Year 表上应用的筛选器。 Category 表上的筛选器传播到 Product 表,分离出分配给类别 Cat-A 的两个产品。 然后,Product 表筛选器传播到 Sales 表,针对这些产品分离出两个销售行。 这两个销售行表示分配给类别 Cat-A的产品销售额。 它们的组合数量为 14 个单位。 与此同时,传播 Year 表筛选器以进一步筛选 Sales 表,最终得到一个销售行,该行对应于分配给类别 Cat-A 并于 CY2018 年订购的产品。 查询返回的数量值为 11 个单位。 请注意,当多个筛选器应用于表(如示例中的 Sales 表)时,操作始终是“与”逻辑操作,要求所有条件都必须为真。
应用星型架构设计原则
建议应用 星型架构 设计原则来生成包含维度和事实数据表的模型。 通常,设置 Power BI 以强制实施筛选维度表的规则,从而允许模型关系有效地将这些筛选器传播到事实数据表。
下图是 Adventure Works 销售分析数据模型的模型关系图。 它显示了一个星型架构设计,其中包含一个名为“Sales”事实表。 其他四个表是支持按日期、状态、区域和产品分析销售度量值的维度表。 请注意连接所有表的模型关系。 这些关系将筛选器(直接或间接)传播到“Sales”表。
断开连接的表
一个模型表与另一个模型表不关联的情况不太常见。 有效模型设计中的此类表称为断开连接的表。 断开连接的表不用于将筛选器传播到其他模型表, 它接受“用户输入”(可能包含切片器视觉对象),从而使模型计算能够以有意义的方式使用输入值。 例如,假设有一个断开连接的表,表中加载了一系列货币汇率值。 只要将筛选器应用于按单个速率值进行筛选,度量值表达式就可以使用该值来转换销售值。
Power BI Desktop what-if 参数是一个用于创建断开连接的表的功能。 有关详细信息,请参阅在 Power BI Desktop 中创建并使用 What if 参数来可视化变量。
关系属性
模型关系可将一个表中的一列关联到另一个表中的一列。 (有一个特殊情况,此要求不成立,它仅适用于 DirectQuery 模型中的多列关系。更多信息,请参见 COMBINEVALUES DAX 函数文章。)
注释
无法将列与同一表 中的不同列相关联。 此概念有时与定义外键约束的能力,即关系数据库中的表自引用约束相混淆。 你可以使用此关系数据库概念存储父子关系(例如,每条员工记录均关联到一个“汇报对象”员工)。 但是,不能使用模型关系基于这种类型的关系生成模型层次结构。 若要创建父子层次结构,请参阅父函数和子函数。
列的数据类型
"关系中的“from”列和“to”列的数据类型应相同。" 处理 DateTime 列上定义的关系时可能与预期有所不同。 存储 Power BI 数据的引擎,仅使用 DateTime 数据类型;日期、时间 和 日期/时间/时区 数据类型是基于 Power BI 格式构造实现的。 任何依赖模型的对象仍将在引擎中显示为 DateTime(例如关系、组等)。 因此,如果用户从此类列的 建模 选项卡中选择 日期,由于引擎仍在考虑数据的时间部分,它们仍不会被注册为相同的日期。 详细了解如何处理日期/时间类型。 若要更正行为,应在 Power Query 编辑器中更新列数据类型, 从导入的数据中删除 时间 部分,因此当引擎处理数据时,值将显示相同。
基数
每个模型关系都由基数类型定义。 一共有四个基数类型选项,表示“从”和“到”相关列的数据特征。 “一”侧表示该列包含唯一值;“多”侧表示该列可以包含重复值。
注释
如果数据刷新操作尝试将重复值加载到“一”侧列中,则整个数据刷新将失败。
以下项目符号列表描述了这四个选项及其速记符号:
- 一对多 (1:*)
- 多对一 (*:1)
- 一对一 (1:1)
- 多对多 (*:*)
当你在 Power BI Desktop 中创建关系时,设计器会自动检测并设置基数类型。 Power BI Desktop 会查询模型,以了解哪些列包含唯一值。 对于导入模型,它使用内部存储统计信息;对于 DirectQuery 模型,它将分析查询发送到数据源。 但是,Power BI Desktop 有时可能会出错。 如果表中尚未加载数据,或你希望包含重复值的列当前包含唯一值,它可能会出错。 不论是哪种原因,只要任何“一”端列包含唯一值(或表中尚未加载数据行),你都可以更新基数类型。
一对多(和多对一)基数
“一对多”和“多对一”基数选项基本相同,并且它们也是最常见的基数类型。
配置一对多或多对一关系时,将选择与列关联顺序匹配的关系。 设想一下,如何使用每个表中的 ProductID 列来配置从 Product 表到 Sales 表的关系。 基数类型将为一对多,因为 Product 表中的 ProductID 列包含唯一值。 如果将表反向关联,即 Sales 到 Product,则基数为多对一。
一对一基数
一对一关系意味着两个列都包含唯一值。 这种基数类型并不常见,并且由于冗余数据的存储,它可能代表了不太理想的模型设计。
若要详细了解如何使用此基数类型,请参阅一对一关系指南。
多对多基数
多对多关系意味着两个列都可以包含重复值。 这种基数类型很少使用。 在设计复杂的模型需求时,它通常很有用。 可以使用它来关联多对多事实或关联更高粒度的事实。 例如,当销售目标事实存储在产品类别级别,并且产品维度表存储在产品级别时。
有关使用此基数类型的指南,请参阅多对多关系指南。
注释
2024 年 1 月开始,为 Power BI 报表服务器开发的模型不再支持“多对多”基数类型。
小提示
在 Power BI Desktop 模型视图中,可以通过查看关系线两端的指示符(1 或 *)来解释关系的基数类型。 若要确定哪些列相关,需要选择或将光标悬停在关系行上以突出显示列。
交叉筛选器方向
为每个模型关系定义交叉筛选方向。 你的设置将决定筛选器的传播方向。 可能的交叉筛选选项取决于基数类型。
基数类型 | 交叉筛选选项 |
---|---|
一对多(或多对一) | 单向 两者 |
一对一 | 两者 |
多对多 | 单一(表1至表2) 单(Table2 到 Table1) 两者 |
单一 交叉过滤方向表示“单一方向”,双 表示“双向”。 在两个方向进行筛选的关系通常称为双向。
在一对多关系中,交叉筛选方向始终从“一”侧开始,也可以选择从“多”侧开始(双向)。 在一对一关系中,交叉筛选方向始终来自两个表。 最后,在多对多关系中,交叉筛选方向可以从其中一个表开始,也可以同时从两个表开始。 请注意,当基数类型包括“一”侧时,此类筛选器将始终从该侧传播。
当交叉筛选方向设置为“双向”时,其他属性变为可用。 当 Power BI 强制实施行级安全 (RLS) 规则时,它可以应用双向筛选。 有关 RLS 的详细信息,请参阅 Power BI Desktop 中的行级别安全性(RLS)。
也可以通过模型计算来修改关系交叉筛选方向(包括禁用筛选器传播)。 它通过使用 CROSSFILTER DAX 函数来实现。
请记住,双向关系可能会对性能产生负面影响。 此外,尝试配置双向关系可能会导致筛选器传播路径不明确。 在这种情况下,Power BI Desktop 可能无法提交关系更改,并通过错误消息发出警报。 但是,有时 Power BI Desktop 可能允许你在表之间定义不明确的关系路径。 后文将介绍如何解决关系路径多义性的问题。
建议仅在需要时使用双向筛选。 有关详细信息,请参阅双向关系指南。
小提示
在 Power BI Desktop 模型视图中,可以通过观察关系线的箭头来解释关系的交叉筛选方向。 单箭头表示沿箭头方向的单向筛选器;双箭头表示双向关系。
激活此关系
两个模型表之间只能有一条活动的筛选器传播路径。 但是,可以引入其他关系路径,但必须将这些关系设置为 非活动。 只能在模型计算评估期间激活非活动关系。 它通过使用 USERELATIONSHIP DAX 函数来实现。
通常,建议尽可能定义活动关系。 扩大了报表作者使用模型的范围和潜力。 仅使用活动关系意味着应在模型中复制角色扮演维度表。
不过,在特定情况下,可以为角色扮演维度表定义一个或多个非活动关系。 在以下情况下,可以考虑这种设计:
- 不要求报表可视化内容同时按不同角色进行筛选。
- 使用
USERELATIONSHIP
DAX 函数激活特定关系,以进行相关模型计算。
有关详细信息,请参阅活动与非活动关系指南。
小提示
在 Power BI Desktop 模型视图中,可以解释关系的活动状态与非活动状态。 活动关系用实线表示;非活动关系用虚线表示。
假定引用完整性
假设引用完整性属性仅适用于属于同一源组的两个 DirectQuery 存储模式表之间的一对多和一对一关系。 仅当“多”侧列不包含 NUL 时,才能启用此属性。
启用后,发送到数据源的本机查询会使用 INNER JOIN
(而不是 OUTER JOIN
)来联接两个表。 通常,启用此属性可以提高查询性能,但具体取决于数据源的详细情况。
当两个表之间存在数据库外键约束时,始终启用此属性。 即使没有外键约束,但只要确定特定数据完整性存在,就可以考虑启用此属性。
重要
如果数据完整性被破坏,内部联接将消除表间不匹配的行。 例如,考虑一个模型 Sales 表,其中有一个 ProductID 列值在相关的 Product 表中不存在。 从 Product 表到 Sales 表的筛选器传播将消除未知产品的销售行。 这会导致低估销售结果。
有关详细信息,请参阅 Power BI Desktop 中的假设引用完整性设置。
相关的 DAX 函数
有几个与模型关系相关的 DAX 函数。 以下项目符号列表简要介绍了每个函数:
- RELATED:从关系的“一”侧检索值。 当涉及在行上下文中评估的不同表的计算时,此函数会很有用。
- RELATEDTABLE:从关系的“多”侧检索表行。
- USERELATIONSHIP:允许计算使用非活动关系。 (从技术上说,此函数修改特定非活动模型关系的权重,有助于影响其使用。当模型包含角色扮演维度表,并且你选择从此表中创建非活动关系时,这非常有用。 你还可以使用此函数来解决筛选器路径多义性的问题。
- CROSSFILTER:修改关系交叉筛选方向(单或双),或者禁用筛选器传播(无)。 在评估特定计算时需要更改或忽略模型关系,此功能非常有用。
- COMBINEVALUES:将两个或多个文本字符串合并形成一个文本字符串。 此函数的目的是,在表属于同一源组时支持 DirectQuery 模型中的多列关系。
- TREATAS:将表表达式的结果作为筛选器应用于不相关的表中的列。 在高级场景中,当您想在评估特定计算时创建虚拟关系,这会非常有用。
- 父函数和子函数:可用于生成计算列以自然化父子层次结构的相关函数系列。 然后你可以使用这些列创建固定级别的层次结构。
关系评估
从评估的角度来看,模型关系被归类为 常规 或 有限的。 此关系属性不可配置。 实际上,它从基数类型和两个相关表的数据源推断出来。 了解评估类型非常重要,因为如果数据完整性受到损害,可能会产生一些性能影响或后果。 本主题介绍了这些影响和完整性后果。
首先,需要通过一些建模理论来充分了解关系评估。
导入或 DirectQuery 模型从 Vertipaq 缓存或源数据库收集其所有数据。 在这两个实例中,Power BI 都能确定某个关系的“一”侧是否存在。
但是,复合模型可以由使用不同存储模式(导入、DirectQuery 或双重存储模式)的表组成,或者包含多个 DirectQuery 源。 每个源(包括导入数据的 Vertipaq 缓存)都被视为 源组。 然后,可以将模型关系分类为内源组 或跨/交源组 。 源组内部关系将源组中的两个表关联,而跨源组关系将表关联到两个源组。 请注意,导入模型或 DirectQuery 模型中的关系始终位于源组中。
下面是 Composite 模型的一个示例。
在此示例中,复合模型由两个源组组成:一个 Vertipaq 源组和一个 DirectQuery 源组。 Vertipaq 源组包含三个表,DirectQuery 源组包含两个表。 存在一个跨源组关系,用于将 Vertipaq 源组中的表与 DirectQuery 源组中的表相关联。
常规关系
当查询引擎可以确定关系的“一”侧时,模型关系为“常规”。 它已确认“一”侧列包含唯一值。 所有一对多的源组内关系都是常规关系。
在以下示例中,有两个正则关系,两者都标记为 R 。关系包括 Vertipaq 源组中包含的一对多关系,以及 DirectQuery 源中包含的一对多关系。
对于导入模型,其中所有数据都存储在 Vertipaq 缓存中,Power BI 会在数据刷新时为每个常规关系创建一个数据结构。 数据结构由所有列到列值的索引映射组成,其用途是在查询时加快表的联接速度。
在查询时,常规关系允许进行表扩展。 表扩展会包含基表的本机列,然后扩展到关联表中,从而创建虚拟表。 对于导入表,表扩展是在查询引擎中完成的;对于 DirectQuery 表,它是在发送到源数据库的本机查询中完成的(只要未启用 假定引用完整性 属性)。 然后,查询引擎对扩展表进行操作,应用筛选器,并按扩展表列中的值进行分组。
注释
非活动关系也会进行扩展,即使计算操作未使用该关系也是如此。 双向关系对表扩展没有影响。
对于一对多关系,使用 LEFT OUTER JOIN
语义从“多”侧到“一”侧进行表扩展。 当从“多”侧到“一”侧的匹配值不存在时,会向“一”侧表添加一个空白虚拟行。 此行为仅适用于常规关系,不适用于有限关系。
表扩展也适用于一对一的源组内关系,但要使用 FULL OUTER JOIN
语义。 此联接类型可确保必要时在任一侧添加空白虚拟行。
空白虚拟行实际上是未知成员。 未知成员表示引用完整性冲突,其中“多”侧值没有对应的“一”侧值。 理想情况下,这些空白不应存在。 可以通过清理或修复源数据来消除它们。
下面是表扩展如何与动画示例配合使用。
在此示例中,模型由三个表组成:Category、Product 和 Sales。 Category 表通过一对多的关系关联到 Product 表,而 Product 表通过一对多的关系关联到 Sales 表。 Category 表包含两行,Product 表包含三行,Sales 表包含五行。 所有关系的两端都有匹配的值,这意味着不存在引用完整性冲突。 系统会显示一个查询时扩展表。 该表由这三个表中的列组成。 实际上,它是三个表中所含数据的非规范化透视图。 将向 Sales 表添加一个新行,其中包含一个生产标识符值 (9),该值在 Product 表中没有匹配值。 这是一个引用完整性冲突。 在扩展表中,新行针对 Category 和 Product 表列具有 (Blank) 值。
有限关系
当没有确定的“一”侧时,模型关系为“有限”。 关系受限可能出于以下两个原因:
- 该关系使用多对多基数类型(即使其中一列或两列都包含唯一值)。
- 该关系是跨源组的(这种情况仅适用于复合模型)。
在以下示例中,有两个有限关系,两者都标记为 L 。这两种关系包括 Vertipaq 源组中包含的多对多关系,以及一对多跨源组关系。
对于 Import 模型,永远不会为有限关系创建数据结构。 在这种情况下,Power BI 在查询时执行表联接的解析。
表扩展永远不会发生在有限关系中。 表联接是通过使用 INNER JOIN
语义实现的,因此不会添加空白虚拟行来补偿引用完整性冲突。
存在与有限关系相关的其他限制:
- 无法使用
RELATED
DAX 函数来检索“一”侧列值。 - RLS 的强制执行存在拓扑限制。
小提示
在 Power BI Desktop 模型视图中,可以将关系解释为受限关系。 基数指示器后,用括号状标记 () 表示有限关系。
解决关系路径不明确性
双向关系可以在模型表之间引入多个(因此不明确)筛选器传播路径。 在评估多义性时,Power BI 根据其优先级和权重选择筛选器传播路径。
优先权
优先级层定义 Power BI 用来解析关系路径歧义的规则序列。 第一个规则匹配确定 Power BI 将遵循的路径。 下面的每个规则描述了筛选器如何从源表流向目标表。
- 由一对多关系组成的路径。
- 由一对多或多对多关系组成的路径。
- 由多对一关系组成的路径。
- 一个路径,包括从源表到中间表的一对多关系,随后是从中间表到目标表的多对一关系。
- 由从源表到中间表的一对多或多对多关系以及从中间表到目标表的多对一或多对多关系组成的路径。
- 任何其他路径。
某一关系包含在所有可用路径中时,应将其从所有路径中删除。
重量
路径中的每个关系都有一个权重。 默认情况下,除非使用 USERELATIONSHIP 函数,否则每个关系权重都是相等的。 路径权重 是路径上所有关系权重的最大值。 Power BI 使用路径权重来解决同一优先级层中多个路径之间的歧义。 它不会选择优先级较低的路径,但它将选择权重较高的路径。 路径中的关系数不会影响权重。
可以使用 USERELATIONSHIP 函数来影响关系的权重。 权重由对此函数的调用的嵌套级别确定,其中最内部的调用接收最高权重。
请考虑以下示例。 产品销售 度量值对 Sales[ProductID] 和 Product[ProductID]之间的关系赋予更高的权重,其次是 Inventory[ProductID] 和 Product[ProductID]之间的关系。
Product Sales =
CALCULATE(
CALCULATE(
SUM(Sales[SalesAmount]),
USERELATIONSHIP(Sales[ProductID], Product[ProductID])
),
USERELATIONSHIP(Inventory[ProductID], Product[ProductID])
)
注释
如果 Power BI 检测到具有相同优先级和相同权重的多个路径,它将返回一个不明确的路径错误。 在这种情况下,必须通过使用 USERELATIONSHIP 函数或删除或修改模型关系来影响关系权重来解决歧义。
性能首选项
以下列表对筛选器传播性能(从最快到最慢)进行了排序:
- 一对多的源组内关系
- 使用中间表实现的多对多模型关系,并且涉及至少一个双向关系
- 多对多基数关系
- 跨源组关系
相关内容
有关本文的详细信息,请查看以下资源: