活动与非活动关系指南

本文针对使用 Power BI Desktop 的您——数据建模人员。 它提供有关何时创建活动或非活动模型关系的指南。 默认情况下,活动关系将筛选器传播到其他表。 然而,非活动关系只有在 DAX 表达式激活(使用)此关系时,才传播筛选器。

注意

本文未介绍模型关系简介。 如果不熟悉关系、其属性或配置方式,建议先阅读 Power BI Desktop 文章中的 模型关系。

了解星型架构设计也很重要。 有关详细信息,请参阅 了解星型架构及其对于 Power BI 的重要性

活动关系

通常,建议尽可能定义活动关系。 此类关系扩大了报表作者和使用问答的用户使用模型的范围和可能性。

请考虑 导入模型 的一个示例,该模型旨在分析航班的准点率(OTP)。 该模型有一个 Flight 表,该表是一个事实表,每个航班存储一行。 每行记录航班日期、航班号、出发和到达机场以及任何延误时间(以分钟为单位)。 还有一个 Airport 表,该表是一个维度表,每个机场存储一行。 每行描述机场代码、机场名称和国家或地区。

下面是这两个表的部分模型图。

显示包含两个表的模型的关系图:航班和机场。以下段落介绍了关系设计。

FlightAirport 表之间存在两种模型关系。 在 Flight 表中,DepartureAirport 列和 ArrivalAirport 列与 Airport 表的 Airport 列相关。 在星型架构设计中,Airport 表被描述为角色扮演维度。 在此模型中,这两个角色是 出发机场抵达机场

虽然此设计适用于关系星型架构设计,但它不适用于 Power BI 模型。 这是因为模型关系是筛选器传播的路径,这些路径必须是确定性的。 有关确保筛选器传播路径确定性的详细信息,请参阅 解析关系路径不明确性。因此,如本示例中所示,一个关系处于活动状态,而另一个关系处于非活动状态(由虚线表示)。 具体而言,与 ArrivalAirport 列的关系是活动的,这意味着应用于 Airport 表的筛选器会自动传播到 Flight 表的 ArrivalAirport 列。

此模型设计对如何报告数据施加了严重限制。 具体而言,无法通过筛选 Airport 表来自动隔离出发机场的航班详细信息。 由于报表需要同时按出发机场和到达机场进行筛选(或分组),因此需要两个活动关系。 将此要求转换为 Power BI 模型设计意味着该模型必须具有两个机场表。

下面是改进的模型设计。

关系图,显示包含四个表的模型:日期、航班、出发机场和到达机场。

模型现有两个机场表:Departure AirportArrival Airport。 这些表与 Flight 表之间的每个模型关系都处于活动状态。 另请注意,Departure AirportArrival Airport 表中的列名以“出发”或“到达”作为前缀。

改进的模型设计支持生成以下报表设计。

显示报表页的 关系图显示了包含两个切片器和一个表视觉对象的报表页。切片器是“月份”和“出发机场”。

报表页按“墨尔本”作为出发机场进行筛选,表视觉对象按到达机场进行分组

注意

对于导入模型,添加另一个维度表会导致模型大小增加,刷新时间更长。 因此,它与导入建模的数据缩减方法一文中所述的建议相矛盾。 不过,在此示例中,只包含活动关系的要求比这些建议更重要。

此外,维度表通常存储的行数相对于事实表而言较少。 因此,增加的模型大小和刷新时间不太可能太大。

重构方法

