转自:http://hi.baidu.com/sheenshine/item/002e20d22a3b45826cce3fd3
其实对于一般OLAP产品而言,只有度量维度和普通维度两种,普通维度里可能时间维度有一些预定义的行为,基本上这些维度的定义都是一些技术上的定义,不会具有业务上的含义(比如你不能建立一个具有财务费用属性的维度,这个所谓费用的行为需要你自己通过某种技术手段去实现),但是Essbase在这方面则有不少特点,一方面你也可以从头开始建立自己所需要的维度,但是另一方面
Essbase已经根据大部分多维模型项目的需要,归纳出一些在大部分项目都需要的特殊维度和属性,提供了预定义的这些维度和属性的行为,这是essbase的一个很大的特点,只要根据不同的需求去选择不同的维度类型和维度属性,就能够自动产生许多针对该维度类型相关的分析。这个特点也是熟悉其他OLAP产品的人学习Essbase的一个主要疑惑,就是为什么Essbase的教材总要花很多时间去交代各种各样的维度类型和属性。
这些预定义的维度和属性比如:account维度类型(度量)和属性,时间维度和属性,场景维度(scenario)和属性,这些维度在大部分的项目都会用到,并且都是计算密集和分布密集的维度。 Account维度和属性
Essbase里的第一种特殊的维度也是最复杂的维度是account dimension,account dimension其实是对应了多维模型里的度量,所以属性是和其他维度相差最大的维度类型,它有非常丰富的各种属性和各种各样可定义的行为。
Account dimension主要用于描述销售额,利润,利润率等企业的关键指标,所以多维数据库的设计里需要花许多时间做account dimension的设计。下面是account维度的一些属性的描述:
- 时间余额属性(Time Balance):
虽然在OLAP运算中大部分用到的是根据不同的层次进行累加,比如一个季度的销售额是三个月销售额的总和,但是对于某些业务概念的表达则不能简单的进行相加。
比如存货数量,当一月存货是100,二月存货是200,3月存货是80的时候,则第一季度的存货是多少呢?很显然并非是这三个月的总和380,而是根据预先的设定是取期初余额,还是取期末余额来还是取平均值来决定,如果是使用期初规则,则这个季度的存货数量是100,如果是期末规则,则存货数量是80,类似于这种的属性则称之为account维度的时间余额(time balance)属性。
- 费用属性(Expense):Account Dimension成员里的第二种特殊属性是Expense属性和差异计算:一个成员可以标记为费用属性从而会自动具有财务上费用属性的特征,所谓具备财务费用上的特征的意思是,对于一个不具备费用属性的数值而言,如销售额,如果销售额从100变为200的时候,这个时候应该是好事,也就是数值上的反应应该正数,以红色来表示(如果红色代表好的话);但是对于费用的数值则相反,因为费用从100变为200的时候,实际上对于公司而言并非是什么好的事情,如果采取和一般数值相同的算法(即200-100=一个正数的100的话),则看起来好像也是好事,而这和实际业务是有冲突的,所以所有费用属性的数值会采取相反的方式(100-200=负的100),这样就能够很直观地看出来费用实际上是有问题的;当然如果使用别的OLAP来定义出费用属性,你可能就需要定义一个计算列,这个计算列,这个计算列前面加一个负号来表示费用属性,我们通过这个属性不难看到,essbase在长期的积累中已经出现了大量的现成的可以使用的属性行为,而这些属性行为都是可以让业务人员很容易理解的。这个费用属性的具体表现还体现在差异计算中,在差异计算比较实际发生和预算数的时候,当一个维度不是费用属性的时候,如销售额,假设实际是100,而预算数是120,则差异计算variance=@VAR(actual,budget)计算出来是-20;而另一个维度如果标记成费用维度,则相同的公式给出的数值是20。
时间维度是essbase里另外一个非常重要的维度,一个OLTP和OLAP的主要区别就可以通过时间维度来说明:
在交易系统里我们关注的时间特性是交易发生的时间,如果有两个交易分别发生在是15点10分和15点20分,这对于交易系统而言是有本质的区别的,但是对于一个以一个小时为最小单位的OLAP的设计来说,这个两个交易是没有区别的,他们同样是发生在15点到16点的这个区间里,所以交易系统关心时间上的点,而OLAP系统则关心时间的区间。
这个也提出了设计时间维度的一个基本问题就是时间维度的设计的最小的时间粒度应该是什么的问题,是一个小时,一天,还是15分钟,其实这些都取决于应用的具体需要。
比如一个分析一天内超市销售行为的分析系统一个合理的最小单位是半个小时或甚至15分钟,这样的时间区间可以分析出中午吃饭的时间是不是对于销售额有明显的影响,但是这样的区间对于分析一年销售量随着时间的变化的曲线则没有任何意义,在这样的场景则最小单位取1天甚至1周更加合适。
时间维度的另一个重要设计是关于年度的概念,可能是因为essbase起源于财务领域有关系,而任何真实公司财务系统都是按照年的概念(财政年度)来分开交易的。
(发生在12月31日--还是今年和1月1日—已经是明年的交易对于财务系统而言有本质的区别,虽然其实他们从某种观点来看不过就是今天和明天的区别)所以essbase里也需要对财务年度的选取有特殊的考虑,最传统的一个设计是在使用一个时间维度的同时,再增加使用另一个维度来代表年度,这种设计方式就可以完全按照财务的理解来处理年份,Hyperion的财务应用就使用这种设计方式,如下图是按照财政年度来处理年份的设计:

