多维数据库

多维数据库

在 OLAP 中,我们通常会通过 Schema 来定义一个多维数据库,它是一个逻辑概念上的模型,其中包含 Cube(立方体)、Dimension(维度)、Hierarchy(层次)、Level(级别)、Measure(度量),这些被映射到数据库物理模型。

  • Cube(立方体)是一系列 Dimension 和 Measure 的集合区域,它们共用一个事实表。

  • Dimension(维度)是一个 Hierarchy 的集合,维度一般有其相对应的维度表,它由 Hierarchy(层次)组成,而 Hierarchy(层次)又是由组成 Level(级别)的。

  • Hierarchy(层次)是指定维度的层级关系的,如果没有指定,默认 Hierarchy 里面装的是来自立方体中的真实表。

  • Level(级别)是 Hierarchy 的组成部分,使用它可以构成一个结构树,Level 的先后顺序决定了 Level 在结构树上的位置,最顶层的 Level 位于树的第一级,依次类推。

  • Measure(度量)是我们要进行度量计算的数值,支持的操作有 sum、count、avg、distinct-count、max、min 等。

概括总结一下:在多维分析中,关注的内容通常被称为度量(Measure),而把限制条件称为维度(Dimension)。多维分析就是对同时满足多种限制条件的所有度量值做汇总统计。包含度量值的表被称为事实表(Fact Table),描述维度具体信息的表被称为维表(Dimension Table),同时有一点需要注意:并不是所有的维度都要有维表,对于取值简单的维度,可以直接使用事实表中的一列作为维度展示。

事实表

每个数据仓库都包含一个或者多个事实数据表。事实数据表可能包含业务销售数据,如现金登记事务。所产生的数据,事实数据表通常包含大量的行。事实数据表的主要特点是包含数字数据(事实),并且这些数字信息可以汇总,以提供有关单位作为历史的数据,每个事实数据表包含一个由多个部分组成的索引,该索引包含作为外键的相关性纬度表的主键,而维度表包含事实记录的特性。事实数据表不应该包含描述性的信息,也不应该包含除数字度量字段及使事实与纬度表中对应项的相关索引字段之外的任何数据。

包含在事实数据表中的“度量值”有两中:一种是可以累计的度量值,另一种是非累计的度量值。最有用的度量值是可累计的度量值,其累计起来的数字是非常有意义的。用户可以通过累计度量值获得汇总信息,例如。可以汇总具体时间段内一组商店的特定商品的销售情况。非累计的度量值也可以用于事实数据表,单汇总结果一般是没有意义的,例如,在一座大厦的不同位置测量温度时,如果将大厦中所有不同位置的温度累加是没有意义的,但是求平均值是有意义的。一般来说,一个事实数据表都要和一个或多个纬度表相关联,用户在利用事实数据表创建多维数据集时,可以使用一个或多个维度表。

一个按照州、产品和月份划分的销售量和销售额存储的事实表有 5 个列,概念上与下面的示例类似。

Sate

Product

Mouth

Units

Dollars

WA

Mountain-100

January

3

7.95

WA

Cable Lock

January

4

7.32

OR

Mountain-100

January

3

7.95

OR

Cable Lock

January

4

7.32

WA

Mountain-100

February

16

42.40

在这些事实表的示例数据行中,前 3 个列——州、产品和月份——为键值列。剩下的两个列——销售额和销售量——为度量值。事实表中的每个列通常要么是键值列,要么是度量值列,但也可能包含其他参考目的的列——例如采购订单号或者发票号。事实表中,每个度量值都有一个列。不同事实表将有不同的度量值。一个销售数据仓库可能含有这两个度量值列:销售额和销售量。一个现场信息数据仓库可能包含 3 个度量值列:总量、分钟数和瑕疵数。创建报表时,可以认为度量值形成了一个额外的维度。即可以把销售额和销售量作为并列的列标题,或者也可以把它们作为行标题。然而在事实表中,每个度量值都作为一个单独的列显示。

事实表数据行中包含了您想从中获取度量值信息的最底层级别的明细。换句话说,事实表中对每个维度的最详细的项目成员都有数据行。如果有使用其他维度的度量,只要为那些度量和维度创建另一个事实表即可。数据仓库中可能包含拥有不同度量值和维度的不同事实表。

事实表前缀为 Fact。

维度表

维度表可以看作是用户来分析数据的窗口,纬度表中包含事实数据表中事实记录的特性,有些特性提供描述性信息,有些特性指定如何汇总事实数据表数据,以便为分析者提供有用的信息,维度表包含帮助汇总数据的特性的层次结构。例如,包含产品信息的维度表通常包含将产品分为食品、饮料、非消费品等若干类的层次结构,这些产品中的每一类进一步多次细分,直到各产品达到最低级别。

在维度表中,每个表都包含独立于其他维度表的事实 特性,例如,客户维度表包含有关客户的数据。维度表中的列字段可以将信息分为不同层次的结构级。维度表包含了维度的每个成员的特定名称。维度成员的名称称为“属性”(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 中的上下级关系,每个级别都是一个具体的维度成员,即:每个级别都是一个或多个维度成员,每个级都包含多个属性。后一种级别在数据库中往往是以递归的方式进行保存的。

聚合表

数据是按照最详细的格式存储在事实表中,各种报表可以充分利用这些数据。一般的查询语句在查询事实表时,一次操作经常涉及成千上万条记录,但是通过使用汇总、平均、极值等聚合技术可以大大降低数据的查询数量。因此,来自事实表中的底层数据应该事先经过聚合存储在中间表中。中间表存储了聚合信息,所以被称为聚合表,这种处理过程被称为聚合过程。