schema概念
- 一个Schema定义了一个多维度的数据库,它包含了一个逻辑模型(其中包含了cubes,hierarchies,members),模型对应的物理模型的映射。
- 逻辑模型包含的这些结构用来在MDX语言中写查询:cubes,dimensions,hierarchies,levels,members.
- 物理模型通过逻辑模型展现的数据源,它一般是星型结构(在关系型数据库中的一系列表)。
schema files
Mondrian schemas 通常在xml中展现出来,目前来说,创建schema的唯一方法就是编辑xml文件,可以参考demo/FoodMart.xml文件内容
逻辑模型
schema中最重要的部分是:cubes,measures,dimensions.
- Cube:在一个专门领域的维度和度量的集合
- Measure:你所感兴趣的度量的数量,比如:产品销量。
- Dimension:是一种属性或者是属性的集合,你可以通过它将measures划分子类。
下面,我们看一个例子:
<Schema>
<Cube name="Sales">
<Table name="sales_fact_1997"/>
<Dimension name="Gender" foreignKey="customer_id">
<Hierarchy hasAll="true" allMemberName="All Genders" primaryKey="customer_id">
<Table name="customer"/>
<Level name="Gender" column="gender" uniqueMembers="true"/>
</Hierarchy>
</Dimension>
<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>
</Dimension>
<Measure name="Unit Sales" column="unit_sales" aggregator="sum" formatString="#,###"/>
<Measure name="Store Sales" column="store_sales" aggregator="sum" formatString="#,###.##"/>
<Measure name="Store Cost" column="store_cost" aggregator="sum" formatString="#,###.00"/>
<CalculatedMember name="Profit" dimension="Measures" formula="[Measures].[Store Sales] - [Measures].[Store Cost]">
<CalculatedMemberProperty name="FORMAT_STRING" value="$#,##0.00"/>
</CalculatedMember>
</Cube>
</Schema>
这个schema只是一个cube,它有两个维度:”Time”,”Gender”,和四个量度:”Unit Sales”,”Store Sales”,”Store Cost”,”Profit”.
通过Schema可以写出MDX查询语句:
SELECT {[Measures].[Unit Sales],[Measures].[Store Sales]} ON COLUMNS,
{descendants([Time].[1997].[Q1])} on ROWS
FROM [sales]
where [Gender].[F]
Cube
一个Cube就是measures和dimensions的集合,measures和dimensions的共同之处就是都是来自于事实表。
<Cube name="Sales">
<Table name="sales_fact_1997"/>
...
</Cube>
如果事实表不在默认的schema中,我们可以提供一个明确的schema.
<Table schema=" dmart" name="sales_fact_1997"/>
我们可以使用<View>
来创建更多的复杂的SQL语句,<Join>
结构不支持事实表。
Measures
上面的Sales Cube定义了几个度量,包含”Unit Sales”,”Store Sales”.
<Measure name="Unit Sales" column="unit_sales" aggregator="sum" datatype="Integer" formatString="#,###"/>
<Measure name="Store Sales" column="store_sales" aggregator="sum" datatype="Numeric" formatString="#,###.00"/>
- 每一个measure包含一个name,column(在事实表中),aggregator。aggregatore通常是”sum”,但是”count”,”min”,”max”,”avg”,”distinct-count”也是支持的.
- “datatype”属性指定了cell value如何在Mondrian的cache中展现,它有”String”,”Numberic”,”Integer”,”Boolean”,”Date”,”Time”,”TimeStamp”,默认是”Numeric”
“formatString”:指定了值是如何展现的,”,” 和”.”符号可以作为分隔。
Measure可以不仅来自于列,可以使用cell reader,或者是SQL语句,比如:
<Measure name="Promotion Sales" aggregator="sum" formatString="#,###.00">
<MeasureExpression>
<SQL dialect="generic">
(case when sales_fact_1997.promotion_id =
0 then 0 else sales_fact_1997.store_sales end)
</SQL>
</MeasureExpression>
</Measure>
Dimensions,Hierarchies,Levels
下面是一些定义:
- member:第一个维度所包含值的集合,比如gender包含2个Members:M ,F。
- hierarchy:为了方便分析而组织在一个结构中的members集合。
- level:到层级根节点同样距离的members集合。
- dimension:hierarchies的集合,用以区分事实表的属性。
举个例子:
<Dimension name="Gender" foreignKey="customer_id">
<Hierarchy hasAll="true" primaryKey="customer_id">
<Table name="customer"/>
<Level name="Gender" column="gender" uniqueMembers="true"/>
</Hierarchy>
</Dimension>
这个维度包含一个层级,这个维度的值来自于customer表中的gender列,在sql中实际上是通过join语句,
事实表 “sales_fact_1997.customer_id” 到维度表的 “customer.customer_id”.
将dimensions和hierarchies映射到表中
在一个表中加入维度是通过一些列,一个来自于是事实表,一个来自于维度表。
Dimension元素包含foreignKey属性,这是是事实表中的列名;hierarchy中包含primaryKey属性,这是维度表的列名。
如果一个层级关系中有一张表以上,可以使用”primaryKeyTable” 属性
column属性定一个level的key,它必须是来自于维度表的列名,如果key是一个表达式,我们可以使用KeyExpression元素,
下面是一个例子:
<Dimension name="Gender" foreignKey="customer_id">
<Hierarchy hasAll="true" primaryKey="customer_id">
<Table name="customer"/>
<Level name="Gender" column="gender" uniqueMembers="true">
<KeyExpression>
<SQL dialect="generic">customer.gender</SQL>
</KeyExpression>
</Level>
</Hierarchy>
</Dimension>
其他的属性,我们可以在下表中找到:
注:
1.uniqueMembers属性是用来优化SQL语句的产生,比如:一个时间维度[Year].[Month]将会设置uniqueMembers=”false”,
因为相同的月份出现在不同的年中;如果你有一个层级[Product Class].[Product Name],那么可以设置[Product Name]的uniqueMembers=”true”,在最高的层级中,总是将uniqueMembers设置为true.