随笔-39  评论-300  文章-0  trackbacks-1

SSAS中Cube的结构

在SSAS(SQL Server Analysis Services)中构建Cube和编写MDX的时候,我们很容易被一些名词弄糊涂,比如:Dimension(维度),Measures Dimension(度量维度),Measure(度量),Hierarchy(层次结构),Attribute hierarchy(属性层次结构),Level(级别),Cell(单元),Member(成员),Member Property(成员属性),Set(集),Turple(元组)等等。要想弄清楚这些名词,就必须理解Cube的结构。

上述名词的解释详见:http://msdn2.microsoft.com/en-us/library/ms144884.aspx

Cube、Dimension和Measure
Cube就象一个坐标系,每一个Dimension代表一个坐标轴,要想得到一个点,就必须在每一个坐标轴上取的一个值,而这个点就是Cube中的Cell。见下图(来源于http://msdn2.microsoft.com/zh-cn/library/ms144884.aspx):
 

上图很好的说明了Cube、Dimension、Measure之间的关系。这里需要注意的是:其实Measure也属于一个维度,即Measures Dimension。所有的Measure构成了Measures Dimension,这个维度的只有一个Hierarchy,而且这个Hierarchy只有一个层次(Level)

Hierarchy、Level和Memeber
在上节的图中,每个Dimension只有一个Hierarchy,而在实际的环境中,一个Dimension往往有很多Hierarchy。因此,上一小节中关于“Cube就象一个坐标系,每一个Dimension代表一个坐标轴”这句话其实不够准确,准确的说应该是每一个Hierarchy代表了一个坐标轴,而Hierarchy中每一个Member代表了坐标轴上的一个值。下图以时间维度为例展示了Dimension的内部结构。


此外,我们需要说明的是:

1) 上图中说明的是一般Dimension的结构,在实际的模型中,其实可以做很多自定义的工作。比如:我们可以修改Hierarchy的默认Member。 

2) 一般情况下,SSAS中Hierarchy的默认Member是All(在你的模型中,可能叫其他名称)。换句话说在MDX中[时间].[财政]等价于[时间].[财政].[All][时间].[财政].Children等价于[时间].[财政].[All].Children

3) Dimension_Name.Hierarchy_Name.Level_Name等价于Dimension_Name.Hierarchy_Name.Level_Name.Members。比如:[时间].[财政].[半年]等价于[时间].[财政].[半年].Members。Level的Members是该级别的所有元素(对于[时间].[财政].[半年].Members={[上半年],[下半年],[上半年],[下半年]},其中前两个是2001年下的,后两个属于2002年),而Hierarchy的Members包含了该Hierarchy下所有的内容。

4) 当且仅当一个Dimension下只有一个Hierarchy,则Dimension_Name等价于Dimension_Name.Hierarchy_Name纬度。比方说:时间维度只有一个财务Hierarchy,则[时间]等价[时间].[财务]

5) Attribute Hierarchy中Members的层次是两层(MSDN的说法更加准确,这里简化了一些):第一层:All,第二层:叶子节点。也就是说它和多层的Hierarchy相比,两者结构完全相同,这是统一维度模型(Unified Dimensional Model)一个方面的体现。 

      注意:采用Attribute Hierarchy能够使编写MDX更加容易,但同时也增加了Cube的容量,加大了Cells的个数,对性能有负面影响。因此,在建模的时候,我们可以把一些Attribute Hierarchy的AttributeHierarchyEnabled属性设置成False,同时在编写MDX时,以Member Property的方式来引用,这样可以在满足需求的前提下提高性能。

6) Measures Dimension是一个特殊的维度,它的Members中没有All这个成员,它的默认Member可以在建模时指定。

7)对于一般的维度,其第一层Level的默认是“(All)”。

Turple和Set
如果说Cube好像一个坐标系,那么Turple、Set的关系就好比点和面的关系。Turple由Cube中每个Hierarchy的一个Member组成。由于Hierarchy的个数非常多,所以一般不可能在Turple表达式中把所有的Member都明确指定,故此,为了简化开发,所有没有明确指定Member的Hierarchy,用该Hierarchy的默认Member代替。也就是说:([时间].[财政].[2001].[上半年]) 等价于([时间].[财政].[2001].[上半年],[时间].[日历].[All])。另外我们需要注意的:

1) 有的说法认为:Turple是“Cube 上的一个子集(不断开的子Cube),这个看法是不准确的,因为Turple只是一个点,不是面,它仅仅由每个Hierarchy的一个Member组成的。

