维度设计

维度的概念

维度是维度建模的基础和灵魂。在维度建模中,将度量称为“事实”,将环境描述为“维度”,维度是用于分析事实所需要的多样环境。

维度表中的列,称为维度属性。维度属性是查询约束条件、分组和报表标签生成的基本来源,是数据易用性的关键。维度的作用一般是查询约束、分类汇总以及排序等。

如何获取维度或维度属性?一方面,可以在报表中获取;另一方面,可以在和业务人员的交谈中发现维度或维度属性。

因为它们经常出现在查询或报表请求中的“按照”( by )语句内。例如,用户要“按照”月份和产品来查看销售情况,那么用来描述其业务的自然方法应该作为维度或维度属性包括在维度模型中。

维度设计方法

数据仓库的能力直接和维度属性的质量和深度成正比。

第一步:选择维度或新建维度,维度作为维度建模的核心,在企业级数据仓库中必须保证维度的唯一性。

第二步:确定主维表,此处的主维表一般是ODS表,直接与业务系统同步。比如商品板块中的商品表。

第三步:确定相关维表。数据仓库是业务源系统的数据整合,不同表之间存在关联性。根据对业务的梳理,确定哪些表和主维表间存在关联关系,并选择其中某些表用于生成维度属性。比如类目、SPU、商家等维度和商品存在关联关系。

第四步:确定维度属性。本步骤分为两个阶段,第一阶段是直接从主维表中生成新的维度属性;第二个阶段是从相关维度表中选择生成。

确定维度属性

  • 尽可能生成丰富的维度属性

    一个维度表有上百个维度属性时,可以为下游的数据统计、分析、探查提供良好的基础。

  • 尽可能多给出包含一些富有意义的文字性描述

    属性不应该是编码,而应该是真正的文字。一般是编码和文字同时存在,比如商品ID和商品标题等。

  • 区分数值型属性和事实

    数值型字段作为事实还是维度可以参考字段的一般用途。如果通常用于查询约束条件或分组统计,则是作为维度属性;如果通常用于参与度量的计算,则作为事实。

  • 尽量沉淀出通用的维度属性

    有些维度属性获取需要进行比较复杂的逻辑处理,有些需要通过多表关联得到,或者通过单表的不同字段混合处理得到,或者对某个字段解析才能得到。此时就需要将尽可能多的通用的维度属性进行沉淀,提高下游使用的方便,减少复杂度,同时避免下游解析时由于逻辑不同而造成的口径不一致。

维度规范化和反规范化

当类目、行业、品牌等属性层次不是被实例化为维表,而是作为维度属性存在在商品维度中,这是商品维度表被称为一个雪花模式。通过规范化处理将重复属性移至其自身所属的表中,删除冗余数据。

将维度表的属性层次合并到单个维度中的操作被称为反规范化。分析系统的主要目的是用于数据分析和统计,如何更方便用户进行统计分析决定了分析系统的优劣。采用雪花模式,用户在统计分析的过程中需要大量的关联操作,使用复杂度高,同时查询性能很差;而采用反规范化处理,则方便、易用且性能好。

使用雪花模型,处了可以节约一部分存储外,对于OLAP系统来说,没有其他效用。

一致性维度和交叉探查

数据仓库总线架构的重要基石之一就是一致性维度。需要保证一类维度只存在一个维度表,避免同类维度表重复出现。例如日志数据域使用商品维度2,交易数据域使用商品维度1,两个维度的维度属性或维度属性存储的字段不一致,进行合并计算时,因为粒度不同造成交叉探查存在问题。

保证一致性维度就需要保证共享维表,所有的数据仓库中的维度表有且只有一个。

同时反规范化的维度表可以进行一致性上卷。比如类目维度表退化进商品维度表,但是他们拥有相同的维度属性和属性值。

维度设计高级主题

维度整合