下面介绍了一种方法,可将模型从单个角色扮演维度表重构为采用“每个角色一个表”的设计

  1. 删除所有非活动关系。

  2. 请考虑重命名角色扮演维度表以更好地描述其角色。 在本文中的示例中,Airport 表与 Flight 表的 ArrivalAirport 列相关,因此将其重命名为 Arrival Airport

  3. 创建角色扮演表的副本,为其提供一个与其角色相符的名称。 如果这是一个导入表,我们建议您创建一个计算表。 如果是 DirectQuery 表,则可以复制 Power Query 查询。

    在此示例中,Departure Airport 表是使用以下计算表定义创建的。

    Departure Airport = 'Arrival Airport'
    
  4. 创建活动关系来关联新表。

  5. 请考虑重命名表中的列,以便准确反映其角色。 在本文中的示例中,所有列都以 “出发”或 到达一词作为前缀。 默认情况下,这些名称可确保报表视觉对象具有自我描述和非模棱两可的标签。 它还改进了 Q&A 体验,允许用户轻松编写准确的问题。

  6. 不妨向角色扮演表添加说明。 (在“数据”窗格中,当报表作者将光标悬停在表上时,工具提示中会显示说明。)这样,你就可以向报表作者传达其他筛选器传播详细信息

非活动关系

在特定情况下,非活跃关系可以满足特定的报告需求。

请考虑不同的模型和报告要求:

  • 销售模型包含一个具有两个日期列的 Sales 表:OrderDateShipDate
  • Sales 表中的每一行都记录单个订单。
  • 日期筛选器几乎始终应用于 OrderDate 列,该列始终存储有效日期。
  • 只有一个度量值要求将日期筛选器传播到 ShipDate 列,其中可能包含 BLANK(即在订单发货前)。
  • 无需同时筛选(或分组)订单 发货日期周期。

下面是这两个表的部分模型图。

模型图,显示包含两个表的模型:Sales 和 Date。Sales 表包含六个度量值。

SalesDate 表之间存在两种模型关系。 在 Sales 表中,OrderDate 列和 ShipDate 列与 Date 表的 Date 列相关。 在此模型中,Date 表有两个角色,分别是 订单日期发货日期。 与 OrderDate 列之间的关系是活动的。

除了一个之外,其余所有五个度量值都必须按 OrderDate 列进行筛选。 但 Orders Shipped 度量值必须按 ShipDate 列筛选。

下面是 Orders 度量值定义。 它只需计算筛选器上下文中 Sales 表的行数。 应用于 Date 表的任何筛选器都传播到 OrderDate 列。

Orders = COUNTROWS(Sales)

下面是 Orders Shipped 度量值定义。 它使用 USERELATIONSHIP DAX 函数,该函数仅在表达式求值期间才激活特定关系的筛选器传播。 在此示例中,使用的是与 ShipDate 列之间的关系。

Orders Shipped =
CALCULATE(
    COUNTROWS(Sales)
    ,USERELATIONSHIP('Date'[Date], Sales[ShipDate])
)

此模型设计支持生成以下报表设计。

关系图显示了包含一个切片器和一个表视觉对象的报表页。切片器是“季度”,表视觉对象列出了每月销售统计信息。

报表页按 2019 年第 4 季度进行筛选。 表视觉对象按月份进行分组,并显示各种销售统计信息。 OrdersOrders Shipped 度量值产生不同的结果。 它们都使用相同的摘要逻辑(统计 Sales 表中的行数),但使用的 Date 表筛选器传播却不同。

请注意,“季度”切片器包含一个 BLANK 选项。 此切片器选项作为表扩大的结果显示。 虽然每个 Sales 表行都有有效的订单日期,但某些行有空白发货日期-这些订单尚未发货。 表扩大也考虑非活动关系,因此显示 BLANK 可能是因为关系的“多”端包含 BLANK,也可能是因为出现数据完整性问题。

注意

行级安全性 (RLS) 筛选器仅通过活动关系传播。 即使度量值定义使用 USERELATIONSHIP DAX 函数,RLS 筛选器也不会针对非活动关系传播。

建议

我们建议尽可能定义活动关系,尤其是在为数据模型定义 RLS 角色时。 它们扩大了报表作者和使用 Q&A 的用户对模型的使用范围和潜力。 这意味着角色扮演维度表应在模型中进行复制。

但是,在特定情况下,可以为角色扮演维度表定义一个或多个非活动关系。 在以下情况下,可以考虑此方法:

  • 不要求报表视觉对象同时按不同角色进行筛选。
  • 使用 USERELATIONSHIP DAX 函数激活特定关系,以进行相关模型计算。

有关本文的详细信息,请查看以下资源: