维度表
维度表可以看作是用户来分析数据的窗口,纬度表中包含事实数据表中事实记录的特性,有些特性提供描述性信息,有些特性指定如何汇总事实数据表数据,以便为分析者提供有用的信息,维度表包含帮助汇总数据的特性的层次结构。例如,包含产品信息的维度表通常包含将产品分为食品、饮料、非消费品等若干类的层次结构,这些产品中的每一类进一步多次细分,直到各产品达到最低级别。
在维度表中,每个表都包含独立于其他维度表的事实 特性,例如,客户维度表包含有关客户的数据。维度表中的列字段可以将信息分为不同层次的结构级。维度表包含了维度的每个成员的特定名称。维度成员的名称称为“属性”(Attribute)。假设Product维度中有3种产品,那么维度表将如下所示。
PROD_ID |
Product_Name |
347 |
Mountain-100 |
339 |
Road-650 |
447 |
Cable Lock |
产品名称是产品成员的一个属性。因为维度表中的Product ID与事实表中的Product ID相匹配,称为“键属性”。因为每个Product ID只有一个Product Name,显示时用名称来替代整数值,所以它仍然被认为是键属性的一部分。
在数据仓库中,维度表中的键属性必须为维度的每个成员包含一个对应的唯一值。用关系型数据库术语描述就是,键属性称为主键列。每个维度表中的主键值都与任何相关的事实表中的键值相关。在维度表中出现一次的每个键值都会在事实表中出现多次。例如Mountain-100的Product ID 347只在一个维度表数据行中出现,但它会出现在多个事实表数据行中。这称为一对多关系。在事实表中,键值列(它是一对多关系的“多”的一方)称为外键列。关系型数据库使用匹配的主键列(在维度表中)和外键列(在事实表中)值来联接维度表到事实表。
把维度信息移动到一个单独的表中,除了使得事实表更小外,还有额外的优点——可以为每个维度成员添加额外的信息。例如,维度表可能为每个产品添加种类(Category)信息,如下所示。
PROD_ID |
Product_Name |
Category |
347 |
Mountain-100 |
Bikes |
339 |
Road-650 |
Bikes |
447 |
Cable Lock |
Accessories |
现在种类是产品的另一个属性。如果知道Product ID,不但可以推断出Product Name,而且可以推断出Category。键属性的名称可能是唯一的——因为每个键只有一个名称,但其他属性不需要是唯一的,例如Category属性可能会出现好几次。这样一来,便可以创建按照产品和类别对事实表信息进行分组的报表。除了名称外,维度表可以包含许多其他的属性。本质上,每个属性都对应于维度表中的一个列。下面是带有其他额外属性的只有3个成员的Product维度表的示例。
PROD_ID |
Product_Name |
Category |
Color |
Size |
Price |
347 |
Mountain-100 |
Bikes |
Black |
44 |
782.99 |
339 |
Road-650 |
Bikes |
Silver |
48 |
3399.99 |
447 |
Cable Lock |
Accessories |
NA |
NA |
25.00 |
维度属性可以是可分组的,也可以是不可分组的。换句话就是,您是否见过按照哪个属性来分组度量值的报表?在我们的示例中,Category、Size和Color全都是可分组的属性。由此自然会联想到可能在某个报表中按照颜色、大小或种类来分组销售额。但Price看起来不像是可分组的属性——至少它本身不是。在报表中可能会有一个更有意义的其他属性——例如Price Group,但价格本身变化太大,导致在报表上分组意义不大。同样地,按照Product Description属性在报表上进行分组意义也不大。在一个Customer维度中,City、Country、Gender和Marital Status都是可以在报表上按照它们进行有意义分组的属性,但Street Address或Nickname都应当是不可分组的。不可分组的属性通常称为成员属性(member property)。
Hierarchy与Level
某些可分组的属性可以组合起来创建一个自然层次结构(natural hierarchy)。例如假设Product有Category和Subcategory属性,在多数情况下,单个产品只会属于单个Subcategory,并且单个Subcategory只会属于单个Category。这将形成一个自然层次结构。在报表中,可能会显示Categories,然后允许用户从某个Category钻取到Subcategories,以及最终钻取到Products。
层次结构——或者说钻取路径——不一定要是自然的(例如,每个低层次的成员会决定下一个高层次的成员)。例如,您可能会创建一个按照Color分组产品的报表,但允许用户根据每个Color钻取到每个不同的Size。因为报表的钻取能力,Color和Size形成了一个层次结构,但是根据Size却没有任何信息可以用来断定产品的Color将是什么。这是一个层次结构,但不是一个自然层次结构——但也不是说它是个非自然层次结构。Color和Size形成一个层次结构并没有什么不对,它只是这样一个简单的事实:相同的Size可以出现在多个Color中。
在OLAP中定义维度时,层(Hierarchy)与级(Level)是比较让人迷惑的两个概念。简单的说,层就是一种维度成员的分类方式,级就是维度成员之间或维度成员属性之间的包含关系。一个维度至少要包含一个层。以【产品】维度为例,可以创建一个【产地】层,可以创建一个【厂商】层,也可以创建一个【分类】层。在SSAS中,可以不定义层,此时维度的默认层为AllMembers层。在Mondrian的Schema定义工具中,则要求全部手工定义。
一个层至少要包含一个级,以【产品】维度为例,【产地】层可以包含省-市-县三个级别,【分类】层可以包含日用品-洗涤用品-洗衣粉三个级别。级别的定义有2种方式,一种是在一个维度成员的属性之间定义,例如【产品】维度的每个成员都有产品系列、大类、小类三个属性,这样定义【分类】层的级别时,直接利用这三个属性即可,即:每个级别都是一个成员的一个属性。另一种是在维度成员之间进行,例如HR中的上下级关系,每个级别都是一个具体的维度成员,即:每个级别都是一个或多个维度成员,每个级都包含多个属性。后一种级别在数据库中往往是以递归的方式进行保存的。