数据开发之离线计算_维度建模关键知识与读后感

数据开发之离线计算_维度建模关键知识与读后感

一、背景

1.1 阅读契机

有三个契机去买下《维度建模》这本书,去真正沉下心读一本实体书:

1.刚毕业入职,得知我是做后端,之前没有接触过数据仓库,推荐我去读一下Kimball的《维度建模》。

2.在工作一段时间第一次想跳槽时,投了美团的数据仓库工程师岗位,那个面试官问了很多数据仓库基础理论知识,包括项目中如何构建数据模型、构建数据模型考虑了哪些因素,我垭口无言。

3.自己工作中,更多的是做数据应用层包括数据应用的查询加速,很多需求就是数据产品直接给出从上游取数的数据口径,那么上游为什么要这么建表、有些工作应该在上游还是下游做、上游的变更会给下游带来什么影响这些问题,我通通都不知道,这就导致在方案设计、问题定位、价值描述时非常被动。做需求一定要对尽可能长的上下游做全面了解,也要对整个技术全貌有一个大致了解,而《维度建模》可以说是数据仓库技术全貌的底层基座。

1.2 初识维度建模

维度建模基本步骤:

维度建模通常采用星型或雪花型模式,其中星型模式适用于简单的数据模型,而雪花型模式则更适用于复杂的数据模型。以下是维度建模的一些关键步骤:

  1. 定义主题域:首先,你需要明确你的数据仓库所关注的主题领域。例如,如果你正在构建一个销售数据仓库,那么主题域可能是销售、客户、产品等。
  2. 创建维度表:对于每个主题域,创建一个或多个维度表。维度表包含描述性的信息,如日期、时间、地理位置、客户信息、产品信息等。
  3. 创建事实表:事实表包含关于主题域的度量信息,如销售额、订单数量等。事实表通常与维度表相关联,以便查询时能够快速获取所需的信息。
  4. 确定事实表与维度表之间的关系:事实表通常与多个维度表相关联,以提供更详细的信息。例如,在销售数据仓库中,事实表可能与客户维度表、产品维度表以及日期维度表相关联。
  5. 构建星型模式或雪花型模式:星型模式是最简单的模式,其中每个维度表都直接连接到事实表。雪花型模式则更复杂,它允许维度表之间建立联系,从而形成一个类似于雪花的结构。
  6. 设计维度表的粒度:维度表的粒度决定了数据仓库中存储的信息的详细程度。例如,如果你的客户维度表包含客户的姓名和地址,那么这个维度表的粒度就比较粗;如果你还希望包含客户的电话号码和电子邮件地址,那么这个维度表的粒度就会更细。
  7. 确定主键和外键:在设计维度表时,确保为每个表定义一个唯一的主键,并在事实表和其他维度表中设置外键,以便在查询时能够正确地关联数据。
  8. 实施和测试:一旦设计完成,就可以开始实施数据仓库并进行测试,以确保数据的准确性和完整性。

比如一个交易业务案例:一个订单成交是一个业务过程,伴随着用户在某个时间购买店铺的某个商品,那么拆解出来的主题域有用户、日期、商家、商品,对应每个主题可以衍生并建立一个或多个维表。比如衍生之下的商品类别、采销人员、采销部门等等等。

二、《维度建模》关键知识点摘录

2.1 维度建模概述

事实表

  • 维度建模的核心原则之一是同一个事实表中的所有度量行必须具有相同的粒度。牢记建立事实表时使用统一的细节基表这一原则可以确保不会出现重复计算度量的问题。(我们在实际业务中创建预计算事实表时,经常讲不同聚合粒度的数据存储在同一张表中,用lvl_code来做区分,如果查询时不卡lvl_code过滤条件确实有可能出现重复计算度量的问题,但是为了减少物理表的运维成本、减少表数量,这也是一种妥协方案。)
  • 物理世界的每一个度量事件与对应事实表行具有一对一的关系,这一思想是维度建模的基本原则。
  • 最实用的事实是数值类型和可加类型事实。可能也会遇到一些半可加事实,如账户结余不能按时间维度执行汇总操作;也会遇到不可加事实,如商品价格不可相加。
  • 设计者应该尽最大可能将文本数据放入维度中,将它们有效地关联到其他文本维度数据属性上,以减少空间开销。除非对事实表的每个行来说,其文本时唯一的,否则应将其放入维度表中。准确的文本事实比较少见,因为文本事实存在不可预测性,例如,自由文本注释,几乎没有对其进行分析的可能性。
  • 从行的数量来看,事实表趋向于变长。从列的数量来看,事实表趋向于变短。鉴于事实表占据大量空间的实际情况,应该仔细考虑对事实表空间的利用问题。