数据仓库的重要数据来源是大量的、分散的面向应用的操作型环境。不同的应用在设计过程中,可以自由决策,主要满足本应用的需求,很少会考虑和其他系统进行数据集成。应用之间的差异表现如下:

  • 在编码、命名习惯、度量单位等方面会存在很大差异。比如对用户的性别编码不同,有0和1、男和女、F和M等;不同应用用户ID含义相同但字段名称不同,有user、userID等;不同应用对于金额的度量单位不同等。
  • 应用出于性能和扩展性的考虑,或者随技术架构的演进,业务的发展,采用不同的数据库。

而在整合时,具体体现在如下几个方面:

  • 命名规范的统一。表名、字段名等统一。
  • 字段类型的统一。 相同和相似字段的字段类型统一。
  • 公共代码及代码值的统一。公共代码及标志性宇段的数据类型、命名方式等统一。
  • 业务含义相同的表的统一。主要依据高内聚、低耦合的理念,在物理实现中,将业务关系大、源系统影响差异小的表进行整合;将业务关系小、游、系统影响差异大 的表进行分而置之。通常有如下几种集成方式:
    • 采用主从表的设计方式,将两个表或多个表都有的字段放在主表中,从属信息放在从表中。这时应该采用复合主键的方式。
    • 直接合并,共有信息和个性信息都放在同一个表中。如果表字段的重合度较低,则会出现大量空值。
    • 不合并,因为源表的表结构以及主键差异很大,无法合并,可以作为单独的表存放各自的数据。

上述内容是字段的整合,下面重点来看表级别的整合。

垂直整合

即不同的来源表包含相同的数据集,只是存储的信息不同。比如会员基础信息表、会员扩展信息表、会员等级表等,这些表都属于会员相关信息,依据维度设计方法,尽量整合到会员维度模型中,丰富维度属性。

水平整合

即不同的来源表包含不同的数据集,不同子集之间存在部分交叉。比如不同业务线的数据仓库中肯定都有会员信息,是否需要将这些会员信息整合到一个会员表中,如果整合,就需要将冲突的字段进行合并,将不冲突的字段进行整合;另一种方式是设置超自然键,将来源表的自然键加工为一个超自然键,并将来源字段设置为分区字段。

水平拆分

维度通常可以按照类别或类型进行细分。比如商品维度可以按照业务线分为不同业务商品表,他们的维度属性有可能相同,也可能不同。这样的维度表该如何设计呢?

此类问题有两种解决方案,方案1:

将维度的不同分类实例化为不同维度,同时在主维度中保存公共属性,即微型维度。

方案2:

维护单一维度,包含所有可能的属性。

在设计维度时需要重点考虑一下三个原则:

  • 扩展性:当原系统、业务逻辑变化时,能通过较少的成本快速扩展模型,保持核心模型的相对稳定性。
  • 效能:在性能和成本方面取得平衡,可以牺牲一定存储成本,达到性能和逻辑的优化。
  • 易用性:模型可理解性高、访问复杂度低。

当不同业务线的属性差异较大时,将所有维度属性建立在一个表中不切合实际,此时建议采用方案1。这是可以提取公用维度属性建立主维度表,将差异维度属性定义为多个子维度挂靠在主维度表中。通过扩展子维度的方式,保证模型可扩展性。

当某几条业务线的属性差异较小时,虽然可以采用方案2将维度属性统一在一起,但是耦合在一起弊大于利,对于模型的稳定性和易用性影响较大。未来不管业务线1变更还是业务线2变更都会影响此维度表设计,稳定性、易用性、扩展性都会变差。

垂直拆分

水平拆分是未来解决同一维度存在不同维度属性的问题,垂直拆分是为了解决同一维度产出时间差异过大的问题。

产出时间早的维度表必然在热度高、使用频繁、相对成熟,在出于整体扩展性的考虑,设计主从维度。主维度存放稳定、产出时间早、热度高的属性;从维度放变化较快、产出时间晚、热度低的属性。由于从维度有冗余等变化较快的数据,对于主维度的缓慢变化处理就较为重要,可以提升一定存储成本和计算成本,实现主维度稳定快速产出。

