数据蒋堂 | JOIN延伸 - 维度概念

谈到数据分析时常常会用到维度这个词,针对数据立方体的钻取、旋转、切片等操作都是围绕维度进行的,几乎所有的数据分析人员都知道并会运用这个术语,但要问及它的定义,却几乎没有人能给出来。

通俗来讲,我们把用来分类的属性(字段)称为维度,比如地区、年度、产品类型等;而另外一些用于聚合运算的属性则称为测度,比如销售额、产量、考试成绩等。维度不能做聚合运算,比如计算地区合计是没有意义的;测度则不能用于分类,比如按销售额分类也没什么业务意义。我们通常就是用是否”可用于分类“来判定一个属性是不是维度,但这其实只是对于维度性质的描述,并不能作为定义。

我们基于关系数据库来讨论这个问题,先简单回顾一下基本概念。

设有一个关系数据库,其中有若干数据表,表的数据结构由字段构成,表的数据由记录构成。

数据表的某些字段被指定为主键,需要满足这样的条件:表中所有记录在这些字段上的取值是互不相同的。也就是说,可以用主键值来确定唯一相应的记录。数据表可以没有主键,但有只能有一套。构成主键的字段称为主键字段。

每个数据表可以有多套外键,外键也是该数据表的某些字段,其取值总是在另一个表(可能是本表)的主键取值范围内。这里的另一个表被称为外键指向表,简称外键表,构成外键的字段被称为外键字段

现在,我们定义:在关系数据库中,不是外键字段的主键字段被称为维度,维度所在的表称为维表,维度可以用维表的主键字段来标识。顺便地,我们定义即不是主键字段也不是外键字段的字段为测度。从这个定义上看,显然不可能某个字段既是维度又是测度。

需要说明的是,我们这里所说的主键外键是指逻辑意义上的概念,也就是在数据的E-R结构设计中的主外键。有时为了性能而在物理数据结构中并不真地建立主键和外键,这种情况不在我们的考虑范围内。

先从一些例子来理解维度的定义。

看这两个同维表:

我们会在manager表建立外键,字段为id,指向employee表的主键id。这时,manage.id既是主键字段也是外键字段,那么它不是维度。而employee.id是主键字段而不是外键字段,那么它就是维度。

再看主子表的情况:

OrderDetail.id是主键字段,但也是指向Orders表的外键字段,所以它不是维度。而Orders.id是主键字段但不是外键字段,那么它是维度,OrderDetail.no是主键字段且不是外键字段,它也是维度。

OrderDetail.no这个维度有些特殊,一般来说,不会有另外一个外键字段和它关联了,我们把这种未被指向的维度称为孤维。在查询界面中做维度对齐运算时一般不用列出来孤维。

再来检验这个定义是否和常规的维度观念相符,并且对于不相符的情况要给出合理的解决方案。

对于地区、产品这些常规维度,数据库中都会有对应的地区表、产品表,那么这些维度就对应了这些表的主键字段,符合我们定义。而销售额、产量等属性则不可能对应到某个表的主键,所以确实也不是维度。

但日期(或年度)呢?它显然是个维度,但数据库中并没有一个表以它为主键,似乎不符合我们的维度定义。

事实上,所有用到日期数据类型的数据库在逻辑上都应当有一个日期表,其它数据表的日期型字段均可以视为指向这个日期表的外键。但由于日期的相关信息都可以由日期本身计算出来(年度、月份等),而不需要单独存储的属性,因此我们通常不会在物理数据库中建立这个日期表。那么,只要在逻辑上恢复这个日期表,日期就符合前面的维度定义了。我们把这种逻辑上应该有但物理上并未建立的表称为假表,假表可以看成是一个单字段无记录的表,这个单字段也就是该表的主键,这样就可以承载没有物理表的维度了。类似地,年度、月份也都可以用假表定义。

再观察年龄这种属性,它有可能用于分类(每个年龄的人数),又可能用于聚合(某部门人员的平均年龄),从性质上看,它似乎即是维度又是测度?这就与我们的定义相悖了。

其实,我们在用年龄分类统计时并不是用年龄值本身,而是年龄段,且年龄本身应该是个实数值,这是不能用于分类的。也就是说,年龄是测度,而通过年龄计算出来的年龄段才是个维度。这时候,我们要引入维函数概念,维函数以某个字段值为参数,返回某个维度的取值。通过维函数可以把测度转换成维度,在它的帮助下,我们就可以保持维度的严格定义,同时又不和常规观念矛盾。

这里的维度定义是基于外键概念的,而我们知道,外键实际上定义了表之间的JOIN关系。从这个意义上讲,维度是被JOIN定义的!


原文发布时间为:2017-12-28

时间: 2024-09-20 08:34:15

数据蒋堂 | JOIN延伸 - 维度概念的相关文章

数据蒋堂 | JOIN简化 - 维度对齐

我们先把上一期中双子表对齐例子的SQL写出来: SELECT Orders.id, Orders.customer, A.x, B.y FROM Orders LEFT JOIN (SELECT id,SUM(price) x FROM OrderDetail GROUP BY id ) A ON Orders.id=A.id LEFT JOIN (SELECT id,SUM(amount) y FROM OrderPayment GROUP BY id ) B ON Orders.id=B.i

