促销维度
促销维度描述了销售商品的促销条件。促销条件包括临时降价、终端通道展示礼券等。促销维度通常被认为是一种因果维度,因为它描述了认为可能导致产品销售发生改变的因素。
促销基于以下一个或多因素来判断:
1.促销产品的销售是否在促销期间获得大幅增加,也称提升。
2.促销产品在促销前或促销后的销售,与促销期间的销售比较,是否有降低,这种降低是否抵消了促销期间的销售增益。
3.促销产品在销售方面表现良好,但是其他与其相邻的产品的销售却显著降低了。
4.促销分类中的所有产品是否都获得了销售方面的净总增益,将考虑促销前、促销期间,促销后的时间段。
5.促销是否有利可图。
事务系统跟踪降价。礼券的出现通常也通过交易获得,因为客户要么在销售时出示礼券,要么不出示。广告和橱窗展示条件可能需要其他源的介入。
临时降价通常与广告或终端通道展销相关。在促销维度中为每个发生的促销条件的组合建立一行是具有实际意义的。在过去一年中,有1000个广告,5000个临时降价,1000个终端通道展销,但仅有10000次该三个条件的组合能够影响任何特定的产品。(如:对某次促销,多数门店同时采用上述三种促销机制。但一些商店可能没有布置终端通道展销。在这种情况下,需要两个不同的促销条件行,一行包括通常的降价加广告加展示,另外一行包括降价加广告。)
通过将4个不同的因果机制(降价、广告、展示、礼券)区分开,建立不同的维度而不是将它们合并在一个维度中。这样将会记录与促销信息相似的信息。将4个维度放在一起的理由如下:
1.如果4个因果机制高度关联,合并而成的单一维度不会比任一单个维度大很多。
2.合并成单一维度可方便浏览,观察降价、广告、展示、礼券的相互影响关系。对维度表的浏览无法揭示促销对哪个商店或产品有影响,此类信息显然需要浏览事实表方能获得。
赞成4个因果机制划分到4个不同的维度中的原因:
1.对业务群体来说,当分别考虑不同的机制时,不同的维度可能更易于理解。
2.对不同维度的管理可能比对合并维度的管理更直接。
这两种选择在内容上没有差别。
注:应当仔细权衡包含在促销维度中的促销成本属性。该属性可用于约束和分组。该成本没有出现在表示独立产品销售的POS事务事实表中,因为其粒度不符。成本应该驻留在粒度为整个促销的事实表中。
空外键、空属性和空事实
通常,许多销售事务包括未被促销的产品。促销维度必须包含一行,具有唯一键0或-1,用以表示这个不含促销条件,避免事实表中出现空的促销键。如果将一个空值放在事实表中的已被声明为外键的列,则违背了参照完整性的要求。
警告:不要在事实表中使用空值键。正确的设计应在对应维度表中包括一行以表明该维度不可用于度量。
当某一给定的维度行未被完全填充时,或者有些属性未被应用到所有维度行时,就会导致出现空值。建议用描述字符串替换空值(如:Unknown(未知)或Not Applicable(不适用))。某些OLAP产品禁止使用空值属性。
在事实表中也会遇到空值。让事实表非空的方法可通过聚集函数处理,(如:SUM、MIN、MAX、COUNT和AVG等。)如果用零值替换可能会使聚集计算产生倾斜。
其他零售业维度
任何出现在事实表度量事件中的表示单一值的描述性属性是增加到一个已存在维度或自身维度的一个好的选择。有关某个维度是否应该与某个事实表关联的决策应该基于事实表的声明的粒度来确定是或不是。(如:可能由出纳员确定每个事务。对应的出纳员维度可能包含非专属于员工属性的子集。)
一种展现支付方式的更棘手的情况是,也许商店有严格的规则,每个事务仅能接受一种支付方式。作为维度建模人员比较简单的方式是将一个简单的支付方式维度附加到销售模式中,该维度可能包括支付方式描述,以及将支付方式分组为现金等价物或用信用卡支付类型。
每种产品每种支付方式一行这样的方式,不如将支付方式获取到不同的事实表中,其粒度要么是每个事务一行,要么是每个事务的每个支付方式一行。
事务号码的退化维度
零售事实表的每个列表项行都包含POS事务号码。在某个操作型的父/子关系数据库中,POS事务号码是事务头指针记录的键。包括所有将事务作为一个整体的有效信息。在维度模型中,已经从其他维度获得了该头指针信息。POS事务号仍然有用,因为它可用于分组键,将购买的所有产品放在一个单一的市场购物篮事务中。还能确保与操作型系统的关联。
尽管POS事务号码看起来像事实表中的维度键,但是当POS事务维度被清空时,描述性项可能会出现错误。因为产生的维度是空的,我们将POS事务号码称为退化维度。当事实表粒度表示单一事务或事务列表时,退化维度是比较常见的,因为退化维度表示双亲的唯一标识符。
退化维度通常在事实表的主键中起着重要作用。在本案例研究中,销售事实表主键包含退化POS事务号码以及产品键。
*注:操作型事务控制号码,(如:订单号码、发票号码、提货单号码通常产生空的维度并且表示为事务事实表中的退化维度。退化维度是没有对应维度表的维度键。)
实际的销售模式
零售模式的扩展能力
因为POS事务数据在最初建模时就是以最细粒度级别构建的。增加的维度可方便地应用细粒度,不必改变维度键或事实,所有现存的BI应用不需要任何改变,仍然可以运行。
维度模型可预见的对称性确保它们能够承受一些源数据相当显著的变化,以及建模假设为无效的现有BI应用,包括:
新维度属性。如果发现了维度的新文本描述符,可以把这些属性作为新列增加进去。所有现存的应用将可以不受这些属性的影响而继续其工作。如果新属性仅在某特定时间点可用,则老的维度行中将插入不可用或类似的描述。要警告的是,如果商业用户想要根据新确定的属性跟踪历史数据变化,则该场景将更加复杂。
新维度。可在事实表上增加新维度,在事实表上增加新的外键列并将新维度的主键填写到该外键列上。
新可度量事实。如果新的可度量事实可用,可以将它们方便地增加到事实表。最简单的实例是当新事实在同一个度量事件中可用,并与已经存在的事实粒度相同时。事实表被改变,增加了新列,值被填充至表中。如果新事实仅在某个时间点可用,则将空值填充到旧事实表行中。当新的可度量事实以不同粒度出现时,如果新事实不能分配或分派到事实表的原始粒度,新事实应有属于自己的事实表,因为在同一个事实表中出现不同的粒度是错误的。
无事实的事实表
在促销范围事实表中,将为每天(或每周,如果促销是为一周为持续期的话)每个商店中促销的产品加载一行,无论产品是否卖出。事实表能够确保看到被促销定义的键之间的关系,与其他事件例如产品销售无关。我们将其称为无事实的事实表,因为它没有度量结果,仅仅获得所包括的键之间的关系。为了便于计算,可以包括虚拟事实,(如:本例中的促销计数,它始终包含常量值1,这是一种包装方法,可使BI应用避免对外键计数。)
为确定当前促销的产品中哪些尚未卖出,需要两步过程:首先,查询促销无事实的事实表,确定给定时间内促销的产品。然后确定通过POS销售事实表哪些产品已经卖出去了。多维度数据库通常包含未发生行为的确切值。
维度与事实表键
维度表代理键
维度表的唯一主键应该是代理键而不是来自于操作型系统的标识符,也就是所谓的自然键。代理键有许多其他的称谓:无意义键、整数键、非自然键、人工键和合成键等等。代理键简单地以按照顺序序列生成的整数表示。产品行的第1行代理键为1,则下一产品行的键为2,如此下去。代理键的作用仅仅就是连接维度表与事实表。列名带有Key后缀的,表示该键是主键(PK)或外键(FK),表示可能是代理键。
注:数据仓库中维度表与事实表的每个连接应该基于无实际含义的整数代理键。应该避免使用自然键作为维度表的主键。
最初,利用操作型自然键作为维度模型的主键实现起来可能比较便捷。但从长远来看,使用代理键的效果会更好。使用维度表代理键的优点如下:
1.为数据仓库缓冲操作型系统的变化。代理键确保仓库小组维持对DW/BI环境的控制,而不受制于生产代码的建立、更新、删除、循环、重用等操作型规则。在许多组织中,历史的操作型代码,(如:不活跃的账户号码或废弃的产品代码,经过一段休眠期后,可能会被重新分配。长时间不用重新使用,操作型系统不会停止运行。)但对DW/BI系统来说,可能需要保存数据许多年。代理键为数据仓库提供了一种机制,用于区分同一个操作型账号的两个不同的实例。若仅依赖操作型代码,可能在获取或整理数据时遭遇键重叠的问题。
2.集成多个源系统。代理键能够确保数据仓库小组从多个操作型源系统中集成数据,即使它们缺乏一致性的源键,通过后端整理,建立交叉引用映射表可将多个自然键连接成为一个公共的代理键。
3.改进性能。代理键是尽可能小的一个整数,这样确保方便地适应未来预期的粒度变化(维度行的数量变化)。通常操作型代码是庞大的字母数字组合串,甚至是由一组字段组成。事实表中的代理键越小,事实表的索引就越小,能够一次输入-输出更多的事实表行。
4处理空值或未知条件。特定的代理键值用于记录不涉及操作型代码的维度条件,(如:非促销条件或匿名客户)。可分配一个代理键区分这些缺乏操作型代码的情况。
5支持维度属性变化跟踪。一种主要的处理维度属性变化的技术需要代理键处理单一自然键的多个轮廓。伪代理键简单地将自然键粘接到一起,增加一个时间戳,这种方式存在危险。需要避免多个维度和事实表的连接。有时称为双筒连接,主要原因在于这样会降低性能和易用性。
需要在ETL系统建立并维护交叉参考表,用于以代理键替代每个事实表和维度表行。
维度中自然和持久的超自然键
由操作型源系统分配和使用的自然键使用其他名称,(如:业务键、产品键和操作键等。在书中,它们用NK标识表示。)自然键通常被建模为维度表的属性。如果同一个实体在两个操作型源系统中表示,则可能在维度中存在两个自然键属性,表示不同系统的实体。操作型自然键通常组成有意义的组合键。
在跟踪维度表属性变化时,重要的是能够确定一个标识符用于唯一地和可靠地区分维度实体的属性变化。如果维度的自然键没有受到完全的保护和保存,ETL系统需要分配永久的持久性标识符,也被称为超自然键。持久的超自然键被DW/BI系统控制并在系统生命周期中保持不变。类似维度代理键,它是一种简单的整数序列分配方法。
退化维度的代理键
通常不会给退化维度分配代理键,但每种环境下仍然需要评估以确定是否需要。如果事务控制号在跨多个本地系统或重用时不是唯一的,则需要分配代理键。(如,销售商的POS系统可能不会为多个商店分配唯一的事务号。)最后,与BI工具的能力有关,需要分配代理键(建立关联维度表)以横向钻取事务号。以此方式对应维度表建模的控制号维度不在退化。
日期维度的智能键
日期维度具有特殊的特征和需求。日历日期是固定的预先确定的,不需要担心删除日期或处理新的,未预见的日历上的日期。因为日期维度具有可预测性,因此可以在日期维度中使用更加智能的键。
如果序列整数作为日期维度的主键,则该键应该按照时间先后顺序分配。
日期维度的主键是一个有意义的整数,其格式为YYYYMMDD。事实表的YYYYMMDD键的过滤对可用性和性能具有决定性影响。对日历属性的过滤和分组发生在维度表,而不应该处于BI应用的代码中。
YYYYMMDD键可用于分区事实表。分区确保能够将表划分为更小的表。按照日期对一个大的事实表进行划分是可行的,可以移除旧数据,加载新数据,索引当前分区,二不需要操作事实表的其他内容,减少了加载、备份、归档以及查询响应的时间。如果日期键是有序的整数,年按照增量1到希望的年份,月从1到12等等,则可以直接用程序更新和维护分区。使用智能YYYYMMDD键提供代理,将使分区的管理更加方便。
事实表的代理键
事实表中的代理键通常只是对后端ETL处理有帮助。如前文所述,事实表的主键通常包括表外键的子集以及退化维度。
事实表代理键是一个简单整数,不包含任何业务含义,按照事实表行顺序分配。事实表的代理键的确可以带来以下的利益:
1.直接的唯一标识。单一事实表行可以由此键直接获得。在ETL处理过程中,不需要查询多个维度就可以识别出特定的行。
2.返回或恢复海量加载。若某一加载涉及大量的行,这些行带有顺序分配的代理键,在完成前过程停止,则通过观察表的最大键,数据库管理员能够准确地确定过程在何处停止。数据库管理员可以不执行完全加载,只定义一个需要加载的范围键,或从正确的点重新开启加载过程。
3.插入加删除的替换更新。事实表代理键成为事实表中真正的物理键。不再是仅仅由一系列维度外键组合而成的事实表键,至少到目前为止与关系数据库管理系统有关。因此它可能采用插入加删除的方式替换事实表更新操作。
4.使用事实表代理键作为父/子模式中的父节点。一个事实表包含的行是另外粒度更细的事实表的父指针。父表中的事实表代理键也会暴露在子表中。使用事实表代理键而不使用自然父键与在维度表中使用代理键一样都存在争议。
抵制规范化的冲动
具有规范化维度的雪花模式
带有重复文本的扁平非规范化维度表使来自操作型世界的数据建模者非常不舒服。
规范化的维度表被称为雪花模式。冗余属性从扁平非规范化维度表中移除,放置于不同规范化的维度表中。
雪花模式是维度建模的合法分支,然而,建议您抵制采用雪花模式的冲动主要出于设计动机:易用性和性能。
1.众多的雪花模式表构成了一个复杂的结果。
2.多数数据库优化器也要考虑处理雪花模式的复杂性。
3.与雪花模式维度表有关的磁盘空间节省问题并不是非常明显。
4.雪花模式对用户浏览维度的能力具有负面影响。
5.如果仅希望获得分类描述列表,雪花模式产品维度表非常不错。然而,如果想要浏览分类中的所有品牌,则需要遍历品牌和分类维度。如果还希望获得分类中每个品牌的包装类型,则需要遍历更多的表才行。
6.最后,雪花模式无法实现位图索引。
注:固定深度层次在维度表中应该被扁平化。规范化雪花模式维度表不利于多属性浏览并妨碍了位图索引的使用。通过规范化维度表所节省的磁盘空间通常不会超过整个模式所需要空间的1%。应该知道牺牲一些维度空间有利于改善性能和可用性。
过去,一些BI工具对雪花模式带有一种偏好,雪花模式解决了BI工具的特殊需求。同样,如果所有数据都通过OLAP多维数据库发布给商业用户(雪花模式用于装载多维数据库,但对用户来说是不可见的),则采用雪花模式是可以接受的。
支架表
为某个事实表范围之内的维度建立附加的支架维度,如下图。在该例中,“一旦删除”支架表示日期维度,该维度与主维度呈雪花模式。支架表日期属性具有描述性的独特的标记用于区分与业务过程有关的其他日期。只有当业务希望按照非标准的日历属性(例如,财务周期、商业日期)过滤将日期属性作为产品维度中的标准日期类型列对待。如果使用了日期支架,注意当标准日期维度表按照范围存储时,支架日期将发生错误。
支架表可以节省空间并能够确保相同属性被一致地引用。缺点:支架表引入了更多的连接,连接严重降低了系统的性能。支架表不易用户理解,限制了用户在单一维度中浏览属性的能力。
【警告】尽管可以使用支架表,但出于对其潜在影响考虑,维度模型尽量不要大量使用支架表。
包含大量维度的蜈蚣事实表
维度模式中的事实表自然地具有高度规范化和紧凑的特性。无法进一步规范化事实表键之间的极端复杂的多对多关系,因为维度之间不是相互关联的。
尽管存在规范化维度层次的难以控制的期望,但是知道雪花模式是存在问题的。因此通过加入事实表消除了规范化表。不是在事实表上建立单一产品外键,他们将产品层次上频繁分析的元素也当成外键,(如,品牌、分类、部门等等)。原先紧凑的事实表变成连接大量维度表的奇形怪状的怪物。我们将这样的设计称为蜈蚣事实表。
即使有紧凑的格式,事实表也是维度模型中的巨兽。包含太多维度表的事实表设计,将导致事实表需要更多磁盘空间。在蜈蚣表实例中,无法实现多对多部分构成的键构建有效的索引。
多数业务过程可以用不超过20维度的事实表表示。如果某个设计有25个或更多维度,应该考虑采取措施合并关联的维度。在产生的新维度比不同维度的笛卡尔积小很多的情况下,可以考虑合并这些维度。
注:大量的维度通常表明某些维度不是完全独立的,应该合并为一个维度。将同一层次的元素表示为事实表中不同维度是维度建模常见的错误。
列数据库开发可以减少与蜈蚣事实表有关的查询和存储的负担。不是将表的每行都存储,列数据库将表列作为连续对象存储,表列建立了索引。即使基本的物理存储时按列存储的,在查询级别上,表仍然按行方式显示。列数据库更有利于处理前面讨论的蜈蚣表。
小结
在处理维度模型设计时采用4步过程方法。注意清楚地声明与维度模型关联的粒度是特别重要的。加载事实表时,获取原子数据将会带来最大的灵活性,因为可按任何可能的方式对数据进行汇总。