Power BI之DAX神功:第4卷第6回 理解DAX中的物理关系
一、VertiPaq和DirectQuery存储模式
跟我学过Access基础篇的小伙伴,一定知道,数据库中可以导入表,也可以链接表。
// 如果你在火力全开第1集没听我的,没去学习且无基础,那也就证明你不懂数据库基本原理,虽然DAX原理有些地方有争议性,是各抒己见的。但是很多不懂数据库基本原理的人,直接学习DAX原理,甚至讲出DAX原理,能犯下很多低级错误,而且造成这些错误的原理与DAX毫无关系,因为知识是相通的。
VertiPaq:就类似import导入表,简单的说就是将表中的数据导入到PowerBI。(我这只是简单的说)
DirectQuery:就类似链接表,数据还在数据源中,这里只是个影像。链接表就好比看电视,比如说你不喜欢这个明星,你把电视砸了,明天你买台新电视,那个明星又出现了。
当然,VertiPaq和DirectQuery都是有原理而且还有复合模型的存储模式,《权威指南》第17章有详细讲解,这牵扯优化知识,我们会在不久将来《DAX神功》DLC优化篇详细讲这部分的原理知识。
从2020.3~2021.12 我所有课程讲的都是VertiPaq导入表。
截止2021年10月2日,微软官网发布的PowerBI数据源,我摘抄了几个常用源:

暂时只有SQL Server支持DirectQuery,但是这个数据是实时变化的,也许你看到这篇文章时,微软做了调整,均实现了DirectQuery也说不定。因为Access都能以链接表方式连接Excel、TXT、CSV、Access等文件,PowerBI未来可期(也可能永远都不支持)。

Ps: SQL Server也可以导入,有些人会问硬盘存不下怎么办?SQL的查询语句是干嘛的?14亿中国人,我想分析某一个省的平均寿命,我应该到民政局调取这个省的记录,而不是取14亿中国人的记录。但是,你确实要分析14亿中国人的平均寿命,这时使用导入可能不合适了,DirectQuery会更快一些。DAX优化既有对导入表的优化,也有对DirectQuery的优化。我们在不久将来的DLC中再做详解。
在很多地方都可以看到表的存储模式,例如在模型中鼠标悬停在红卷之内:

友情提示:如果一张表是VertiPaq模式、另一张表是DirectQuery模式,这两张表进行连线后必然影响查询速度。在同一模式下就相当于是国内服务器之间访问,不同模式下,就相当于是国内服务器访问国外服务器。在建立关系时尽量避开不同模式下的连线。
二、强关系、弱关系直接决定扩展表
确定是强关系还是弱关系,要看两点:
<1> 主键 <2> 存储模式
简单的说就一句话:有主键且在同一存储模式下就是强关系,否则弱关系。
那强关系与弱关系有什么意义呢?弱关系扩展表就是自己原生列,不会有相关列!

Access基础篇我们讲过:主键要求:不为空,不重复,不易发生改变。
外键是相对存在的!什么叫相对,比如说A1单元格右边的单元格、你前面的同学,比孙兴华年龄小的人。说白了外键就是相对主键存在的。
大家都知道,三种表关系:1对1、1对多、多对多,我们分别来看一下他们是什么关系

如上图所示,一对一关系,左表学号(主键)不为空不重复,连接右表学号(外键),只要两张表存储模式相同,就是强关系,否则是弱关系。
例如左表是导入表VertiPaq(假设是导入的Excel),右表是链接表DirectQuery(假设是链接SQL Server),两张表是弱关系,左右表的扩展表都是自己本身,不会向一端延申。
否则如果两张表都来自同一存储模式,那就是强关系,左表扩展表包含右表所有列,右表扩展表也包含左表所有列。因为扩展表原理是向一端延伸。

如上图所示,一对多关系左表有主键,如果两表在同一存储模式下就是强关系,右表向左表(一端)扩展,但是左表不能向右表(多端)扩展。反之,如果两表在不同存储模式下,就是弱关系,弱关系下扩展表就是自己本身,不能向一端表延伸。

多对多关系,没有主键,因为主键要求不为空不重复。无论是否在同一存储模式下,都是弱关系,扩展表都是自己本身。因为我们在讲扩展表原理时提到,扩展表只能向一端扩展,其原理是因为多对多关系没有主键。
Ps: 有些人将左表学号说成主键,那是不对的。
三、因不满足实时参照完整性产生的空行只会出现在强关系中
《DAX神功》第1卷第9回 我们讲到了因为不满足实时参照完整性,比如一端商品表中都是华为手机,但是多端销售表中出现了小米手机,这就是不满足实时参照完整性,我们在使用VALUES或ALL等函数时会产生空行。但是这只限于强关系的情况下。
怎么确定是强关系:<1> 有主键 <2> 在同一存储模式下
当时我们在一对多关系下证明了,我跟大家说,一对一关系应该合并成一张表。如果你不合并,就是用原理,那么空行这件事,只看是不是强关系。下面我们用一对一来验证:

如上图所示,一对一关系有主键,同一存储模式,强关系。
我们分别使用DISTINCT和VALUES测试空行问题:
返回结果:

总结:只要满足强关系,当不满足实时参照完整性时,使用VALUES和ALL等就会产生空行。
四、表关系之箭头方向
【1】一对一关系,必须是双向,你改不了单向箭头
但是可以使用CROSSFILTER停用关系

【2】一对多关系,默认是单向箭头,从一端指向多端。你可以手工改成双向箭头。
但是不推荐这么做,详见《DAX神功》第1卷第2回
原理:虽然你两张表之间保持了一对多关系,但是一旦你使用了双向箭头,这一条线路上,可能就形成了多对多关系,这样就会出现您想不到的结果。如下图所示:因为改变了表2与表3的箭头方向,线路2中出现了多对多关系。

【3】多对多关系,可以选择单向箭头或双向箭头
在建立关系时,会弹出下面对话框,让你选择是哪张表筛选哪张表或者两个表双向筛选。

在这点上就有别于一对多关系,一对多关系使用单向箭头时必须是一端筛选多端,但是在多对多关系中,由于两张表都是多端,需要你手工指定谁筛选谁,或者是相互筛选。
五、多表确定强弱关系

表1与表2是强关系,因为有主键且同一模式。
表2与表3是弱关系,虽然有主键但不在同一模式。

《孙兴华讲PowerBI火力全开》PowerBI必学课程
https://www.bilibili.com/video/BV1qa4y1H7wp
《DAX神功》文字版合集:
https://www.bilibili.com/read/readlist/rl442274
《DAX神功》视频版合集:
https://www.bilibili.com/video/BV1YE411E7p3
《DAX神功番外篇》文字版合集:
https://www.bilibili.com/read/readlist/rl478271
PowerBI(DAX函数)、PowerQuery(M函数)、Python办公自动化、Python爬虫、Python数据分析、ExcelVBA、WordVBA、AccessVBA、MySQL等等