数据蒋堂 | JOIN简化 - 意义总结

简化JOIN的好处不仅在于此,还能够降低出错率. 我们知道,SQL允许用WHERE来写JOIN运算的过滤条件(回到原始的笛卡尔积式的定义),很多程序员也习惯于这么写.当JOIN表只有两三个的时候,那问题还不大,但如果JOIN表有七八个甚至十几个的时候,漏写一个JOIN条件是很有可能的.而漏写了JOIN条件意味着将发生多对多的完全叉乘,而这个SQL却可以正常执行,一方面计算结果会出错(回忆一下以前说过的,发生多对多JOIN时,大概率是语句写错了),另一方面,如果漏写条件的表很大,笛卡尔积的规模将是

数据蒋堂 | JOIN运算剖析

JOIN是SQL中用于多表关联的运算,无论从程序员编写还是数据库实现角度来看,JOIN都是SQL中最难的运算. 其实,SQL对JOIN的定义非常简单,就是对两个集合(表)做笛卡尔积后再按某种条件过滤,写出来的语法也就是A JOIN B ON ...的形式.原则上,笛卡尔积后的结果集应当是以两集合成员构成的二元组为成员,不过由于SQL中的集合成员总是有字段的记录,而且也不支持泛型数据类型来描述成员为记录的二元组,所以就简单地把结果集处理成由两表记录的字段合并后构成的新记录集合.这也是JOIN一词在

数据蒋堂 | JOIN提速 - 外键指针化

我们来看重新定义JOIN后如何能够提高运算性能,先看外键式JOIN的情况. 设有两个表: 其中sales表中的productid是指向products表中id字段的外键,id是products表的主键. 现在我们想计算销售额有多少(为简化讨论,就不再设定条件了),用SQL写出来: SELECT SUM(sales.quantity*products.price) FROM sales JOIN products ON sales.productid=products.id 基于笛卡尔积定义的JO

数据蒋堂 | JOIN提速 - 有序归并

我们再来看同维表和主子表的JOIN,这两种情况的优化提速手段是一样的. 设两个关联表的规模(记录数)分别是N和M,则HASH分段技术的计算复杂度(关联字段的比较次数)大概是SUM(Ni*Mi),其中Ni和Mi分别是HASH值为i的两表记录数,满足N=SUM(Ni)和M=SUM(Mi),这大概率会比完全遍历时的复杂度N*M要小很多(运气较好的时候会小K倍,K是HASH值的取值范围). 如果这两个表针对关联键都有序,那么我们就可以使用归并算法来处理关联,这时的复杂度是N+M:在N和M都较大的时候(一

【数据蒋堂】第31期:JOIN简化 - 维度对齐

那么问题来了,这显然是个有业务意义的JOIN,它算是前面所说的哪一类呢? 这个JOIN涉及了表Orders和子查询A与B,仔细观察会发现,子查询带有GROUP BY id的子句,显然,其结果集将以id为主键.这样,JOIN涉及的三个表(子查询也算作是个临时表)的主键是相同的,它们是一对一的同维表,仍然在前述的范围内. 但是,这个同维表JOIN却不能用上一期说的写法简化,子查询A,B都不能省略不写. 可以简化书写的原因在于:我们假定事先知道数据结构中这些表之关联关系.用技术术语的说法,就是知道数据

【数据蒋堂】第32期:JOIN简化 - 意义总结

我们重新审视和定义了等值JOIN运算,并简化了语法.一个直接的效果显然是让语句书写和理解更容易.外键属性化.同维表等同化和主子表一体化方案直接消除了显式的关联运算,也更符合自然思维:维度对齐则可让程序员不再关心表间关系,降低语句的复杂度. 简化JOIN的好处不仅在于此,还能够降低出错率. 我们知道,SQL允许用WHERE来写JOIN运算的过滤条件(回到原始的笛卡尔积式的定义),很多程序员也习惯于这么写.当JOIN表只有两三个的时候,那问题还不大,但如果JOIN表有七八个甚至十几个的时候,漏写一个

【数据蒋堂】第30期:JOIN简化 - 消除关联

我们将等值JOIN分成三种情况来分别讨论,分情况相当于加强了条件,我们可以充分利用每种情况下的特征. 1. 外键属性化 先看个例子,设有如下两个表: employee表和delpartment表的主键都是其中的id字段,employee表的department字段是指向department表的外键,department表的manager字段又是指向employee表的外键.这是很常规的表结构设计. 现在我们想问一下:哪些美国籍员工有一个中国籍经理? 用SQL写出来是这样的: SELECT A.*

【数据蒋堂】我们需要怎样的OLAP?

被狭义化的OLAP OLAP是商业智能应用中重要的组成部分,这个词从字面上理解是在线分析的意思,也就是由用户,特别是业务人员,面对数据进行各种分析操作. 但是,现在的OLAP概念被严重狭义化了.说到OLAP,基本上仅指多维分析,也就是针对一个事先建设好的数据立方体,按指定维度层次进行汇总并呈现成表格或图形,再辅以钻取.聚合.旋转.切片等操作以变换维度层次及汇总范围.多维分析的基本思路认为,直接观察大范围统计值过于粗略,无法精确定位问题,需要剥茧抽丝似地对可能有问题的大范围统计值一步步钻取到更细层