学无止境
分类: Oracle
2009-12-16 12:08:36
关于Dimension
Dimension是一个逻辑结构,定义了dimension table中的一个列或一组列于其他列之间的一个层次关系。Dimension只保存定义,可以将其理解为一种特定的constraint。
Dimension不是一种必须存在的结构,但是,创建dimension对于数据仓库中一些复杂的查询重写有着相当重要的意义。查询重写是数据仓库性能优化的重要方法。
数据仓库中由于数据量巨大,一些聚合计算等操作往往通过物化视图预先计算存储。但是,不可能对所有维度的所有可能的聚合操作都建立物化视图,一则空间不允许,二则刷新时间也不允许。
那么,在对某些聚合操作的sql进行查询重写时,就希望能利用已经存在的物化视图,尽管他们的聚合操作条件不完全一致。而dimension定义的各个level之间的层次关系,对于一些上卷(rolling up)和下钻(drilling down)操作的查询重写的判断是相当重要的,而dimension中定义的attributes对于使用不同的列来做分组的查询重写起作用。
Dimension中三个重要的属性:level,hierarchy,attribute。其中level定义了一个或一组列为一个整体,而hierarchy则定义了各个level之间的层次关系,父level和子level之间是一种1:N的关系,而且,在dimension中可以指定多个hierarchy层次关系。attribute则定义了level和其他列的一个1:1的关系,但这种1:1的关系不一定是可逆的。
下面的例子中,根据player_info,也就是LEVEL player(由club_id和club_num组成),可以确定players.name,但不一定要求players.name就能确定LEVEL player。
而且,各个level之间的列不一定要来自同一个table,对于雪花模型,dimension table可能被规范化为许多的小表,则dimension中的level可能是来自不同表中的列。这是需要在dimension中指定join key来指出各个表之间的关联列。例如上面的例子中,players.club_id与LEVEL club关联,也就是players表的club_id字段的外键是clubs.id。
一个创建维度(Dimension)的例子,创建之前,必须存在players和clubs表。
1. CREATE DIMENSION fb_dim
2. LEVEL player IS (players.club_id,players.club_num)
3. LEVEL club IS (clubs.id)
4. LEVEL city IS (clubs.city)
5. LEVEL league IS (clubs.league)
6. LEVEL country IS (clubs.country)
7. HIERARCHY fb_rollup(
8. player CHILD OF
club CHILD OF
city CHILD OF
league CHILD OF
country
9. JOIN KEY (players.club_id) REFERENCES club)
10. ATTRIBUTE player_info LEVEL player DETERMINES
11. (players.name,players.country,players.pos,players.age)
12. ATTRIBUTE club DETERMINES
13. (clubs.name);
解释:
1. 创建一个Dimension,名为fb_dim。
2. 关键字LEVEL用于定义Dimension中的每一个LEVEL,它是构成维度层次关系和属性的基础。LEVEL可以来自不同的表。定义一个名为player的LEVEL,该LEVEL由2个列组成,分别是players表的club_id和club_num。
3. 定义一个名为club的LEVEL,该LEVEL由1个列构成,是clubs表的id字段。
4. 定义一个名为city的LEVEL,该LEVEL由1个列构成,是clubs表的city字段。
5. 定义一个名为league的LEVEL,该LEVEL由1个列构成,是clubs表的league字段。
6. 定义一个名为country的LEVEL,该LEVEL由1个列构成,是clubs表的country字段。
7. 关键字HIERARCHY用于定义LEVEL之间的层次关系,可以定义多个层次关系,每个层次关系中不一定需要包含上面所有的LEVEL。定义了个名为fb_rollup的HIERARCHY。
8. 关键字CHILD OF之前的是child_level,之后的是parent_level,也就是说,player是最小的child_level,它的parent_level是club,而club又是city的child_level,league又是city的parent_level,最大的parent_level是country。在HIERARCHY中,child_level和parent_level是一种1:N的关系。
9. 由于LEVEL可以来自不同的表,可以通过关键字JOIN KEY来指出各个表之间的关联列。该子句只允许HIERARCHY中包含来自不同表的LEVEL时才能使用。这里表示players.club_id字段与LEVEL club关联,也就是players.club_id字段与clubs.id外键关联。
10. 关键字ATTRIBUTE用于定于一个LEVEL的属性,可以指定一个attribute_name,后面要跟LEVEL关键字和名称,也可以直接使用LEVEL的名称。关键子DETERMINES之后表示该LEVEL的字段有1:1关系的字段。ATTRIBUTE定义了level和其他列的一个1:1的关系,但这种1:1的关系不一定是可逆的。
11. 这些字段必须和level中的字段来自同一张表。由level的字段可以决定出这些字段唯一的记录。
12. 这里的ATTRIBUTE定义没有使用attribute_name,直接用了LEVEL的名称。
13. 这些字段必须和level中的字段来自同一张表。由level的字段可以决定出这些字段唯一的记录。