历史归档

在设计模型时如何降低存储、降低下游使用难度是必须考虑的问题,这时需要一套数据归档策略将某些废弃状态或具有废弃状态的数据归档至历史库。

归档策略1:在数据仓库中实现前台归档策略算法,定期对历史数据进行归档,但是归档算法复杂时实现成本较高;同时归档策略也会经常变化,维护和沟通成本较高。适用于稳定且逻辑简单的情况。

归档策略2:采用数据库变更日志的方式,从数据库日志中获取每日增量,通过增量merger全量的方式获取最新的全量数据。可以使用增量日志的删除标志作为前台数据归档的标志。并通过此标志对数据进行归档。推荐使用。

归档策略3:可以使用数据库自定义归档策略。但原则是尽量晚归档,少归档。避免出现数据仓库已经归档的数据再次更新的情况。

维度变化

缓慢变化维

缓慢变化维是为了解决业务系统中维度属性随着时间流逝而发生变化的情况,因为其变化速度与业务数据增长相比变化的很缓慢,所以叫做缓慢变化维。

缓慢变化维是Kimball理论中很重要的知识点,有三种处理方式:
第一种处理方式为重写维度值,采用这种方法只保留最新数据,不保留历史数据。

第二种处理方式:插入新的维度行。采用这种方式,保留历史数据,维度值变化前的事实和过去的维度值关联,维度值变化后的事实和当前维度值关联。

第三种处理方式:添加维度列。采用第二种处理方式不能将变化前后记录的事实归一为变化后的维度。

选择哪种方式处理缓慢变化维,假设业务需求不关心历史数据,则可使用方法1,如果关心历史数据但不关心变化情况,则可使用方法2,如果都关心,则可使用方法3。

快照维表

在维度建模方法中,必须使用代理键作为每个维表的主键,用于处理缓慢变化维,但是大量使用代理键会十分依赖事务,同时会大大增加ETL的复杂性,使得ETL任务的开发和维护成本提高。

使用快照维表只需要定期将维度表数据完整保留一份即可,简单而有效,开发和维护成本低,同时使用简单,使用方只需要限定日期,就可以获得当天的数据。

弊端也十分明显,快照维表会造成大量存储浪费,牺牲存储提升ETL效率。同时需要配合对应的数据存储机制,保证整体效率。

而既想拥有快照维度的便捷性,同时拥有低存储成本,也是有的,便是极限存储维表。

极限存储维表

极限存储维表是使用历史拉链存储,增加两个时间戳字段(start_dt和end_dt),将所有以天为粒度的变更数据记录下来。

卖家A在2016年1月1日发布B、C两个商品,在1月2日将商品B下架,上架商品D,数据同步后商品C的状态顺延保存至1月2日。

如果没有发生更改的数据很多,则产生了大量的数据重复。采用历史拉链存储,存储结构如下:

这样下游应用可以通过限制时间戳字段来获取历史数据。但是这样的存储方式会对下游使用产生一定的理解障碍,另外这样的存储方式会使用start_dt和end_dt做分区,随着时间推移,分区数量会急速膨胀。

为了解决这个问题,阿里巴巴提出了极限存储的方式。

  1. 透明化

    首先要解决下游查询的障碍,如果使用历史拉链存储,下游查询2016年1月1日的数据的语句为:

    select * from A where start_dt <= 20160101 and end_dt > 20160101;
    

    这时可以做一个视图或者Hook封装该表,使查询语句转换为:

    select * from A where dt = 20160101;
    
  2. 分月历史拉链

    假设使用start_dt和end_dt做分区,不做限制的话,一年最多产生的分区数为365X364/2=66430个。

    |一一 202110/ #每月一个周期
    |一一 20211001/99990101 # 每月1日的全量数据
    |一一 20211001/20211002 # 1001 产生且 1002 死亡记录
    |一一 20211001/20211003 # 1001 产生且 1003 死亡记录
    ...
    |一一 20211001/20211031 # 1001 产生且 1031 死亡记录
    |一一 20211002/20211002_ins # 1002 产生新增记录
    |一一 20211002/20211003 # 1002 产生且 1003 死亡记录
    ...
    |一一 20211002/20211031/ # 1002 产生且 1031 死亡记录
    |一一 20211003/20211003_ins # 1003 产生新增记录
    ...
    |一一 20211031/20211031_ins # 1031 产生新增记录
    |一一 202111/
    |一一 20211101/99990101 # 每月1日的全量数据
    ...
    

    再计算一年最多可能产生的分区数为12X(1+(30+29)/2)=5232个。

