【数据模型系列_04】笛卡尔积 vs FineBI主题模型的N:N

楼主
我是社区第525317位番薯,欢迎点我头像关注我哦~

BI的数据模型就是通过关系相互连接的一组表。这组表里面有事实表、维度表,通过关系把他们连在一起。

两个不同表之间存在以下3种关系类型:一对一(1 : 1),一对多(1 : N),多对多(N : N)。

1:1 & 1:N很容易理解,但N:N就复杂多了,理解起来没那么直观。

N:N关系的基础理论来自于集合论。在集合论中,可以将实体看作集合,实体之间的关系可以看作集合之间的关系。N:N关系可以通过两个集合之间的笛卡尔积来表示。

笛卡尔积:

指由两个集合中的每个元素组成的每一对有序元素构成的集合。例如,S={1, 2},T={a, b},则它们的笛卡尔积为{(1,a),(1,b),(2,a),(2,b)}。这个集合中每个元素都是一个有序对,表示S和T之间的所有可能的对应关系。因此,通过两个集合之间的笛卡尔积,可以表示两个集合之间的多对多关系。

在数据建模中,N:N关系的建模,我们天然的认为会发生数据膨胀,导致多条重复数据出现,最终会影响统计结果。这么认为其实没错,SQL中多对多的JOIN连接,确实会导致数据膨胀。为了避免这个问题,常规的做法就是使用桥表,将N:N转化为两个1:N后再进行join连接,这个处理方法也通用于BI的N:N关系处理。

 

23年4月份,FineBI 发布了“主题模型”功能,除了让数据准备更简单、多表分析更高效外,还能更加友好的支持 N:N 计算场景。可以说是大大的减少了N:N场景的计算准备工作量,但随之而来的就是高度抽象的合并&计算逻辑,大大的增加了理解成本。

能够深度理解主题模型计算原理的人可能会使用后发出惊呼:wow,太棒了!

不能够理解主题模型计算原理的人,可能就会“想用却不敢用”,因为搞不清楚用了之后哪里会暴雷。

所以今天想拆解下FineBI的N:N计算步骤,把抽象的计算过程具体化一些,便于大家理解。

我们通过一个案例来看: 

需求背景:

BYD是一家日用品仓储超市,主要经营纸巾、洗衣液等相关产品,每年2月、6月、7月和11月是超市的固定大促月,基本可以享受全年最低价,另外,为了方便顾客,超市提供一项寄存服务,比如,7月付款买10箱纸巾(预售单),后续用到的月份再来提货,用几箱提货几箱即可,也允许一笔订单提多个预售单的货(提货单),对那些家中存在空间有限的顾客来说,这是一项完美的服务。所以每到大促月,很多顾客会选择寄存。

 

Tom是这家连锁超市的运营经理,近期他在分析经营数据的时候发现,超市预售的业绩越来越高,就想了解下预售提货的数据,所以向数据部提了如下需求:

1、2023年超市每月的预售件数、提货件数是多少,还有多少未提?

2、哪些会员还未提货完成,分别还有多少未提件数?

 

 

这个需求听起来很简单,但如果深入了解业务过程,你就不会认为简单了。

最大的障碍点在于:超市允许一笔订单多次提货,也允许一笔订单提多个预售单的货。

什么意思呢?翻译成关系就是:

一笔预售订单多次提货 ,即1笔预售单,对应多个提货单(1:N),这个简单

一笔提货单提多个预售单的货 即 1笔提货单,对应多个预售单(1:N),这个简单

但是,关键是但是,算未提得合在一起看,然后。。。就成了N:N。就不简单了。

不过幸好,FineBI6.0的主题模型支持N:N,我们来看看这个需求怎么通过主题模型实现~

FineBI N:N

1

Part.1

数据导入

弹出【选择数据】框,将Excel数据导入。

数据如下,

预售单:

提货单:

