Power BI:保持数据建模原则并处理多对多关系

现在在哪里

Power BI的除了可以进行漂亮的可视化,更多内容隐藏在表面下的建模本身。

Power BI 数据建模:

  • 鼠标拖拽形成关系
  • 处理筛选器方向
  • 处理关系的激活与非激活
  • 理解维度建模与数据仓库
  • 处理多对多关系

Power BI 深度数据建模:

  • 维度建模与自由建模(不受维度和事实的限制)
  • 用DAX建立虚拟关系(集合,contains,treatas)
  • 用DAX表函数建立新表
  • 扩展表原理
  • 性能优化
  • 行级别安全性及传递

本次关注其中一个问题:多对多关系。对此,SQLBI的大师已经给出近乎终极全面的参考,可以参考阅读:

这里更多从简单的角度来看Power BI中处理多对多关系的方法。

如何看懂Power BI的数据模型

对于普通用户来说,没有专业的数据库背景,我们可以这样来理解Power BI中的数据模型:

作为一个最佳实践:请确保Power BI模型中并不出现两个箭头的连线,下面的图是应该避免的:

筛选器的方向指导分析的思路

如果想知道各省分别有多少销售额,就是从地区来筛选订单;而如果想知道单价大于1000的订单都卖到过哪些地区则从订单来筛选地区。

可以这么说,Power BI的双向筛选器是给真正知道他在做什么的分析师用的,在默认状态下务必使用单向筛选器,也就是将筛选器方向全部改为单向。

往往针对一个特定的主题加载相关的数据,例如在上例中要分析销售情况,是不需要加载库存情况数据的。在分析时(在Power BI画布上拖拽时)可以遵循下面的思路:

始终考虑 从什么角度来观察什么问题。

在这个案例中:

筛选器的方向通常指明了观察问题的方向。也就是:

  • 从地区的角度看销售额大小
  • 从客户的行业角度看销售额大小
  • 从产品的类别角度看销售额大小
  • 从特定年份不同月份角度看销售额大小

除了看销售额大小,还可以看:利润,利润率,同比利润率等等。通过这些套路,可以完成对数据的初步探索

如果注意观察思维的语义,不难发现:

  • 思考的角度(通常称为维度),放在Power BI的坐标轴字段。
  • 思考的问题(通常称为度量值),是一个能用数值表示的量,放在Power BI的值字段。

Power BI提供了对度量值的默认算法,包括:求和,计数,非重复计数,求平均等。而最佳实践是不依赖Power BI提供的默认计算,而是自己显式地定义度量值,哪怕仅仅是求和。例如:

  • 总销售额 = SUM( 订单[销售额] )
  • 总利润率 = SUM( 订单[利润] ) / SUM( 订单[销售额] )

总利润率是Power BI无法默认实现的,必须由设计师显式定义。

Power BI 中的关系

Power BI 中的关系有以下这几种可能:

类型 关系 交叉筛选器方向
1 多对一 单一
2 多对一 两个
3 一对多 单一
4 一对多 两个
5 一对一 两个

如果知道正在做什么,那不需要遵守下面的约定,如果不知道正在做什么,请遵守:

  • 保持关系仅限于:多对一或一对多。
  • 保持筛选器方向仅限于:单一。

由于多对一和一对多的意思是一样的,所以统一叫做一对多。此时,我们的模型就仅仅存在一种模型中的关系那就是:保持单一筛选的一对多关系

这样就将一团复杂简化到只有一条原则的状况,也就实现了文初的模型:

保持这样的简单关系就像保持简单的人际关系一样,生活和模型都本应简单。在此基础上,模型就像生活偶尔会出现复杂点的关系,怎么办?

什么是多对多关系

说:有猫和狗,有肉和奶。问:猫吃了什么?狗吃了什么?肉都谁吃的?奶都谁喝的?

这就是典型的多对多关系。它表示了事物之间的一种可能关系。如果这个问题不够触动的话,可能更熟悉的是:

  • 不同类产品卖给过多少客户?
  • 不同行业职业客户买过多少种产品?
  • 不同省份提供过多少种产品?
  • 不同类产品从多少个城市进过货?

解决多对多问题的第一步是识别多对多问题,例如:一种产品可能卖发给过多个客户,一个客户可能买过多种产品。因此,这种产品与客户的购买关系就是多对多的。

在Power BI中处理多对多关系

首先,在Power BI中并不直接支持多对多关系;根据上述的原则:保持单一筛选的一对多关系也无法反应这样关系。

这时需要一个,桥是一种形象的称呼。可以这样理解:产品客户 之间无法直接建立多对多的关系,但可以通过一个中间表作为桥一样(称为桥表),来实现产品客户 之间的连接。