采用极限存储的处理方式,可以极大压缩全量存储的成本,又可以达到对下游用户透明的效果。但是产出效率极低,通常需要做T+2;其次对于变化频率高的数据并不能达到解决成本的效果。

做极限存储前有一个全量存储表,全量存储表仅保留最近一段时间的全量分区,历史数据通过映射的方式到极限存储表。即用户只访问全量存储表,不会访问到极限存储表。

同时部分变化频率频繁的字段需要过滤。假设用户表存有积分维度属性,因为这样的属性每天都在发生变化,如果不过滤的话,极限存储的每个分区都相当于存储了一份全量数据,起不到解决存储的效果。

微型维度表

采用极限存储时需要避免维度属性变化频繁,此时就需要将一些属性从维表中移出,放在全新的维表中,就可以解决变化频繁的维度属性影响极限存储效果的问题。

微型维度的创建就是将一部分不稳定的属性从主维度移出,并将它们放置在拥有自己代理键的新表中。

但是微型维度有自己的局限性:

  • 微型维度是实现用尽可能值的组合加载的,需要考虑每个属性的基数,且必须是枚举值。
  • 会使得ETL逻辑复杂,开发和维护成本过高。
  • 破坏了维度的可浏览性。

特殊维度 - 层次结构扁平化

维度表中肯定存在层次类目结构的维度表,比如行政区域维度,他有固定的五级类目层次:乡镇/街道、区县、城市、省份、国家。对于这种具有固定数量级别的递归层次,称为“均衡层次结构”。比如企业区域维度,公司间的层次结构不固定,对于这种不固定的递归层次,称为“非均衡层次结构”。

层次结构扁平化是为了降低使用此类维度表的复杂度。

存储结构如下,四五级忽略。

此类结构使用方便性得到大大提高,但是存在下面三个问题:

  • 针对某类目上钻或下钻时,必须知道其所属的类目层级。
  • 假设使用三级类目进行统计,但是对应的三级类目为空,对应的叶子节点为二级或一级,此类类目就无法被统计到。需要事先规避。
  • 扁平化仅包含固定数量的级别,对于非平衡层次结构,可以通过预留级别的方式来解决,但扩展性较差。

特殊维度 - 层次桥接表

针对层次结构扁平化存在的问题,可以采用桥接表的方式来解决。此类方式与扁平化对比,更适合解决更宽泛的分析问题,灵活性好;但复杂度高,使用成本高。

假设针对类目石家庄进行下钻操作,步骤如下:

限制类目表的类目ID为石家庄,通过类目ID与类目桥接表的父类目ID关联;通过桥接表子类目ID事实表类目ID关联,接着针对事实表进行下钻操作。

建设针对类目石家庄进行上钻操作,步骤如下:

限制类目表的类目ID为石家庄,通过类目ID与类目桥接表的子类目ID关联;通过桥接表父类目ID事实表类目ID关联,接着针对事实表进行上钻操作。

可以看出,桥接表确实解决了层次结构扁平化带来的一些问题,但是其加工复杂,使用逻辑复杂,而且桥接表多对多的关系还造成了双重计算的风险。

现有扁平化设计可以满足需求,不需要引入桥接表。

特殊维度 - 行为维度

在数据仓库中存在一些维表,例如卖家主营类目维表、买家常用地址维表等,都需要从事实表采用算法计算得到,这样与事实相关的维度被称为行为维度。

