维度-层次维度
Dimension 元素有一个foreignKey 属性,它是事实表的列名;而Hierarchy 元素有一个primaryKey 属性。
如果一个层次有不止一个表,可以使用primaryKeyTable 属性来区分。
Level 的column 定义了它的键,必须是这个层次所在表的列名。如果键是一个表达式,可以使用KeyExpression 元素子元素。Level、Measure 和Property 的一些属性相应的嵌套元素:
Level 元素的uniqueMembers 属性用于优化SQL 生成。
如果知道一个层次列的取值在整个维表中即使跨越父层次的所有取值中都是唯一的,那就把uniqueMembers 设为true,否则设为false。
例如,时间维度分为年、月层次,在月层次上要把uniqueMembers 设为false,因为每年都有这些月。另一例子,如果有产品分类、产品层次,如果能够保证产品是唯一
的(别的分类不会有同名产品,或者说,一个产品不会有多个分类),那么可以把uniqueMembers 设为true。如果不确定,就设为false。在顶层,uniqueMembers 总会是true,因为它没有父层次。
4.3.2 成员“ALL”
默认情况下,每套层次都包含一个顶级层次叫做“(All)”,它只包含单个叫“(All {层次名})”的成员。这个成员是这套层次中所有其他成员的父成员,因此表示一个累计值。它也是这套层次的缺省成员,意思是,如果这套层次没有出现在轴上或分片上,那就采用它来进行计算。
allMemberName 和AlevelName 属性覆盖了“All”成员和“All”层次的缺省名称(即“(All{层次名})”和“(All)”)。
如果Hierarchy 元素有hasAll=”false”,“All”层次会被禁止。现在这一维度的缺省成员会变
成第一个级别的第一个成员。例如,在时间维度层次,会变成第一个年份。修改缺省成员会带来混淆,因此一般都应该使用hasAll=”true”。Hierarchy 元素同样有一个defaultMember 属性,用以覆盖层次的缺省成员。以下把时间维度的缺省成员设为1997 年的第一个季度:
<Dimension name="Time" type="TimeDimension" foreignKey="time_id"> <Hierarchy hasAll="false" primaryKey="time_id" defaultMember="[Time].[1997].[Q1] "/> ...
4.3.3 多层次体系
一个维度可以由多个层次组成:
<Dimension name="Time" foreignKey="time_id"> <Hierarchy hasAll="false" primaryKey="time_id"> <Table name="time_by_day"/> <Level name="Year" column="the_year" type="Numeric" uniqueMembers="true"/> <Level name="Quarter" column="quarter" uniqueMembers="false"/> <Level name="Month" column="month_of_year" type="Numeric" uniqueMembers="false"/> </Hierarchy> <Hierarchy name="Time Weekly" hasAll="false" primaryKey="time_id"> <Table name="time_by_week"/> <Level name="Year" column="the_year" type="Numeric" uniqueMembers="true"/> <Level name="Week" column="week" uniqueMembers="false"/> <Level name="Day" column="day_of_week" type="String" uniqueMembers="false"/> </Hierarchy> </Dimension>
注意第一个层次没有名字。默认第一个层次的名字跟维度的一样,因此第一个层次就叫”Time”。
除了它们都连接事实表的同一列”time_id”以外,这些维度层次没有多少共同的地方,它们甚至没有使用同一个表。
把两个层次放到一个维度中的主要原因是,这对终端用户来说有更多意义。终端用户知道如果把”Time”层次放到一个轴上而把”Time Weekly”放到另一个轴上是没有意义的。如果两个层次是同一个维度,MDX 不会允许它们用于同一个查询中。