2) 外面()起来的表达式不一定是Turple。比如:([时间].[财政].[半年].Members,[时间].[日历].[2001].[上半年])就不是一个Turple,而是一个Set,其原因在于,Turple是点,它仅仅由每个Hierarchy的一个Member组成,如果在任何一个Hierarchy上有两个成员,则其就变成Set了。

      注意:([时间].[财政].[半年].Members,[时间].[日历].[2001].[上半年])等价于Crossjoin([时间].[财政].[半年].Members,[时间].[日历].[2001].[上半年]){[时间].[财政].[半年].Members}*{[时间].[日历].[2001].[上半年]},在SSAS的MDX中,我们可以在()中定义多个用逗号分隔开的表达式,编译器会进行分析,如果发现是Set的话,就把它转化成多个Set相乘的形式。

3) Set中的Turple可以重复。比如:{[时间].[日历].[2001].[上半年],[时间].[日历].[2001].[上半年]}并不等于{[时间].[日历].[2001].[上半年]},因为前者有两个Turple,后者只有一个。

4) SSAS能够根据上下文的需要,自动把Turple变成Set,单个Member变成Turple,多个Member变成Set。这也是我们常常混淆Turple和Set的原因。详细的例子如下:

a)上下文需要Set时,([时间].[日历].[2001].[上半年])自动转化成{[时间].[日历].[2001].[上半年]}。 
b)上下文需要Turple时,[时间].[日历].[2001].[上半年]自动转化成([时间].[日历].[2001].[上半年])
c)上下文需要Set时,[时间].[日历].[2001].Children自动转化成{[时间].[日历].[2001].Children}

总结
总体来看,SSAS中的Cube的内部结构非常的清晰,在实际开发中,只要多注意一下默认的一些转化,使用起来是很容易的。




posted on 2006-10-31 16:53 microsheen 阅读(4594) 评论(5) 编辑 收藏

评论:
#1楼 2006-11-23 01:34 | Ricky1981[未注册用户]
好文章,获益匪浅!
谢谢

 回复 引用   
#2楼 2007-01-22 22:26 | goldfeng[未注册用户]

希望多交流:Smartgoldfeng@sina.com (MSN)

 回复 引用   
#3楼 2007-11-27 17:27 | 请教[未注册用户]
准确的说应该是每一个Hierarchy代表了一个坐标轴

 回复 引用   
#4楼 2009-06-17 18:15 | t-beck[未注册用户]
"1) 有的说法认为:Turple是“Cube 上的一个子集(不断开的子Cube),这个看法是不准确的,因为Turple只是一个点,不是面,它仅仅由每个Hierarchy的一个Member组成的。
2) 外面()起来的表达式不一定是Turple。

A tuple is a coordinate in multidimensional space.
tuple定义了多维空间里的一个坐标系。

A slice is a section of multidimensional space that can be defined by a tuple.
slice是多维空间里的"一段"(连续的,不断开的子cube),一个tuple定义了一个slice.

所以很明显tuple不是一个点。tuple中文翻译一般作“元组”,而不是“元点”。slice是切片,。同样括号括起来的就是tuble,大括号括起来的就是set,cute定义不断开子cube,set即可以理解为同样维度的子cube的集合。

拿三维坐标系(x,y,z)举例,tuple(x.1, y.1)定义了 (1,1,*)这个slice,可理解为过(x=1,y=1)的一直线。(x.1)定义了(1,*,*)slice,可以把这个slice理解成x=1上的平面。所以tuple定义的不是点,而是slice.

同样{ (x.1),(x.2)}就是set,元素是两个具有相同维度的tuple.

 回复 引用   
#5楼[楼主] 2010-05-13 15:25 | microsheen      
拿三维坐标系(x,y,z)举例,tuple(x.1, y.1)定义了 (1,1,*)这个slice,可理解为过(x=1,y=1)的一直线。(x.1)定义了(1,*,*)slice,可以把这个slice理解成x=1上的平面。所以tuple定义的不是点,而是slice.

当你定义(x=1,y=1)时,z是什么值呢,z一般情况下等于All。也就是
(x=1,y=1) = (x=1,y=1, z=All). 这样可以就成为一个点啦。(x=1,y=1, z=All)的measure值都是在cube处理后,就生成好了。在执行mdx时,并不需要额外的计算。当计算(x=1,y=1, z=All)并没有
sum((x=1,y=1, z=1),(x=1,y=1, z=2),...)的过程。也就是(x=1,y=1, z=All)本身就是一个点,一个cell。

 回复 引用 查看