行为维度可以划分为以下几种:

  • 另一个维度的过去行为,比如买家最近一次访问网站的时间,最近一次交易时间等等。
  • 快照事实行为维度,比如买家从年初截至到今交易额等等。
  • 分组事实行为维度,比如对买家交易额转换为枚举值,通过金额划分买家等级等等。
  • 复杂逻辑事实行为维度,通过复杂算法加工得到,比如卖家主营类目维表,需要从多个事实表中计算得到。

对于行为维度有两种处理方式:

第一,避免维度过快增长,比如买家最近一次访问网站的时间,这样的属性加到维度表中会影响极限存储;第二,避免耦合性过高,比如复杂逻辑事实行为维度加入到维度表中会引起过多的业务耦合导致此维度表维护性差,产出延迟。

特殊维度 - 多值维度

多值维度是指事实表中一条记录与某维度表中多条记录对应,比如交易订单的粒度为一批,买家一批卖了多件商品,那么此交易被称为交易父订单,此订单内每件商品被称为子订单;此时父订单会与两个子订单对应,这就形成多值维度。

针对这种情况,常见的处理方式有三种,第一种处理方式是降低事实表粒度,将粒度由批降低到个,但是当事实表粒度无法降低时,多值维度的出现就无法避免;第二种处理方式是采用多字段,比如一个合同签订事实表会出现多个买受方,但是合同已经是此类事实的最小粒度了,这是就会采用多字段方式,但是为了考虑扩展性,不会预留太多字段。

第三种方式则是使用桥接表,桥接表更灵活、对应的也是会引起逻辑复杂、开发和维护成本高以及会引起双重计算等问题。

特殊维度 - 多值属性

多值属性是指一个维度属性同时具有多个值,他是多值维度的另一种表现形式。比如商品SKU维表、商品标签维表等。每个商品都有一到多个SKU,一到多个标签,比如饮料的SKU可以是瓶,也可以是箱,也可能是促销装,所以商品和他们的关系都是多对多。

多值属性的处理方式有三种;

第一种是保持维度主键不变,将多值属性放在维度表一个字段中,通过K-V对的形式放在该字段中,示例如下:01:瓶;02:箱。这样处理扩展性好,但是使用复杂;

第二种是保持维度主键不变,但将多值属性放在维度的多个属性字段中,属性字段可以按照业务需求来限制,如果多值属性字段具体数量不固定,则可以采用预留字段的方式,但是扩展性很差;

比如统计卖家主营类目,业务需求只统计TOP3,那么设计三类类目字段即可;

第三种处理方法则是维度主键发生变化,一个维度值存放多条记录。这种处理方式扩展性好,使用方便,但是数据量会急速膨胀。

特殊维度 - 杂项维度

杂项维度是由操作型系统中的指示符或者标志字段组合而成,一般不在一致性维度之列。比如一些交易类型、支付状态等字段,他们保存在事实表中则会导致事实表占用空间过大,如果单独建立维表,则会出现维度过多,如果删除这些字段,则有业务人员不同意。

可以使用杂项维度来解决这种情况,将这些字段建立到一个维表中,在事实表中保存一个外键即可。在业务系统中遇到一种组合生成对应的记录即可,杂项维度的ETL过程比一般维度略微复杂一些。