例如:

可以看出:

  • 进货单正是货源地与产品之间的桥;
  • 订单正是产品与客户之间的桥。

它们通常有这样的特点:

  • 产品,客户,货源地表示一种实体(现实中存在的物体)。
  • 订单(以及订货单)表示一种谁(客户实体)在什么时间与谁(产品实体)发生关系的记录。

也就是说:实体是通过表来表示的;实体之间发生关系会形成记录,也用表来表示。从这个意义上,订单已经不再强调它按维度建模理论中的事实表角色,而是强调它连接了两个实体作为关系记录而存在。

在Power BI中实现基于多对多关系的计算

在Power BI中实现回答上述问题,可以常规通度量值加入桥表作为筛选器处理,:

客户数 = CALCULATE( COUNTROWS( 'tb客户' ) )
客户数(桥:订单) = CALCULATE( COUNTROWS( 'tb客户' ) , 'tb订单' )

效果:

可以看出常规度量值的计算是无效的,原因在于常规度量值只能满足按照箭头的方向传递。而加入了桥表作为筛选器就将本来断开的两个实体连接起来,使得原度量值恢复了计算能力

可以看出只需要按 CALCULATE( 常规度量值 , ) 的形式来改写常规度量值,就可以实现基于多对多关系的计算。以上述为例,它表明了这样一种意义: 基于产品与客户的关系记录 订单表 来看,按产品的属性:类别,分别计算客户数度量值是多少。

值得强调的是,这仍然是一个模式(套路):

  1. 基于实体与实体的关系记录
  2. 按某实体的属性作为观察出发点
  3. 计算与另一实体有关的度量值

这三条几乎严格地给出了这个套路,这要遇到类似问题,都可以这样套用。

使用套路处理更多案例

为了加深对这个套路的理解,下面处理更多例子来说明。

不同行业职业客户买过多少种产品

请结合上述关系图理解:

产品数 = CALCULATE( COUNTROWS( 'tb产品' ) )
产品数(桥:订单) = CALCULATE( COUNTROWS( 'tb产品' ) , 'tb订单' )

效果:

不同省份提供过多少种产品

请结合上述关系图理解:

产品数 = CALCULATE( COUNTROWS( 'tb产品' ) )
产品数(桥:进货单) = CALCULATE( COUNTROWS( 'tb产品' ) , 'tb进货单' )

效果:

注意:这里用到了另一个桥表进货单来连接地区和产品。

不同类产品从多少个城市进过货

请结合上述关系图理解:

货源地数 = CALCULATE( COUNTROWS( 'tb货源地' ) )
货源地数(桥:进货单) = CALCULATE( COUNTROWS( 'tb货源地' ) , 'tb进货单' )

效果:

至此,多对多关系已经可以处理。

跨越关系的多对多关系

现实中除了存在两个实体的多对多关系,还可能存在更加隐蔽和复杂的多对多关系,为了方便连贯思考,再次使用上述的模型如下:

可能存在这样的问题:不同货源地省份的供货都销售给多少客户?

这是在研究 货源地最终客户 的关系。这就像一个跨越崇山峻岭的多对多关系,但正确的处理方法是不变的:常规通度量值加入桥表作为筛选器处理。

问题来了, 货源地最终客户 之间没有桥怎么办,其实不是没有桥,而是有“两座桥”。一座桥用来连接货源地和产品,叫:进货单;另一座桥用来连接产品和客户,叫:订单。

所以:

客户数 = CALCULATE( COUNTROWS( 'tb客户' ) )
客户数(桥:订单) = CALCULATE( COUNTROWS( 'tb客户' ) , 'tb订单' )
客户数(桥:订单 进货单) = CALCULATE( COUNTROWS( 'tb客户' ) , CALCULATETABLE( 'tb订单' , 'tb进货单' ) )

效果:

也就是说,把多个桥表装到一起作为筛选器就可以处理关联式的多对多关系。

总结

在Power BI的数据建模中:

  • 如果不知道正在做什么,请遵守:保持单一筛选方向的一对多关系
  • 筛选的方向提示了从...角度去看...问题。
  • 度量值M2M = CALCULATE(度量值,桥表)。
  • 度量值M2M2M = CALCULATE(度量值,CALCULATETABLE(桥表1,桥表2))。
  • 桥表是记录了实体与实体关系的记录表,通常可能是事实表。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,219评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,363评论 1 293
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,933评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,020评论 0 206
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,400评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,640评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,896评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,597评论 0 199
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,327评论 1 244
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,581评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,072评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,399评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,054评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,083评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,849评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,672评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,585评论 2 270

推荐阅读更多精彩内容