1、分析型数据库与维度设计
1.1 维度设计
信息系统主要分为操作型系统(专注业务系统的执行)和分析型系统(专注业务系统的分析)。维度设计的理念直接来源于分析系统的需求。
操作型系统就是OLTP(联机事务处理),简称事务系统。最佳的模式设计方法是3NF,采用E-R模型来描述,数据库事务处理具有ACID特性,即原子性(atomicity)、一致性(Consistentency)、隔离性(isolation)、持久性(durability)。
分析型系统专注于查询(而不是增删查改),而且会聚合多个事务(而不是单个事务)。
度量和环境构成维度设计的基础,维度设计方案对业务过程的描述都是通过获取度量内容和度量所在的环境来构建的。度量称为事实,环境称为维度。维度设计时,需要将信息需求分类到事实和维度中。
在关系型数据库中维度和事实的组织方式称为星型模型,在维度数据库中,被称为多维数据集。
1.2 星型模式
星型模式主要由事实表和维度表构成。
维度表包含表示维度的列,也称为维度或维。每个维度表都分配有一个代理键(维度表的唯一标识),代理键无内在含义。维度表中用于唯一区分实体的键列称为自然键(操作型系统区分唯一实体的键),同时保存自然键和代理键的意义是,可以保存操作系统的历史。操作系统更新时,自然键保持不变,但是我们在维度表中会生成一个新的代理键(自然键一样),这样就可以区分历史。
缓慢变化维度(SCD : Slowly Changing Dimention)
事实表的行存储特殊级别的细节事实,细节的级别称为事实表的粒度。
1.3 星型模式的应用
展示事实表数据的能力主要受限于事实存储的细节级别(粒度),只能获取更粗粒度的数据(通过维度汇总获取),而不能获得更细粒度的数据。
浏览是在维度内探索数据的活动。这个概念也很简单,在确定查询层次和结果时,先浏览每个维表中都包含哪些数据(也就是所有可能的维度),这样方便后续查询、报表的设计。
1.4 指导原则:
参照精度和性能两个指导原则。
2、数据仓库体系结构
2.1 Inmon的企业信息化工厂:
Bill Inmon提出了企业信息化工厂。企业数据仓库是企业信息化工厂的核心枢纽。Inmon主张数据集市中采用维度设计方法,从企业数据仓库的原子表示中聚集数据。
2.2 Kimball的维度数据仓库:
Kimball的两个主要贡献:
1).维度设计为数据库分析和开发提供了一种有效和可行的方式。
2).开发了一种基于维度设计的企业体系结构,也成为“总线体系结构”。维度数据仓库体系结构。
Kimball的数据仓库体系结构与Inmon数据仓库体系结构的2个区别:
1).维度数据仓库是根据维度建模的原则来设计的(Inmon遵循ER模型原则)。
2).维度数据仓库也许能被分析型系统直接访问(Inmon需要访问Data Mart)。
2.3 独立数据集市:
独立型数据集市是一个分析型数据存储,并不是在企业环境中被设计的,只关注于某个主题区域。在短期内获得快速、廉价的结果,但会导致长期费用的提高和效率的低下。
独立型数据集市将导致“信息孤岛”,每个独立主题域都有各自的数据格式,ETL加载流程,合并起来困难。由于独立型数据集市只关注有限的范围造成的缺陷。
2.4 体系结构和维度设计:
两种企业体系结构的相同点,在于他们都有一个独立的原子数据的集成仓库,在企业信息化工厂中叫做企业数据仓库。在维度数据仓库中叫做维度数据仓库。
3、星型模式与多维数据集
3.1 维度表特性
3.1.1 代理键和自然键
维度表的每一行都有一个唯一的代理键与之对应,维度表中的每一个代理键都标记为“SK”,自然键标记为“NK”。
为了代替代理键,可以尝试使用“自然键+序列号/时间戳”的联合多字段的方式,但是这样需要在事实表中也相应修改,维护起来很麻烦。不如使用代理键。
3.1.2 丰富维度集合
为了丰富维度表中的维度,可以从源库中一个维度字段拆解组合出多个维度字段。例如,源库中有一个region_code字段是07-701,可以由这一个字段拆解出:region_code(07-701),country_code(07),territory_code(701),country_name(United States),territory_name(East)。
在源系统中,事实表一般只保存一些code(例如business_type),而不存描述。从分析应用角度考虑,代码和描述都是可用的维度,都可以存(其实就是冗余存储,没啥新东西)。
标志位的存储,在源系统一般存(1,0)或者(Y,N),这种不太容易理解需要查码表,可以在维表中直接存(credit card -1 , not credit card -0)这样更容易理解。
基于事实计算得到的维度称为行为维度。例如:消费在100-1000元的消费者分组,这种维度。
3.1.3 维度表中的组合维度
具有相似属性的维度可以分配到同一张维度表中去,同时,也可以将很多杂项维度组合成一个杂项维度表,该维度表不设置自然键,只设置代理键关联到事实表。
雪花模型可以去除维度表中的冗余,例如产品维度表中,每一行产品都保存品牌属性,其实是重复的。如果想去掉重复可以再建一个“品牌表”,而产品维度表中只保存外键,这时,这个品牌表就称为支架表。
数据冗余可以带来三个好处:性能、一致性和可用性。(一致性指:如果同时存代码和解释,就可以省去关联,降低维度不一致的风险)
技巧:
1)为每个维度表分配一个代理键。
2)提供丰富、全面的维度属性集合,每个新增的属性都会显著提高分析的可能性。
3)对于数字型数据,想要区分其是维度还是指标是比较困难的,如果一个元素用于过滤查询、排序数据、控制聚集、区分主从关系的话,应该就是维度。
4)不要采用规范化理论指导维度设计工作。分析型数据库很难从这些技术中获取帮助。需要采用雪花模型和支架表的情况是一种特例而不能当做规则来使用。
5)在维度设计中应该容忍冗余的存在,详尽的存储每一个维度属性将大大提高系统性能,增强可用性,确保在多个应用中保持一致。规范化理论(3NF)更适合于操作型系统而不是分析型系统。
3.2 事实表特性
事实表记录信息的细节程度称为粒度,明确每个事实表的粒度至关重要,避免包含不同粒度的情况。
3.2.1 事实表与过程
事实采用外键为每个度量提供维度环境,某些情况事实表可以包含维度。如下例,product_key是外键(也是维度表代理键),order_cnt和price是度量。
product_key | date_key | customer_key | order_cnt | price |
---|---|---|---|---|
102291 | 20190603 | 53 | 10 | 786 |
203278 | 20190603 | 72 | 30 | 637 |
451145 | 20190603 | 13 | 45 | 129 |
3.2.2 获取事实
事实表中有一些度量是非可加事实。例如利润率这个指标,我们在上卷聚合时,不能把利润率做简单相加向上层汇总。处理这种问题的方法是,在事实表中保存利润额度和订单额度,这2个事实是可加的,汇总后相除得到聚合后的利润率。
3.2.3 粒度
尽可能将事实表的粒度设置为最详细的数据粒度级别。
3.2.4 稀疏性
出现在事实表中的维度值组合数量远远小于可能存在的组合数量,这个性质称为稀疏性。例如,某客户未在特定的一天从特定销售商购买特定产品,导致事实表中无这些维度组合的订单数据。
3.2.5 退化维
有时候,不能将与业务相关的很多维度存到同一个维表中,而需要将一个或者多个维度存到事实表中,这种存储到事实表中的维度称为退化维度,简称退化维。
虽然存到事实表,该列仍旧是维度,不是度量。
3.3 缓慢变化维
采用维度设计方案时,确定数据源的变化在维度表中如何表示十分重要,称为缓慢变化维。相比于事实表,维度表的变化相对缓慢,这也是名字的由来。缓慢变化类型主要包含3种。
3.3.1 缓慢变化类型1
当一个维度值变化时,不需要在星型模式中保存历史,直接覆盖维度表的值即可。这种使用场景常常是修正错误。举例说明,在客户维表中保存了客户的生日,假设之前客户生日输入有误(生日是不可能变的),可以直接更新。
这种情况下,维表改变时,代理键和自然键都不变,直接用新的生日信息覆盖原来的信息。
变化类型1可能会导致报表数据不一致。除此之外,变化类型1还存在不能追踪维度历史的问题,鉴于此,应该尽量避免使用变化类型1。
3.3.2 缓慢变化类型2
多数情况下使用变化类型2,可以追踪维度历史。
采用类型2时,在维度表中会新插入一条数据,这条数据自然键customer_id还是不变的,但是代理键是全新的。这样事实表中,历史数据行保存的仍然是历史版本代理键的维度行,这就保证了,历史的事实数据与历史的维度关联,新的事实数据与新的维度关联,保持事实环境的清晰。
按照上述的做法,虽然保存了事实(表)的历史环境。但却未保存维度历史,在维度表中保存了2条自然键一样的记录(代理键不一样),用户无法判断哪一条客户信息才是准确的。
此问题可能通过为不同版本维度数据添加时间戳的方式来解决,后续再进行深入介绍。
3.3.3 选择并实现响应类型
考虑上述两种变化类型,我们可以对维度表中的每一个属性进行定义,定义这个属性是属于变化类型1还是变化类型2,并在设计文档中体现。具体的以上边为例,客户的生日属性选择变化类型1更合适,而客户的家庭住址使用变化类型2就更合适,下表简单列出2种类型的区别,可以根据实际情况选择:
变化维类型 | 操作 | 对事实表的影响 |
---|---|---|
变化类型1 | 更新维度 | 重新声明历史 |
变化类型2 | 在维度表插入新行 | 保留历史 |
缓慢变化维对ETL的处理来说非常复杂,也是设计中需要重点关注的地方。
3.4 多维数据集
多维数据库(MDB)以一种称为多维数据集的方式存储维度信息。通过预先计算维度值和事实值方式获取各种组合值,以进行交互研究。
多维数据库主要优势在速度。交互过程称为OLAP,当执行切片、切块、向上钻取、向下钻取时可以获得即时反馈。但这种优势也需要付出代价,需要预先计算和存储,会消耗很多计算和存储资源。
通常采用多维数据集取代关系存储作为主要数据存储,应用于数据集合比较小的特定主题区域。
技巧:一般关系存储和多维数据集一起使用,发挥各自的优势。星型模式作为原子数据的集成仓库,而多维数据集作为数据集市。
4、过程处理中的事实表
一般企业的业务都会比较复杂,很难使用一张事实表覆盖所有业务过程。在维度设计时,可以为每个待处理业务过程构建单个事实表。
4.1 事实表与业务过程
一个重要的技巧是:为了便于独立的分析研究,应为每一个过程建立一个事实表。那么问题来了,该如何界定每个过程的范围呢?一个过程是否应该切分成多个子过程呢?例如,一个打车的业务过程,可以细分为提单、接单、司机接驾、司机送架、结算等子过程。
技巧:对于给定的2个事实,提出2个问题:
(1)这些事实同时发生吗?
(2)这些事实可以用于同一个粒度上吗?
如果2个问题,有一个回答是否定的,就可以界定为2个过程。
4.2 具有不同时间的事实
如果描述事件的两个或两个以上的事实不在同一时间发生时,这些事实描述的就是不同的过程。
将多个过程放入单一的事实表会出现问题,如果仅仅需要研究某一个过程时,将会出现大量无关行,反应到汇总报表上就是,出现了大量0值的事实数据。
该种场景的另一种有缺陷的设计方案是:仅仅记录一个通用事实(在事实表中不区分该指标是表示订单量还是发货量),而通过建立一个新的维度来判断它是表示一个订单还是一次发货。
4.3 具有不同粒度的事实
4.4 从多个事实表中分析事实
在比较多个过程的事实时(来自不同的事实表),应该采用称为横向钻取的包含2个步骤的过程获取,与上钻和下钻无关,描述的是跨越一个星型模式到另一个星型模式的步骤。
可以认为维度表和事实表具有父子关系,其中维度表是父表。如果一个维度表与多个事实表关联,事实表中的行就可以视为具有兄弟关系。
4.4.1 直接连接事实表的危险
从多个事实表分析事实时,直接关联事实表是不可取的,如果某个事实表中的维度键重复(例如某个产品提了2个订单),关联会造成笛卡尔积进而造成结果错误,当然也有可能丢掉数据。
比较两个过程的适当方法是横向钻取,由多个查询实现。
4.4.2 横向钻取
在比较多个事实表时,应该使用横向钻取。
横向钻取主要包含2个阶段:阶段一是应用适当过滤器从每个事实表检索事实,并按照维度细节需要的层次输出结果(实际上是各个事实表先各自按照同样的维度聚合)。阶段二将中间结果合并(通常使用full join来实现,以保证包含每个结果集中的所有数据)。
参与横向钻取的事实表没必要在一个数据库内,甚至可以是不同类型数据库。不难发现,各个事实表的维度“同义性”对横向钻取十分重要,这也是一致性维度的概念。维度的一致性是确保能跨越多个星型模式甚至多个主题区域开展分析工作的关键。
4.4.3 横向钻取的实现
第一种实现方式的名字是过程划分。其实理解起来非常容易,将过程划分为RDBMS环境和报表环境。第一阶段放在RDBMS端执行,按维度聚合的结果发送到报表服务器上;第二阶段的合并操作在报表服务器端来完成。
第二种实现方式的名字是使用临时表。同样划分RDBMS和报表环境,第一阶段的聚合后的结果这次存在RDBMS的临时表中,第二阶段的合并操作也在RDBMS中执行,只是最终合并后将需要的信息发送给报表服务端。可见,这种方式的计算都在RDBMS端。
第三种实现方式的名字是平衡SQL。这种方式与第二种相比及其相似,唯一的区别是不使用临时表。
当采用的工具不支持横向钻取,或者当横向钻取性能不佳时,可设计并建立按照共同的细节(维度)层次汇总过程的合并事实表。采用合并事实表的方式执行横向钻取的工作,不过应该是在ETL期间完成,并不是在查询时候完成。
5、维度一致性问题
5.1 星型模式之间的协同
使用单个主题描述企业所有业务流程是不切合实际的,实际的做法是:将企业划分为主题区域,并将主题区域划分到不同的主题。
星型模式具有两种分析型效益,第一种就是分析通过星型模型度量的商业过程。第二种是结合分析多个星型模式(业务过程)的度量。
表示不同过程的星型模式通过公共维度实现互联。理论上讲,任何两个链到同一维度的事实表都可以用横向钻取技术来比较。
当一系列星型模式共享一组公共维度时,所涉及的维度称为一致性维度。
5.2 维度和横向钻取
支持横向钻取时,多维表不需要完全相同,当一个维表的属性是另一个维表中属性的子集时,横向钻取也是可以实现的。
5.2.1 造成横向钻取失败的原因
一致性的基本要求:
1.结构相同:在结构方面,表必须具有相同的维度列集合(不一定是所有维度列,部分即可),而且对应的维度列应该具有相同的列名和相同的数据类型定义。
2.内容相同:在内容方面,维度列中存在的值必须有相同的表示形式,保证合并操作需要的列值的同一性。
5.2.2 维度表不必相同
可以在维度表中找到一样的维度属性,并各自按照这个维度聚合,最终合并结果即可。
5.3 一致性维度
当维度表具备支持横向钻取需要的一致性时,称其为一致性维度。
5.3.1 维度一致性的类型
维度表能以多种方式保持一致。包括:共享维度、一致性上卷。
1.共享维度:
必须具有之前讨论的特性,维度表具有相同的结构和内容。可以是事实表共享同一个维度表,也可以是事实表共享同一个事实表的副本。
技巧:当一个共享维度存在多个副本时,需要一个单独的ETL过程负责处理新的和发生改变的数据。这工作比较困难,但是非常重要。
2.一致性上卷:
保持维度一致性并不需要维度表完全相同。满足下边条件也可:
(1) 表的维度属性是其他表的维度属性的子集。
(2) 公共维度属性具有相同的结构和内容。
两个维度中较小的那个叫做一致性上卷。较大的叫做基本维度。
当来自某个表的维度属性是其他表的维度属性的子集,并且公共属性包含相同的结构和内容时,这个表包含的子集称为一致性上卷。
在ETL时,确保一致性上卷的实例值与基本维度的实例值匹配的最好方式是指定基本维度作为他们的来源。
3.一致的退化维度
退化维度通常用来标识事务或者文档。相同的退化维度可以在多个事实表中出现。例如订单事实表和发货事实表都可存储订单号(order_id)和订单组号(order_line_id)这2个退化维度。
同样地,如果退化维度也符合公共维度具有相同结构和内容的要求,那么也可以进行横向钻取。
4.重叠维度
两个维度表共享一组公共属性,也就是说两个维度表A和B,他们之间有交集(共同的属性),但是他们各自都不会包含于对方,所以两个表都不能被描述成一致性上卷。
当2个维度重叠时,将通过他们的公共属性保持一致性。重叠维度表通常需要不同的ETL过程来维护,所以有加载不一致的可能性。基于此,应该尽量减少使用重叠维度。 那么该怎么办呢?
可以生成第三个表来避免重叠。删除两个表的公共属性并将它们放在第三个属性表里,但这种方法在找维度表原始字段与删除的公共属性字段时比较麻烦。
5.3.2 规划一致性
1.一致性设计
一致性是维度设计的中心问题,通常以矩阵形式文档化。描述一致性维度的较好的方式是矩阵图,列代表核心一致性维度,行代表不同的过程或事实表,可通过在适当的交叉点放置检查标志来阐明一致性。退化维度也应该出现在矩阵图中。
一致性矩阵不需要包含数据仓库的所有维度,只需要包含那些连接不同事实表分析的关键维度即可。也可以使用额外的主题区域矩阵来补充高层次一致性矩阵。
2.增量实现
5.4 结构与一致性
5.4.1 维度数据仓库
维度模型的一致性框架,可以成为一致性总线。一致性总线使得维度模型可以满足每个主题区域的需要,同时也保留了比较主题区域的能力。设计过程还需要包括为每一个一致性维度确定源系统和加工规则,只有这样才能确保对来自不同源系统的数据的集成。
在维度数据仓库中,维度设计时战略活动。一致性维度是这种设计的中心特征,提供企业级能力。如果前期的一致性维度设计工作合理,后期可以平滑的上线新的项目,并不会出现冲突,而且方便比较。
5.4.2 企业信息化工厂
1.数据集市中的一致性问题:
数据集市内部的一致性问题,主要解决的是存在于企业关键商业实体之间的不同视图,有时甚至是冲突的视图。即使集市内一致性构建压力较小,但是还是应该保证好一致性维度的各种文档,这样可以方便与其他部门进行比较工作。
2.跨数据集市的一致性问题:
6、深入学习维度表
6.1 将维度分组到表中
多数对应分析类别的维度表具有深刻业务特征,初步可按照业务特征来分组。但是,维度模型不能揭示相互关联的属性之间存在的关系。
6.1.1 关联维度属性的两种方法
在星型模型中,给定的一对维度属性的相互关系可能以明确的或隐含的方式被表达出来。其中,明确的多样性关系是指,它们(给定的一对维度属性)通过与事实表相交的形式出现,提供关系的重要环境。隐含关系是指,当两个属性在同一个表中时,就可能存在隐含关系,隐含关系意味着属性间存在天然的相关性,而不是存在于多个环境中的关系。
6.1.2 对维度分组时的考虑
要确定两个维度是否属于同一维度表,最好方法是考虑属性在何处相关以及在何处使用。那些趋向于共享稳定关系的属性可能被存在一起,那些仅在事件、事务或条件等情况下相关的属性,可以归入到不同事实表。
1.基于亲和性分组:
那些属性自身就有关系(例如产品本身就会属于某个品牌),而不需要事务的发生(订单发生前产品和维度间就有关系了)来串联起这2个维度。
2.可浏览性测试:
6.5 行为维度
使用过去的行为模式来理解当前行为的强大分析技术。行为维度将事实转化成维度,以确保获得强大分析能力。
6.5.1 在查询期间将事实转为维度
使用过去行为制作维度,需要从现存事实表中构建新维度,如果在出报表时计算会比较缓慢。
解决该问题的方法是将现存维度表扩展以包含行为数据,因此额外的ETL需要付出代价。
6.5.2 设计并使用行为维度
1.与另一个维度的过去相连,例如customer维表中,保存first_order和last_order。2.历史事实,例如customer维表总,保存annual_sales数据。3.分类事实,