维度表

  • 维度表包含与业务过程度量事件有关的文本环境,它们用于表述与“谁、什么、哪里、何时、如何、为什么”有关的事件。(就是一直在讲的5w1h)
  • 与事实表相比,维度表趋向于包含较少的行,但由于可能存在大量文本列而导致存在多列的情况。
  • 维度属性可作为查询约束、分组、报表标识的主要来源。
  • 维度表的属性是所有查询约束和报表标识的来源,所以维度属性的可用性和可理解性也起着非常重要的作用。属性应该包含真实使用的词汇而不是令人感到迷惑的缩写。应该尽量减少在维度表中使用代码,应该将代码替换为详细的文本属性。
  • 多数情况下,数据仓库的好坏直接取决于维度属性的设置:DW/BI环境的分析能力直接取决于维度属性的质量和深度。为维度属性提供详细的业务术语耗费的精力越多,效果就越好。为属性列填充的领域值耗费的精力越多,效果就越好。为确保属性值的质量耗费的时间越多,效果就越好。强大的维度属性带来的回报是健壮的分片、分块分析能力。
  • 一个数字量到底是事实还是维度属性,对于设计者来说是一个两难的问题,很难做出决策。如果该值参与计算,那么更可能是事实;如果是一个常量、一个约束和行标识,则更可能是维度属性。连续值数字基本可以认为是事实;来自一个不太大的列表的离散数字基本可认为是维度属性。例如,产品的标价看起来像一个产品的常量属性,但它经常会发生变化,所以大多数场景下它更可能是一种度量事实,要根据具体场景具体分析。(比如将商品按价格进行分组,在进行分组聚合分析时,价格又被看做是一种维度属性。)
  • 维度表通常不一定要满足第3范式,它常常是非规范化的,一个维度表中往往存在多对一的关系。由于与事实表相比,维度表通常要小很多,因此采用规范化或雪花模式实际上对数据库的的从存储量没有多大影响。一般对维度表存储空间的权衡往往需要关注简单性和可访问性。(比如商品的一、二、三级类目维度表,如果要满足第3范式,也就是维度表中所有数据列必须相互独立,不存在其他函数关系,那么这个类目维度应该拆分为用3张维度表保存。但是在大数据仓库中一般都直接用一张维度表存储。)

