数据仓库的逻辑设计
基于维度的模型
数据仓库设计的理念就是去解决业务的问题。在大多数情况下,业务人员和执行人员关心的是从某些角度(产品,客户,雇员,时间)来聚合有意义的值(销售额,成本,收益)。从这个角度出发,他们需要知道的基于的这些角度我们就称之为维度。
星型模型
一种传统的设计模式(star schema)
- 相关的维度值被设计在一个或者多个维度表中
- 相关的度量值被设计在一个或多个事实表中
- 事实表和维度表通过一个外键关联
通常来说,一个事实表会与多个维度表相关联,维度表围绕在事实表的周围,像星星的节点一样,因此我们称这种模型为星型模型
维度表的注意点
- 非范式化
众所周知,在OLTP系统中的三个范式,就是为了消除冗余和重复字段的。好处是当有更新或者删除的时候可以最小化修改的记录条数以及节省磁盘空间。但是在OLAP系统中数据通常是很少改动甚至不改动的,使用者通常情况下更关心的是效率的问题。在这样的前提下,OLAP的架构应采用非范式化的设计,表尽量的宽,尽量使用重复字段而不使用join去进行表连接。
- 键
在维度表中,每一行记录都应该使用一个主键来标识。通常情况下,维度表的数据来源于应用程序,这些表里面已经有主键标识了。在数据仓库中,这种来自原有的表的主键我们多数把它设置为业务主键(business key)。
沿用原表中的键来作为数据仓库表中的主键,看起来很明智,但是实际上,我们更倾向于设计一个新的键来作为主键我们称之为代理键(surrogate key)。我们使用代理键基于以下原因:
- 维度表的数据可能来自于多个系统,这样的话,无法保证数据的重复性设置是数据类型
- 源表中的键可能是很复杂的字符串或者GUID,数字型(int)的变量能提供更好效率,尤其是维度表和事实表一定会进行join的操作。
- 由于数据仓库储存的是历史数据,而且有预期变化的时候我们还是需要历史数据。例如:张三从北京调到了天津,张三原来的销售业绩我还是希望算在北京区里面,之后的算在天津。但是如果是用原来的主键的话,就没办法把张三这两个时期的销售业绩区分开了
基于上述, 我们通常使用代理键(surrogate key)来作为主键,同时我们保留业务主键(business key)作为一列作为备用,这个时候我们称业务主键为备用键(alternative key)
事实表的注意点
- 粒度
粒度就决定了你需要聚合的基础。所有的聚合数据都是基于最细的粒度,使用维度来进行聚合。实际上,由于业务的需求,很多事实表都需要基于不同的粒度建立。
- 键
事实表的主键通常是包含了链接到维度表外键的联合主键。某些时候我们也会在主键里包含一些业务字段来达到唯一的目的。
- 度量值
度量值通常分为以下三种:
- 可以累加的值
- 不可以累加的值,例如百分比
- 部分可以累加的值,可以基于某些维度聚合而另外的不可以
雪花模型
事实表连接的维度表都是非范式化的结构我们称之为星型模型。相反,有些情况下,维度表也是基于范式来设计的,这种情况下的模型,我们称之为雪花模型。在以下情况里面,可以考虑雪花模型:
- 有某个子维度关联到多个维度
- 有某个维度里面几个字段经常会修改
- 一个疏散的维度表内包含太多的子类,例如:产品维度,有些属性是所有产品共有的而有些产品有大小,颜色,其他的却没有
- 当多个不同粒度的事实表链接到一个维度表中的不同层次的时候
时间维度
时间维度通常在数据分析和展现的时候都会存在。当你要建立一个时间维度的时候,你需要注意以下的方面,
- 在一个适当的粒度下建立
- 包含时序层次
- 包含业务所需要的时间层次
- 考虑怎样生成一个时序维度的时候,通常不是从数据源中抽取出来,而是基于时间本身创建,因此
- 通过T-SQL语句来创建,使用函数datepart,datename,month,year等
- 使用excel包含的方法创建
- 使用BI工具创建
数据仓库的物理设计
数据的物理存放
数据仓库的设计中,物理存放占据很重要的部分,直接影响到执行查询的速度和效率,在制定一个数据仓库的设计的时候,我们需要考虑以下几点:
- 源于SQLServer多线程的技术,可以将数据分布式的存放到多个存储中,使用RAID技术来分别存放,或直使用SQLServer中的文件以及文件组的概念去分别存放
- 将日志文件单独区别存放
- 将临时表和文件单独存放,减少因为重建和删除产生的索引碎片
- 预先分配空间以及禁止自动增长
索引
大家应该都了解,使用索引可以大大的减少查询时间。因此在数据仓库中使用合适索引也是非常必要的
- 维度表索引
- 在代理键上建立非聚集索引
- 在业务键(备用键)上建立聚集索引
- 在经常使用查询过滤的列上面建立非聚集索引
- 事实表索引
- 由于几乎所有的事实表都基于时间,并且会按时间来进行分区,所以在时间列上建立聚集索引
- 在各个外键上面建立非聚集索引
列存储索引
SQLServer提供了新的基于xVelocity压缩技术的列存储索引,但是注意使用
- 每个表只能使用一个列索引
- 加了列索引的表变为只读
- 在表分区上建立列索引只能基于分区字段
- 只能在表上建立(视图不可以)
分区
数据仓库通常用来存储海量数据,做分区有以下好处
- 提高查询效率
- 加快数据加载和删除
- 提高索引管理性
- 增加备份和还原的灵活性
数据压缩
数据压缩可以减少磁盘存放空间,提高IO查询效率,在IO作为当今IT的最大瓶颈的情况下,压缩是非常必要的
数据压缩的形式
- 行压缩
- 页压缩