P.S.为了便于理解,数据做了简化处理,但请注意预售单的「订单ID」是存在重复的,提货单表内的「关联预售单号」也是存在重复的。

 

2

Part.2

模型构建

模型视图内,关系选择N:N,连接依据选用预售表的「订单ID」以及提货表的「关联预售单号」

 

3

Part.3

指标计算

1. 计算每月的未提数量,添加计算字段,未提数量 = SUM_AGG(销售数量)-SUM_AGG(提货数量)

 

2. 然后将预售表的「订单日期」拖入维度栏,将预售表的「销售数量」、提货表的「提货数量」、上一步的计算字段「未提数量拖入指标栏即可。

 

3. ok了,如此简单,算对了没有?敢不敢用?

回到Part1的数据仔细看看,算一下。发现没错!

怎么样?惊喜么?

 

4. 继续算每个会员还有多少未提。

继续验证下数据对不对,可以放大图片,口算下结果。

完美!!

 

5. 到这里,Tom的这个需求就完成了,一切都很完美。

然而,当我们想进一步知道每个会员是什么产品没提货的时候,异常出现了。下图红框的部分,客户实际上是没有提货数据的,然の,此处却有计数。

为什么会有计数?

答:这个模型的合并依据是预售表的「订单ID」以及提货表的「关联预售单号」,而且分析维度是站在预售表的角度看的。模型在用连接字段合并的时候,优先保证预售表的数据完整,而后开始调用「订单ID」这个连接条件,如果出现一笔订单中多个单品,数据就会出错。比如下图:

 

6. 怎么办呢?

答:联合关联,多字段合为一个字段来唯一标识一行记录。就是把合并依据从预售表的「订单ID」以及提货表的「关联预售单号」,调整为预售表的「订单ID+产品ID」以及提货表的「关联预售单号+ID」,在数据处理阶段新增列合并订单IDID即可。

合并界面如下:

模型的连接关系字段调整为合并后的字段

计算结果:

 

一切又回到了完美!

N:N计算步骤拆解

为了方便理解,我们拆解下计算步骤,把抽象的计算过程稍微具象化一点。依每月未提件数的组件举例:

每月的预售数量、提货数量、未提数量结果如下

主题模型的计算过程:

1. 识别分析字段和关联字段

此例中分析字段为预售表中的「年月」

关联字段为预售表的「订单ID」、提货表的「关联预售单号」。

2. 计算预售表中每月的预售数量,分析维度为「年月」、「订单ID」,聚合结果为SUM(预售数量)

 

3. 计算提货表中每月的提货数量,分析维度为「关联预售单号」,聚合结果为SUM(提货数量)

 

4. 依据预售表的「订单ID」、提货表的「关联预售单号」关联字段合并

 

5. 依据「年月」进行聚合

比如,2月有两笔订单,计算这两笔订单的合计预售件数,提货件数。其它月份依次类推。

 

小结

 

FineBI的主题模型合并逻辑:

  • 只有分析字段和关联字段参与模型的合并计算

  • 先聚合,再合并

如果类比到SQL的JOIN连接,这个计算过程就是通过两个子查询得到的聚合的子查询 JOIN 聚合的子查询b。

相比较来说,FineBI通过主题模型实现还更便捷呢!

 

拿例子去练手吧,多换几个分析字段观察下计算结果。会对主题模型的合并逻辑理解的更深刻。

 

好了,今天就酱紫,回见~

分享扩散:
参与人数 +1 F币 +60 理由
苏瑞 + 60 【2024原创内容激励奖励】给你32个赞!

查看全部评分

沙发
发表于 2024-6-28 10:13:39
您好,此篇文章内容是基于FineBI数据模型系列下的主题模型进行介绍,从需求背景入手,旨在一步步通过主题模型实现目标,整个实现流程十分明晰,使得复杂的流程变得易于理解,体现了作者深厚的专业素养和扎实的基本功。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

返回顶部 返回列表