多维数据库 (Multi Dimensional Database,MDD) 使用 Dimension(维度)和 Cube(数据立方体, 数据集市)模型描述数据.
多维数据模型
关系型数据库 (Relational Database,RDB) 中的星型结构或雪花型结构就是模拟上述多维模型结构的, 但无法提供真正意义上的多维数据分析能力, 这里不做过多解释.
下文讲解 Oracle Essbase 以及 IBM Cogons 这种真正的多维数据库的原理.
多维数据库中模型结构与事实数据分别以概要文件 (profile) 和数据块 (data block) 的形式存在.
profile 和 data block
概要文件用来描述以下信息:
维度和维度成员信息
与维度相关的层级 (Hierarchy) 和级别 (Level) 信息
Cube 的描述性信息, 以及 Cube 与维度的关联性
其他描述性的信息, 如实体模型属性
Cube 中度量数据存放在 data block 中, data block 可以被理解成为多维数组结构, 其大小与相关维度的明细成员数量有直接关系.
计算公式: data block size = 维度 1 明细成员总数 * 维度 2 明细成员总数 * ...... * 维度 N 明细成员总数
数据块容量等于相关维度明细成员数量的笛卡尔积.
数据块大小
明细度量值一般采用 double 类型, 按 8bytes 算, 上图所描述的 Cube 的数据块大小为 480bytes.
除了数据块中的明细度量值外, 其他非明细度量值并没有直接存储, 因为其可以通过对应的明细度量值计算出来.
非明细度量值计算方式
一些不存在的度量值会造成数据空洞问题, 假设 2018 年 4 季度河北省 B 品牌手机的销售量是未知的, 则会在数据块中产生一个空洞.
注意: 数据空洞表示不存在的值, 与数值 0 的意义不同, 数值 0 表示一个有意义的值.
如果数据空洞比较多, 则数据块的数据密度就会下降, 将造成存储空间的浪费.
数据空洞
除了数据空洞问题, 还存在数据爆炸问题. 数据块大小由全部维度明细成员数量的笛卡尔积决定, 假如某个 Cube 关联三个维度, 每个维度明细成员数量均为 100, 则: data block size = 100 ^ 3 = 1000000, 如果度量值按 double 类型存储(8bytes), 数据块文件大约为 7.62M. 如果每个维度明细成员数量增加至 150, 则数据块文件将膨胀到 25.74M(data block size = 150 ^ 3 * 8bytes / 1024 / 1024).
当数据块极度膨胀并且存在很多数据空洞的时候, 会极大地浪费存储空间, 并且可能导致数据存储无法实现.
极度膨胀和存在大量空洞的多维数组
为了解决数据空洞和数据膨胀问题, 引入了密集维度组合和稀疏维组合的概念.
判断维度组合是密集还是稀疏的原则是看其所对应的明细度量值的存在情况, 例如:
北京地区只有 ABC 三种手机的销售额, 天津地区只有 BCD 三种手机的销售额, 河北地区卖出的手机只有 AE 两种, 表明并不是每个地区对于每一种手机都有销售额, 所以地区与产品属于稀疏的维度组合.
2018 年的四个季度都有手机销售额, 所以日期维度自身可以构成密集的维度组合.
注意! 在其他讲解多维数据库的文章中都把维度分为稀疏维与密集维, 这是非常错误的, 对于维度本身来讲没有稀疏与密集之分, 稀疏与密集表示的是维度之间的组合! 对于有 N 个维度的 Cube 而言, 如果其只有一个维度退化成索引, 或者有 N - 1 个维度退化成索引, 则此时稀疏与密集的维组合只包含一个维度, 但这只是一种特例, 并不代表维度本身是稀疏或密集的.
在引入稀疏与密集的维度组合之后, 原本由于数据空洞和数据爆炸而失控的数据块结构将变成索引和密度相对较高的小数据块结构.
索引和小数据块
之前数据文件大小为 3 * 4 * 5 = 60, 结构变换之后每个小数据块大小为 4(共 8 个), 在不计算索引所占存储大小的情况下, 存储容量变为原来的一半.
度量值的变化可能引起稀疏维度组合和密集维度组合的改变, 如下图所示.
重构
虽然解决了数据空洞和数据爆炸的问题, 但稀疏与密集的维组合所带来的负作用是一旦度量值的变化导致了数据块密度中心的改变, 相关的索引和子数据块必须重构, 而这种重构的性能代价与时间成本是极为昂贵的. Cogons,Essbase 等传统多维数据库以及其他 MOLAP 都存在此问题.
基于矢量计算引擎 (Vector Calculation Engine) 的新型分布式多维数据库很好的解决了数据重构问题.
矢量计算引擎将海量数据的运算从多维数据库核心分离出来, 进而将多维分析时的逻辑运算与聚集计算解耦. 多维数据库核心只负责逻辑运算, 完全不需要再考虑数据量的问题. 矢量计算引擎采用极为简单的数据结构存储 TB,PB 级数据, 并且只负责进行一种算法上极为简单的聚集运算, 针对此种特性, 适宜采用更加接近底层的编程语言进行开发(如 C 语言), 不仅得到了性能上的提升, 也因为数据存储结构的简单而获得了更加稳定的运行效果.
基于矢量计算引擎的多维数据库
如上图所示, 在多维数据库内核角度来看, 矢量计算引擎是更加底层的一种基础服务, 所以可以根据各种应用场景切换不同的实现方式, 而这一切对于多维数据库内核来说都是透明的, 多维数据库本身对更上层的应用提供一致的数据查询能力, 从而更好的支持了 100% 面向业务的探索式数据分析能力.
来源: https://www.cnblogs.com/bgo-tech/p/9824182.html