OneData方法论-维度表设计相关推荐

  1. OneData方法论-事实表设计

    事实表设计 事实表特性 事实表作为数据仓库维度建模的核心,紧紧围绕着业务过程来设计. 事实表中一条记录所表达的业务细节程度被称为粒度,粒度可以通过两种方式来表达:一种是维度属性组合所表示的细节程度,一 ...

  2. 维度表创建规范_数据仓库维度建模-维度表设计

    1 维度表的定义 在维度建模中,通常将指标的度量称之为"事实",将产生度量的环境称之为"维度".将描述同一个业务实体的的多个维度列组合在一起,就是常说的&quo ...

  3. 聊聊数据仓库中维度表设计的二三事

    前言 大家好,我是云祁!今天和大家聊聊数据仓库中维度表设计的那些事. 维度表是维度建模的灵魂所在,在维度表设计中碰到的问题(比如维度变化.维度层次.维度一致性.维度整合和拆分等)都会直接关系到维度建模 ...

  4. 一篇文章搞懂数据仓库:维度表(设计原则、设计方法)

    目录 1.什么是维度表? 2.维度表设计原则 (1)维度属性尽量丰富,为数据使用打下基础 (2)给出详实的.富有意义的文字描述 (3)区分数值型属性和事实 (4)沉淀出通用的维度属性,为建立一致性维度 ...

  5. OneData方法论-概述

    OneData OneData概述 OneData是阿里巴巴数据整合及管理体系,其方法论的核心在于:从业务架构设计到模型设计,从数据研发到数据服务,做到数据可管理 .可追溯.可规避重复建设.即数据只建 ...

  6. 维度表,实体表,事实表之间的关系

    这段时间在慢慢学习有关维度建模的一些东西,其中有个问题当时被老大挖了个坑就跳了进去几天都没爬出来,这个坑主要在于我对维度表,实体表,事实表这三种表之间的关系和概念认知比较模糊,当时老大要我去设计一个关 ...

  7. 维度表和事实表以及明细表和宽表和窄表的区别

    简单解释: 事实表就是交易表. 维度表就是基础表. 二者的区别: 维度表的冗余很大,主要是因为维度一般不大(相对于事实表来说的),而维度表的冗余可以使事实表节省很多空间. 事实表一般都很大,如果以普通 ...

  8. maxcompute操作_MaxCompute表设计最佳实践

    MaxCompute表设计最佳实践 产生大量小文件的操作 MaxCompute表的小文件会影响存储和计算性能,因此我们先介绍下什么样的操作会产生大量小文件,从 而在做表设计的时候考虑避开此类操作. 使 ...

  9. 维度建模的事实表设计

    事实表基础 事实表特性 事实表作为数据仓库维度建模的核心,紧紧围绕着业务过程来设计,通过获取描述业务过程的度量来表达业务过程,包含了引用的维度和与业务过程有关的度量. 事实表中一条记录所表达的业务细节 ...

最新文章

  1. Python Module — asyncio 协程并发
  2. SAP在快速消费品行业中的实施方案
  3. 网管必杀技之VLAN的网络管理
  4. utl_file包的使用
  5. Django图书商城项目/图书管理/毕业设计
  6. [转]史上最全Eclipse优化
  7. 四阶魔方初级玩法公式
  8. python-opencv第四期:threshold函数详解
  9. pscs6怎么做html模板,ps cs6设计个人作品网页模板教程(6)
  10. 欧几里得变换(Euclidean transformation)详解
  11. 经典BBS语录100条
  12. 物联网-电力监控平台(二)
  13. 近三年六级作文题目汇总
  14. python采用强制缩进的方式使得代码具有极佳的可读性_python3的优势有哪些
  15. 求自然数e的近似值,要求误差小于10 -6
  16. 关于对四维空间一些理解
  17. springmvc 下载文件ie8可用
  18. 2017年婚恋网站分析
  19. html标签四要素,【复习】HTML基础
  20. UI竟在我身边#2:麦当劳APP

热门文章

  1. 太卷了,企业级智慧社区也是能开源的?
  2. Win10下安装SQL Server 2016 Management Studio报0x80070570的解决办法
  3. 在医院信息科的生存之道
  4. hdoj4540 威威猫系列故事——打地鼠
  5. Mark-Sweep算法
  6. 从 我的兄弟叫顺溜 看技术人才的职业规划
  7. Oracle Database Client 11gR2 精简版 发布
  8. Flutter组件--TextField使用详情
  9. 【vscode运行商城项目】
  10. 带中点电位平衡的基于载波注入NPC三电平SVPWM调制方式_SIMULINK模型