在这样的情景可能直接使用一个包含年和更细时间粒度的单一时间维度更合适一些,下图就是单一时间维度的典型设计方式:

PTD计算
对于一般的应用而言,PTD(Period-to-Date)等按时间累加到某一状态的需求是比较常见的(如Q-T-D季度当前值,如果当前是二月份,则计算的时候会把数据求和更新到二月份,等到了三月份再用户再发出同样的请求,则数据就会自动累计计算到三月份),essbase里对于这种类型的计算也有相应的设计考虑。
Essbase使用两种方式来满足这种设计需求,第一种是通过成员公式(member formula),的方法,如下图:

这样就可以创建出所需要的QTD或者YTD,这种方式比较繁琐,但是很容易理解,最大的好处是可以完全自己控制累加的方式(可以满足某些特殊的需求,比如如说不想把某个月包含在计算里面)。如QTD Jan下只有一月份的成员,而QTD Feb下则包含一月和二月份的值,这种方式从道理上很容易理解,一般使用这种方式的时候所引用的成员可以使用共享成员的方式引用原来存在的各个数据(Jan,Feb一般都已经在时间维度上已经存在)。这样设计之后,当在一月份的时候,需要使用QTD Jan成员来得出QTD的值,而在二月份的时候,需要使用QTD Feb成员来得出当时QTD的值,而到了四月份,则QTD的值重新回到包含当季的的第一个月。
第二种得出QTD的值的方式是使用Essbase内置的PTD的功能,这种方式是通过时间序列的定义的方式来实现,仅对于被定义为时间维度的维度类型起作用,通过右键选择“动态时间序列”,则出现以下的选择:

Scenario维度和属性
Essbase的另一种特殊维度是scenario维度:scenario维度的主要目的是为了比较不同的数据集的差异计算,比如为了比较实际发生和预算值,则scenario就会有两个成员actual代表实际发生数据集,而budget则代表预算数据集,这样就可以使用各种方式去分析比较他们的差异,使用同样的方式还可以进行所谓的what-if分析,比如可以有一个数据集时今年发生数,通过拷贝今年发生的数据集并且相对应的发生乘于一个系数(比如明年销售额是今年的120%),就可以在这种假设下进行很多计算来模拟各种不同的场景,这些主要都是通过scenario维度来实现的。