微软PowerBI考试 PL300-在 Power BI 中设计语义模型 【附练习数据】
微软PowerBI考试 PL300-在 Power BI 中设计语义模型
在 Power BI 中创建复杂语义模型的流程非常简单。 如果您的数据来自多个事务系统,那么您可能会有数十个必须处理的表,而您最初并不知道这一点。 构建出色的语义模型就是要精简混乱的情况。 星形架构是精简语义模型的一种方法,您将在本模块中了解其术语和实现方式。 您还将了解为什么选择适当的数据粒度对于 Power BI 报告的性能和可用性非常重要。 最后,您将了解如何使用 Power BI 语义模型提升性能。
创建出色的语义模型是数据分析人员可以在 Microsoft Power BI 中执行的最重要的任务之一。 通过出色地完成这项工作,你可以帮助用户更轻松地理解你的数据,从而使他们和你自己能够更轻松地生成有价值的 Power BI 报表。
出色的语义模型具有以下优点:
数据浏览速度更快。
聚合更易于生成。
报表更加准确。
编写报表所需的时间更少。
报表以后更易于维护。
为生成出色语义模型制定固定规则很难,因为所有数据都不相同,并且数据的用法也各有不同。 一般而言,较小的语义模型会更好,因为其性能更快并且更易于使用。 但是,定义较小的语义模型同样困难重重,原因在于这是一个启发式的主观概念。
通常情况下,较小的语义模型包含更少的表,且每个表中用户可以看到的列也更少。 如果从销售数据库中导入所有必需的表,但共计有 30 个表,则用户不会认为其具有直观性。 将这些表折叠为五个表会使语义模型对用户而言更直观,而如果用户打开某个表并找到 100 列,他们可能会觉得无从着手。 删除不需要的列来提供可管理的列数可增加用户查看所有列名的可能性。 总而言之,在设计语义模型时应该以简洁性为目标。
下图是示例语义模型。 这些框中包含数据表,且框内的每个行项都是一列。 连接框的线表示表之间的关系。 即使在此类简单模型中,这些关系也可能很复杂。 语义模型很容易变得混乱,且模型中的总表数会逐渐增加。 让语义模型保持简单、全面和准确需要不断地努力。
通过主键和外键在表之间定义关系。 主键是标识每个唯一的非 null 数据行的列。 例如,如果你有一个“Customers”表,则可以有一个标识每个唯一客户的索引。 第一行的 ID 为 1,第二行的 ID 为 2,依此类推。 每行都分配有一个唯一值,该值可通过主键这一简单值进行指代。 当你引用其他表中的行时,此过程非常重要,这也是外键的作用所在。 当不同的表之间具有共用的主键和外键时,便会形成表之间的关系。
Power BI 允许从具有不同数据源的表中生成关系,它是一个功能强大的函数,使你可以从 Microsoft Excel 中拉取一个表并从关系数据库中拉取另一个表。 然后,你将在这两个表之间创建关系,并将它们视为统一的语义模型。
现在,你已了解构成数据架构的关系,接下来可以探索一种特定类型的架构设计,即星型架构。该架构经过优化,可实现高性能和可用性。
星型架构 你可以设计星型架构用于简化数据。 这不是简化数据的唯一方法,但它是一种常用方法;因此,每个 Power BI 数据分析人员都应该了解它。 在星型架构中,语义模型中的每个表都定义为一个维度表或事实数据表,如下图所示。
事实数据表包含观测或事件数据值:销售订单、产品计数、价格、交易日期和时间,以及数量。 事实数据表可以包含多个重复值。 例如,对于不同日期的不同客户,一个产品可以在多个行中多次出现。 可以聚合这些值以创建视觉对象。 例如,总销售订单数视觉对象是事实数据表中所有销售订单的聚合。 对于事实数据表,通常会看到填充数字和日期的列。 这些数字可以是度量单位(例如销售量),也可以是键(例如客户 ID)。 日期表示记录的时间,如订单日期或发货日期。
维度表包含有关事实数据表中数据的详细信息:产品、位置、员工和订单类型。 这些表通过键列连接到事实数据表。 维度表用于对事实数据表中的数据进行筛选和分组。 另一方面,事实数据表包含可度量的数据,如销售额和收入,每一行表示维度表中值的唯一组合。 对于总销售订单数视觉对象,可以将数据分组,以便按产品查看总销售订单数,其中产品是维度表中的数据。
事实数据表比维度表大很多,因为许多事件在事实数据表中发生,例如单独的销售。 维度表通常较小,因为受限于可以筛选和分组的项数。 例如,一年仅包含一定数量的月份,而美国仅由一定数量的州组成。
考虑到有关事实数据表和维度表的这些信息,你可能想知道如何在 Power BI 中生成此视觉对象。
相关数据位于“Employee”和“Sales”这两个表中,如以下语义模型所示。 因为“Sales”表包含可以聚合的销售订单值,所以将其视为事实数据表。 “Employee”表包含特定员工姓名,可用于筛选销售订单,因此它将是维度表。 两个表之间的公用列(即“Employee”表中的主键)为“EmployeeID”,因此,可以基于此列在两个表之间建立关系。
创建此关系时,可以根据要求生成视觉对象,如下图所示。 如果不建立此关系,则在需要考虑两个表之间的共性的情况下,将更难以生成视觉对象。
星型架构和基础语义模型是有序报表的基础;在创建这些连接和设计上花费的时间越多,创建和维护报表就越容易。
使用表
用户看到的表越少,他们就会越喜欢使用你的语义模型。 例如,假设已从许多数据源中导入数十个表,但现在视觉对象看起来杂乱无序。 在这种情况下,你需要确保在开始生成报表之前,语义模型和表结构已经过简化。
简单的表结构具有以下特征:
易于浏览,因为列和表的属性具体且用户友好。
已合并或追加表,以简化数据结构中的表。
表之间具有合理的高质量关系。
以下部分进一步说明可如何使用表来确保获得简单可读的表结构。
配置语义模型并生成表之间的关系
假设已检索数据并在 Power Query 中对其进行了清理,接下来可以转到语义模型所在的“模型”选项卡。 下图显示可如何通过“OrderDate”列查看“Order”和“Sales”表之间的关系。
若要管理这些关系,请转到功能区的“管理关系”,此时会显示以下窗口。
在此视图中,你可以创建、编辑和删除表之间的关系,还可以自动检测已经存在的关系。 将数据加载到 Power BI 中时,“自动检测”功能将帮助你在名称相似的列之间建立关系。 关系可以处于非活动状态,也可以处于活动状态。 表之间只能存在一个活动关系,这将在以后的模块中进行讨论。
尽管“管理关系”功能允许配置表之间的关系,但也可以配置表和列属性以确保表结构的有序性。
配置表和列属性
Power BI Desktop 中的“模型”视图在你可以查看或更新的列属性中提供许多选项。 若要进入此菜单来更新表和字段,只需 Ctrl + 单击或 Shift + 单击此页上的项即可。
在“常规”选项卡下,你可以:
编辑列的名称和描述。
添加可在使用问答功能时用于标识列的同义词。
在文件夹中添加列用于进一步整理表结构。
隐藏或显示列。
在“格式设置”选项卡下,你可以:
更改数据类型。
设置日期格式。
例如,假设已按照“Wednesday, March 14, 2001”的格式设置列中日期的格式,如上一屏幕截图所示。 如果想要更改格式以使日期采用“mm/dd/yyyy”的格式,则可以选择“所有日期时间格式”下的下拉菜单,然后选择相应的日期格式,如下图所示。
选择相应的日期格式后,返回到“Date”列,此时应该看到格式已更改,如下图所示。
在“高级”选项卡下,你可以:
按特定列排序。
为数据分配特定类别。
汇总数据。
确定列或表是否包含 null 值。
此外,Power BI 具有一项新功能,可通过 Ctrl + 单击或 Shift + 单击项来更新许多表和字段上的这些属性。
这些示例只是可用于简化表结构的许多转换类型中的一部分。 在开始创建视觉对象前,必须执行此步骤,以免在进行格式更改时来回切换。 设置格式和配置表的这一过程也可在 Power Query 中完成。
创建日期表
在 Power BI 中创建报表时,一个常见的业务需求是根据日期和时间进行计算。 组织希望了解其业务在几个月、几个季度、会计年度等期间的表现。 因此,正确设置这些时间导向的值的格式至关重要。 Power BI 可自动检测日期列和表;但是,在某些情况下,您需要采取额外步骤才能获取组织所要求格式的日期。
例如,假设您正在为组织的销售团队编制报表。 数据库包含用于销售、订单、产品等的表。 您注意到,其中许多表(包括“Sales”和“Orders”)都包含自己的日期列,如“Sales”和“Orders”表中的 ShipDate 和 OrderDate 列所示。 您的任务是编制按年和月划分的总销售额和订单表。 如何生成具有多个表的视觉对象并让每个表都引用自己的日期列?
若要解决此问题,可以创建一个可由多个表使用的公用日期表。 以下部分将说明如何在 Power BI 中完成此任务。
创建公用日期表
可用于生成公用日期表的方法包括:
源数据
DAX
Power Query
源数据
有时,源数据库和数据仓库已具有自己的日期表。 如果设计数据库的管理员的工作完成得出色,则可以使用这些表执行以下任务:
确定公司假日
分离日历和会计年度
确定周末与工作日
源数据表已非常成熟,可以立即使用。 如果您有这样的表格,请将其纳入您的语义模型,忽略此部分中概述的任何其他方法即可。 我们建议您使用源日期表,因为除了 Power BI 之外,它还可能与您使用的其他工具共享。
如果没有源数据表,则可以使用其他方法来生成公用日期表。
DAX
可以使用 Data Analysis Expression (DAX) 函数 CALENDARAUTO() 或 CALENDAR() 来生成公用日期表。 CALENDAR() 函数根据在函数中作为参数输入的开始日期和结束日期返回连续的日期范围。 或者,CALENDARAUTO() 函数返回根据语义模型自动确定的连续、完整的日期范围。 开始日期被选为语义模型中存在的最早日期,结束日期是语义模型中存在的最晚日期加上已填充到会计月份的数据,您可以选择此会计月份将其作为参数包含在 CALENDARAUTO() 函数中。 在本示例中,使用 CALENDAR() 函数是因为您只想查看从 2011 年 5 月 31 日(“Sales”开始跟踪此数据的第一天)开始到接下来 10 年的数据。
在 Power BI Desktop 中,选择新建表,然后输入以下 DAX 公式:
Dates = CALENDAR(DATE(2011, 5, 31), DATE(2022, 12, 31))
现在,您有一个可以使用的日期列。 但此列略微稀疏, 而且您只想查看年份、月份号、一年中的第几周以及星期几的列。 可通过选择功能区上的新建列并输入以下 DAX 公式来完成此任务,该公式将从“Date”表中检索年份。
Year = YEAR(Dates[Date])
您可以执行相同的过程来检索月份号、周数和星期几:
MonthNum = MONTH(Dates[Date])
WeekNum = WEEKNUM(Dates[Date])
DayoftheWeek = FORMAT(Dates[Date], "DDDD")
完成后,表将包含下图所示的列。
现在,您已使用 DAX 创建了公用日期表。 此过程仅将您的新表添加到语义模型中;您仍然需要在 date 表与 Sales 表和 Order 表之间建立关系,然后将您的表标记为语义模型的正式日期表。 但是,在完成这些任务之前,请确保考虑生成通用日期表的另一种方法:使用 Power Query。
Power Query
您可以使用 M 语言(用于在 Power Query 中构建查询的开发语言)来定义通用日期表。
在 Power BI Desktop 中选择转换数据,它会将您引导至 Power Query。 在左侧查询窗格的空白处,右键单击以打开下面的下拉菜单,并在其中依次选择新建查询 > 空查询。
在显示的新建查询视图中,输入以下 M 公式以生成日历表:
= List.Dates(#date(2011,05,31), 365*10, #duration(1,0,0,0))
对于您的销售数据,您希望开始日期反映您数据中的最早日期:2011 年 5 月 31 日。 此外,您想查看接下来 10 年的日期,包括将来的日期。 此方法可确保随着新销售数据的流入,您不必重新创建此表。 您还可以更改持续时间。 在本例中,您希望每天都有一个数据点,但也可以按小时、分钟和秒递增。 下图显示了结果。
成功完成该过程后,您会发现自己拥有了一个日期列表,而不是一个日期表。 若要更正此错误,请转到功能区上的转换选项卡,然后选择转换 > 为表。 顾名思义,此功能会将列表转换为表。 您还可以将此列重命名为 DateCol。
接下来,您希望向新表中添加列,以按年、月、周和日查看日期,以便可以在视觉对象中生成层次结构。 第一个任务是更改列类型,方法是选择列名旁边的图标,然后在显示的下拉菜单中选择日期类型。
完成日期类型选择后,可以添加年、月、星期和天的列。 转到添加列,选择日期下的下拉菜单,然后选择年,如下图所示。
请注意,Power BI 添加了从 DateCol 中提取的所有年份的列。
对月、周和天完成相同的过程。 完成此过程后,表将包含下图所示的列。
您现在已经成功使用 Power Query 生成了一个通用日期表。
前面的步骤展示了如何将表纳入语义模型。 现在,您需要将表标记为正式日期表,以便 Power BI 可以识别所有未来的值并确保格式设置正确。
标记为正式日期表
要将表标记为正式日期表,首先在字段窗格中找到新表。 右键单击表名,然后选择标记为日期表,如下图所示。
通过将表标记为日期表,Power BI 可执行验证以确保数据包含零个空值、是唯一的并且包含一段时间内的连续日期值。 您还可以选择表中的特定列以将其标记为日期,这在表中包含许多列的情况下非常实用。 右键单击表,选择标记为日期表,然后选择日期表设置。将出现以下窗口,您可以在其中选择应将哪一列标记为日期。
选择标记为日期表将从该表的 Date 字段中删除自动生成的层次结构,您将该表标记为日期表。 对于其他日期字段,在建立该字段与日期表之间的关系或关闭自动日期/时间功能前,自动层次结构仍将存在。 您可以向公用日期表手动添加层次结构,方法是右键单击字段窗格中的 year、month、week 或 day 列,然后选择新建层次结构。本模块后面将详细介绍此过程。
生成视觉对象 若要在“Sales”和“Orders”表之间生成视觉对象,需要在这一新的公用日期表与“Sales”和“Orders”表之间建立关系。 这样您将能够使用新的日期表来生成视觉对象。 要完成此任务,请转到模型选项卡 > 管理关系,可在其中创建通用日期表与“Sales”和“Orders”表之间的关系,方法是使用 OrderDate 列。 以下屏幕截图显示此类关系的一个示例。
建立关系后,您可以通过您使用 DAX 或 Power Query 方法编制的公用数据表,生成自己的按时间划分的总销售额和订单数量视觉对象。
若要确定总销售额,需要添加所有销售额,因为“Sales”表中的 Amount 列仅关注每笔销售的收入,而不是总销售收入。 可通过使用以下度量值计算来完成此任务,这将在稍后的讨论中进行说明。 生成此度量值时将使用的计算如下:
#Total Sales = SUM(Sales[‘Amount’])
完成后,可以通过返回可视化效果选项卡并选择表视觉对象来创建表。 您想要按年和月查看总订单数和销售额,因此只希望包括日期表中的“Year”和“Month”列、OrderQty 列以及 #TotalSales 度量值。 当您了解层次结构后,还可以生成一个允许您从年向下钻取到月的层次结构。 对于本示例,您可以并排查看它们。 现在,您已成功创建具有公用日期表的视觉对象。
使用维度
生成星型架构时,你将拥有维度表和事实数据表。 事实数据表包含有关事件的信息,例如销售订单、发货日期、经销商和供应商。 维度表存储有关业务实体(例如产品或时间)的详细信息,并通过关系连接回事实数据表。
可以将层次结构用作帮助在维度表中查找详细信息的源。 这些层次结构通过数据中的自然分段形成。 例如,可以具有将日期按年、月、周和天分段的日期层次结构。 层次结构很有用,因为它们使你可以向下钻取数据的详细信息,而不是仅查看粗略的数据。
层次结构
生成视觉对象时,Power BI 会自动输入日期类型的值作为层次结构(如果该表尚未标记为日期表)。
在前面的“日期”列中,日期按年、季度、月和日以详细程度越来越高的方式显示。 你也可以手动创建层次结构。
例如,考虑要创建“按类别和子类别划分总销售额”堆积条形图的情况。 可以通过在“Product”表中为类别和子类别创建层次结构来完成此任务。 若要创建层次结构,请转到 Power BI 上的“字段”窗格,然后右键单击要用于层次结构的列。 选择“新建层次结构”,如下图所示。
接下来,将子类别列拖放到创建的新层次结构中。 此列将作为层次结构上的子级添加。
现在,可以通过在“可视化效果”窗格中选择堆积条形图来生成视觉对象。 在“轴”字段中添加“类别名称层次结构”,在“值”字段中添加“Total Sales”。
你可以向下钻取视觉对象,以查看“类别”和“子类别”,具体取决于要查看的内容。 层次结构使你可以在单个视图中查看级别递增的数据。
现在,你已了解层次结构,接下来可以更进一步,查看父子层次结构及其在事实数据表和维度表之间的多个关系中的角色。
父子层次结构
在下面的示例中,数据库中有一个 Employee 表,该表告知有关员工、其经理和其 ID 的重要信息。 查看此表时,你会注意到“Roy F”在“Manager”列中重复出现多次。 如图所示,多个员工可以拥有相同的经理,这指示经理和员工之间的层次结构。
“Manager”列确定层次结构,因此是父级,“子级”则是员工。 在本示例中,你希望能够看到此层次结构的所有级别。 Power BI 不会默认显示层次结构的所有级别,因此,你负责确保自己可以看到此层次结构的所有级别或“平展”它,以便可以看到更多数据粒度。
平展父子层次结构
基于顶级父级查看多个子级的过程称为“平展层次结构”。 在此过程中,你将在一个表中创建多个列,以在同一记录中显示父级到子级的层次结构路径。 你将使用 PATH()(一个简单的 DAX 函数,该函数为每个员工返回管理路径的文本版本)和 PATHITEM()(将此路径分隔为每个管理层次结构级别)。 在表上,转到“建模”选项卡,然后选择“新建列”。 在显示的公式栏中,输入以下函数,该函数将创建员工和经理之间的文本路径。 此操作将在 DAX 中创建一个计算列。
Path = PATH(Employee[Employee ID], Employee[Manager ID])
员工和经理之间的完整路径在新列中显示,如以下屏幕截图所示。
如果查看 Roger M,则 ID 的路径为“1010 | 1011 | 1013”,这意味着 Roger M (ID 1013) 的上一个级别是他的经理 Pam H (ID 1011),而后者的上一个级别是她的经理 Roy F (ID 1010)。 在此行中,Roger M 在层次结构的底部(位于子级),而 Roy F 在层次结构的顶部(位于父级)。 将为每个员工创建此路径。 若要平展层次结构,可以使用 PATHITEM 函数分隔每个级别。
若要分别查看层次结构的全部三个级别,可以通过输入以下公式,以与之前相同的方式创建四个列。 将使用 PATHITEM 函数来检索位于层次结构相应级别中的值。
级别 1 = PATHITEM(Employee[Path],1)
级别 2 = PATHITEM(Employee[Path],2)
级别 3 = PATHITEM(Employee[Path],3)
图片
完成后,请注意,现在拥有表中层次结构的每个级别。 Roy F 在层次结构的顶部,当你浏览级别 2-3 时,请注意,经理和员工相互映射。
现在,可以像之前那样在“字段”窗格上创建层次结构。 右键单击“级别 1”,因为这是第一个层次结构级别,然后选择“新建层次结构”。然后,将“级别 2”和“级别 3”拖放到此层次结构中。
现在,你已成功平展层次结构,以便可以查看各个级别。
之前,你考虑了与事实数据表仅具有一个关系的维度。 但是,确实会发生维度表将与事实数据表具有多个关系的情况。
角色扮演维度
角色扮演维度具有与事实数据表的多个有效关系,这意味着同一维度可用于筛选数据的多个列或表。 因此,可以根据需要检索的信息来以不同方式筛选数据。 此主题很复杂,因此仅在本部分中介绍。 使用角色扮演维度需要复杂的 DAX 函数,这将在稍后的部分中进行讨论。
定义数据粒度
数据粒度指数据中表示的详细信息,这意味着数据粒度越多,数据中的详细信息级别就越高。
对于所有数据分析师,数据粒度都是一个重要主题,而无论你使用的是何种 Power BI 工具。 定义正确的数据粒度可能对 Power BI 报表和视觉对象的性能及可用性产生重大影响。
定义数据粒度
考虑你的公司管理 1000 辆冷藏半挂车的方案。 每隔几分钟,每辆车都会使用 Microsoft Azure IoT 应用程序记录其当前温度。 此温度对你的组织而言很重要,因为如果制冷出现故障,可能让整车货物变坏,并导致数千美元的损失。 卡车如此之多,传感器也如此之多,每天都会生成大量数据。 你的报表用户不想通过仔细查看大量记录来查找他们特别感兴趣的记录。
如何更改数据的粒度以使语义模型更有用?
在此方案中,你可能希望通过使用每辆卡车的每日平均值来导入数据。 这种方法会将数据库中的记录减少到每天每辆车一条记录。 如果认为该方法足以跟踪成本和错误,则可以使用该数据粒度。 或者,你可以选择最后记录的温度,也可以只导入高于或低于正常温度范围的记录。 其中任何一种方法都会减少导入的记录总数,同时仍然提供全面而有价值的数据。
对于不同的方案,可以确定每周、每月或每季度进行定义的数据粒度。 一般而言,使用的记录越少,报表和视觉对象的运行速度就越快。 此方法可提高整个语义模型的刷新率,这可能意味着可以更频繁地刷新。
但是,该方法有一个缺点。 如果用户想深入了解每个事务,汇总粒度时将阻止他们执行此操作,这可能会对用户体验产生负面影响。 与报表用户协商数据粒度级别很重要,这样他们才能了解这些选择的含义。
更改数据粒度以在两个表之间生成关系
在 Power BI 中的表之间生成关系时,数据粒度也会产生影响。
例如,假设你正在为 Tailwind Traders 的销售团队生成报表。 需要使用“Calendar”、“Sales”和“Budget”表生成一段时间内的总销售额和预算的矩阵。 你会注意到,“Sales”表的基于时间的详细信息的最低级别为按天,例如 5/1/2020、6/7/2020 和 6/18/2020。 “Budget”表仅为月级别,例如,预算数据为 2020/5 和 2020/6。 这些表中有不同粒度,需要先对它们进行调节,然后才能在表之间建立关系。
下图显示当前语义模型。
如上图所示,“Budget”和“Calendar”之间的关系缺失。 因此,需要先创建此关系,然后才能生成视觉对象。 请注意,如果将“Calendar”表中的“Year”和“Month”列转换为新列,并在“Budget”表中进行相同的转换,则可以匹配“Calendar”表中“Date”列的格式。 然后,可以在两列之间建立关系。 要完成此任务,需要连接“Year”和“Month”列,然后更改格式。
在功能区上选择“转换数据”。 在“应用的步骤”的右窗格中,右键单击最后一步,然后选择“在以下项后面插入步骤”。
在主页功能区上的“添加列”下,选择“自定义列”。 输入以下公式,将“Year”和“Month”列连接,然后在列名之间添加短划线。
Column = Table.AddColumn(#"Renamed Columns", "Custom", each [Year] & "-" &[Month])
将数据类型更改为“日期”,然后重命名该列。 “Budget”表应类似于下图。
现在,可以在“Budget”和“Calendar”表之间创建关系。
创建表之间的关系
Power BI 会自动检测关系,但也可以转到“管理关系”>“新建”,然后在“Date”列上创建关系。 关系应类似于下图。
完成此任务后,可确保不同表之间的粒度相同。 现在,需要创建 DAX 度量值来计算“Total Sales”和“BudgetAmount”。 转到 Power BI Desktop 上的“数据”窗格,选择“新建度量值”,然后使用以下公式创建两个度量值:
TotalSales = SUM(Sales[Total Sales])
BudgetAmount = SUM (Budget[BudgetAmount])
在“可视化效果”窗格中选择表视觉对象,然后在“值”字段中输入这些度量值和“Date”。 现在,你已完成生成一段时间内的总销售额和预算矩阵的目标。
使用关系和基数
与其他数据库管理系统不同的是,Power BI 中的关系具有方向性 这一概念。 这种方向性在多个表之间筛选数据时起着重要作用。 加载数据时,Power BI 通过匹配列名自动查找数据中存在的关系。 也可以使用管理关系来手动编辑这些选项。
例如,您从 Sales 数据库中检索了许多表,下图就是您的语义模型的一个示例。 Power BI 已经自动检测到几种关系,但您无法辨别它们的含义。 您希望确保这些关系能够准确反映数据中存在的关系。
关系 以下是您可以在 Power BI 中找到的不同类型的关系。
多对一 (*:1) 或一对多 (1: *) 关系
描述一种关系,在这种关系中,一列中某个值的许多实例仅与另一列中的一个唯一对应实例相关。
描述事实表和维度表之间的方向性。
是最常见的方向性类型,也是当您自动创建关系时 Power BI 的默认类型。
一对多关系的一个示例是“CountryName”表和“Territory”表之间的关系,其中可以有多个与一个唯一国家/地区相关联的区域。
一对一 (1:1) 关系:
描述一种关系,在这种关系中,两个表之间只共有某个值的一个实例。
两个表中都需要唯一值。
不建议使用,因为此关系会存储冗余信息,并表明模型设计不正确。 更好的做法是合并表。
一对一关系的一个示例是在两个不同的表中存储产品和产品 ID 的情况。 创建一对一关系是不必要的做法,应该将这两个表合并。
多对多关系 (.) 关系:
描述两个表之间共有许多值的关系。
关系中的任一表中都不需要唯一值。
不建议使用,缺少唯一值会引入多义性,用户可能不知道哪一列值指代哪些对象。
例如,下图显示“Sales”表和“Order”表之间的 OrderDate 列上的多对多关系,因为多笔销售可以有多个订单与其关联。 由于两个表的订单日期可以相同,因此引入了多义性。
交叉筛选器方向
可以在关系的一侧或两侧筛选数据。
使用单个交叉筛选方向:
关系中只有一个表可用于筛选数据。 例如,表 1 可以按表 2 进行筛选,但表 2 不能按表 1 进行筛选。 对于一对多或多对一关系,交叉筛选方向将从“一”侧开始,这意味着筛选将发生在具有多个值的表中。
使用两个交叉筛选方向或双向交叉筛选:
关系中的一个表可用于筛选另一个表。 例如,可以通过事实表筛选维度表,也可以通过维度表筛选事实表。
将双向交叉筛选用于多对多关系时,性能可能会降低。
关于双向交叉筛选的提示:除非您完全了解这样做的后果,否则不应启用双向交叉筛选关系。 启用它可能导致多义性、过度采样、意外结果以及性能降低风险。
基数和交叉筛选方向
对于一对一关系,唯一可用的选项是双向交叉筛选。 可以在此关系的任一侧对数据进行筛选,并生成一个含义明确的非重复值。 例如,可以对一个产品 ID 进行筛选并返回一个产品,也可以对一个产品进行筛选并返回一个产品 ID。
对于多对多关系,可以通过使用双向交叉筛选选择在单个方向或两个方向上进行筛选。 多对多关系会放大与双向交叉筛选相关联的多义性,因为不同表之间将存在多个路径。 如果您创建度量值、计算或筛选器,则可能会在筛选数据时发生意外后果,并且根据 Power BI 引擎在应用筛选器时选择的关系,最终结果可能会有所不同。 双向关系也是如此,这正是为什么在使用它们时要格外小心的原因。
出于此原因,多对多关系和/或双向关系很复杂。 除非确定数据在聚合后会发生的变化,否则具有多个筛选方向的这类开放式关系可在数据中引入多个路径。
创建多对多关系
假设有这样一个场景,您负责生成视觉对象来检查客户和帐户预算。 您可以在同一个单位拥有多个客户,也可以为同一个客户设置多个单位,因此需要创建多对多关系。
要创建此关系,请转到管理关系>新建。 在显示的窗口中,在“CustomerTable”和“AccountTable”的 Customer ID 列之间创建关系。 关系设置为多对多,筛选器类型为双向。 您将立即收到警告,提示仅在预期这两个列都不具有唯一值的情况下才应使用这种类型的关系,因为可能会获得非预期值。 由于想要在两个方向进行筛选,请选择双向交叉筛选。
选择确定。 现在,您已成功创建多对多关系。
解决建模挑战
数据建模指建立和维护关系,以便可以按照业务所需的形式有效地可视化数据。 创建这些关系时,可能会遇到的常见陷阱是循环关系。
例如,你正在为销售团队开发报表,并正在检查表之间的关系。 在设计欠佳的语义模型中,表 1 与表 2 中的某个列具有多对一关系,但表 2 与表 3 具有一对多关系,而表 3 与表 1 具有其自己的关系。 这种关系网很难管理,并且会让生成视觉对象成为艰巨任务,因为不再清楚存在哪些关系。 因此,你能够识别循环关系,以便数据可用,这一点很重要。
关系依赖关系
若要了解循环关系,首先需要了解依赖关系。
例如,假设“Sales”表中有以下计算列“Total”。
Sales[‘TotalCost'] = Sales[‘Quantity’] * Sales[‘Price’]
“TotalCost”取决于“Quantity”和“Price”,因此,如果数量或价格发生变化,“TotalCost”也会发生变化。 本示例概述某个列在其他列上的依赖关系,但你也可以在度量值、表和关系之间具有依赖关系。
考虑“dSalesPerson”、“fSales”和“dCustomer”之间的以下关系。 “dCustomer”中的更改会导致“fSales”发生更改,从而导致“dSalesPerson”发生更改。这些类型的依赖关系可以存在于关系中。
欢迎留言讨论