DW/BI架构

  • Kimball架构将DW/BI环境划分为4个不同的组成部分:操作型源系统、ETL系统、数据展示、商业智能应用。

  • 数据展示区的底座是企业数据仓库总线架构,这个企业级数据仓库就是指事实表应该包含整个企业不带约束条件的事实明细,维度值必须包含整个企业的枚举。展示区四大原则:采用星型模式或OLAP多维数据库、包含原子数据及汇总数据、数据按业务过程进行组织、使用一致性维度。

  • ETL系统的主要任务是在交付过程中划分维度和事实。

  • 建立规范化维度结构,也就是将维度表尽可能减少冗余,向雪花模型靠拢,是在ETL过程中可以采用的方法。但是,这不是最终的目标。不能在用户查询中使用规范化结构,因为规范化结构难以同时满足可理解性和性能这两个目标。

  • 与餐厅厨房情况类似,发生在ETL系统中的活动不应该展示给DW/BI用户。当数据准备工作就绪,质量检查完成后,数据才能进入DW/BI展示区。数据质量检查是ETL的最后一步,也是必不可少、非常关键的一步。展示区数据应该根据要求准备停当并保证安全。

  • 关于数据展示区,第一个建议,我们坚持认为数据应该以维度模型来展示,要么采用星型模型,要么采用olap多维数据库,不应该采用多层嵌套维度表。(olap多维数据库就是Cube预计算和维度路径数组的数据组织形式,使用预聚合、多维建模、列式存储等措施更注重解决复杂分析场景的性能瓶颈

  • 关于数据展示区,第二个建议,必须包含详细的原子数据。为了满足用户无法预期的、随意的查询,必须使用原则数据。尽管在展示区,为提升性能也会存储聚集数据,但若仅仅有这些汇总数据而没有形成这些汇总数据的细粒度数据,这样的展示区是不够完整的。(ETL结束后落库到提供用户查询的展示区的数据,不能只有预计算数据而没有明细数据,就像早期的商智只有HBase数据模型,这样的展示区数据模型是不完整、不健康、不标准的。

  • 关于数据展示区,第三个建议,展示区的数据可以围绕业务过程度量事件来构建。维度模型应该对应物理数据获取时间,不应该将它们设计为仅为完成每天的报表工作。(底层明细模型可以在减少冗余的前提下,尽可能的做得宽一些,多一些度量或维度,多扩展一些主题域,预想一些其他的业务数据诉求。这也是美团面试官在面试中给的建议,设计业务需求模型时也要多考虑一些这次不用但是后续可能会用的字段。

  • 关于数据展示区,第四个建议,遵守总线结构。维度一定要是企业级可共享的、一致性的维度,不应该按照个别部门需要的数据来构建。否则维度模型将成为一个孤立的应用,无法交互的、隔离的烟囱型数据集开发模式也会越来越严重。

  • 餐厅管理者通常积极主动地检查就餐者对菜肴和就餐体验的满意程度。如果某位顾客不满意,立即采取行动对涉及的问题加以纠正。同样DW/BI管理者应该积极主动地开展对满意度的监控工作。您不能被动的地等待听顾客抱怨。通常,顾客甚至没有表达他们的不满,就放弃就餐。一段时间后,管理者会发现不知什么原因,就餐人数下降。

  • 数据管理或治理项目首先应该关注主维度集,健壮的维度是建立健壮的DW/BI系统的基础。

维度建模谣言

  • “维度模型仅包含汇总数据”。由于不可能预测业务用户提出的所有问题,因此必须向业务用户提供对细节数据的查询访问(就像商智大部分页面都有明细下载,黄金眼基本全部页面都要有明细下载。)
  • “维度模型时部门级而不是企业级”。维度模型应该围绕业务过程组织,例如,订单、发货、服务调用等,而不是按照组织中部门的职责划分。多个业务部门往往需要分析来自同一业务过程的相同的维度。
  • “维度模型仅用于预测”。不应该将维度模型设计为仅仅关注预定义的报表或分析。设计应该以度量过程为中心,考虑BI应用的过滤和标识非常需求非常重要。关键是将注意力放到组织的度量事件上,因为与不断变化的分析相比,它们通常是比较稳定的。所以我们要建立的维度模型应该是能够适应业务需求变化的,非常灵活的。实现查询灵活性的灵丹妙药是以最细粒度级别构建事实表。(就像黄金眼要建设产品分析平台,就是用户可以非常灵活地进行漏斗分析、下钻、归因的一个数据看板,这一切的基础也是依赖明细表。)

2.2 维度建模技术概述

事实表

  • 维度模型设计的主要步骤:1)选择业务过程;2)声明粒度;3)确认维度;4)确认事实。(其实就像之前了解到的一样,维度建模步骤就是先确认清楚业务过程,然后确认业务过程涉及到的主题域,根据主题域关键维表及相关字段,然后在确认事实表需要哪些字段来关联这些主题维度和需要分析的度量。)
  • 业务过程是组织完成的操作型活动,例如,获得订单、处理保险索赔、学生课程注册、每个月每个账单的快照等。业务过程事件建立或获取性能度量,并转换为事实表中的事实。
  • 事实表的数字度量可划分为可加、半可加、不可加三类。半可加可以对某些维度汇总,但是不能对所有维度汇总。差额是常见的半可加事实,除了时间维度外,它们可以跨所有维度进行加法操作。另外,一些度量是完全不可加的,例如比率。对于不可加事实,一种好的方法是,尽可能存储不可加度量的完全可加分量,并在计算出最终不可加事实前,将这些分量汇总到最终的结果集合中。(比如引导成交转化率等比率类指标就是典型的不可加度量。)
  • 事实表中可以存在空值度量,但是事实表的外键中不能存在空值,否则会导致违反参照完整性的情况发生。
  • 如果某些度量出现在不同的事实表中,需要注意,如果需要比较或计算不同事实表中的事实,应该保证针对事实的技术定义是相同的。这就是一致性事实。
  • BI应用绝对不应该对两个事实明细表的外键直接进行关联操作。需要采用跨钻的方式关联两个事实表,并对结果按照公共行头,也就是公共分组维度属性值,进行排序-融合操作以产生正确结果。(也就是不能关联明细事实表,最好用维表作为左边关联不同事实表,且最好关联聚合事实表。)

维度表

  • 维度表最好不要有空值属性。当给定维度行没有被全部填充,或存在属性没有被应用到所有维度行时,推荐采用描述性字符串代替空值。例如使用Unknown或Not Applicable替换空值。我们应该避免在维度属性中使用空值,因为不同数据库系统在处理分组和约束时,针对空值的处理方法不一致。
  • 当不同维度表的属性具有相同列名和领域内容时,成维度表具有一致性。利用一致性维度与每个事实表关联,可以将来自不同事实表的信息合并到同一报表中。当一致性属性被用作行头,也就是SQL查询中的分组列时,来自不同事实表的结果可以排列到跨钻报表的同一行,这也是企业级DW/BI系统的基石。一致性维度一旦在与业务数据管理方共同定义后,就可以被所有事实表重用,否则就不是安全、正确的企业级一致性维度。
  • 缓慢变化维度属性就是随着时间缓慢变化的维度属性。对于需要重写维度属性值的变化维度,需要确保原来的属性值被新值覆盖,这种场景不需要新增额外的维度行,但是需要重点关注受此影响的聚集事实表和OLAP多维数据库需要重新回溯历史数据。如果希望存量的事实数据保持不变,增量事实数据使用新的变化后维度,则需要在维度表中增加新行写入修改后的维度属性值,且最少需要在维度表中增加三个额外列:1)行有效开始时间,2)行有效结束时间,3)当前行标识。当存量事实关联时使用存量日期进行关联,增量事实关联时则使用更新后日期进行关联。