【数仓建模】1-维度建模维度表与事实表-解读版本
维度建模理论 - 解读版
维度建模
维度建模(Kimball):分析决策的需求出发构建模型,为分析需求服务,因此 它重点关注用户如何更快速地完成需求分析,同时具有较好的大规模复 杂查询的响应性能。其典型的代表是星形模型,以及在一些特殊场景下 使用的雪花模型
--分享解读:区别于lnmon的范式建模,重点在于快速满足需求,对建模人员要求相对较低,日志规范设计是典型的lnmon建模模式,对日志设计人员对业务的洞察和思考要求很高,很容易出错,做过日志设计就会有感受。
建模步骤
1)选择业务过程:根据需要对进行分析决策的业务过程的选择
2)选择粒度。在事件分析中,我们要预判所有分析需要细分的程度,从而决定选择的粒度。粒度是维度的一个组合。
3)选择好粒度之后,就需要基于此粒度设计维表,包括 维度属性,用于分析时进行分组和筛选。
4)选择事实。确定分析需要衡量的指标
--分享解读:维度建模很重要的一点是重点只针对我们“核心关注的需求”进行建模,然后构建出一致性的维度和事实,这些都需要一套规范化命名体系去约束。
模型分层
ODS:把操作系统数据几乎无处理地存放在数据仓 库系统中。
CDM:采用维度退化手法, 将维度退化至事实表中,减少事实表和维表的关联 ,提高明细数据易用性 :同时在汇总数据层, 加强指标的维度退化, 采取更多的宽表手段构建公共指标数据层,提升公共指标的复用性,减少重复加工。
--分享解读:维度退化的“宽表”打法,有利有弊,都是tradeoff。不要只想着好用,其实未必好用。面向业务数据分析还用,面向系统产品 SLA就是大问题。
ADS:存放数据产品个性化的统计指标数据,根据 CDM 层与 ODS 层加工生成,不提供对外服务。
--分享解读:大胆的把你的应用专用表命名成app_*表吧,这样就可以理直气壮的告诉别人这是我的私有财产,别人不许碰否则后果自负,如果你命名成cdm里的表,那你后果自负。
缓慢变化维:
建模基本原则
1)高内聚低耦合:数据业务特性和访问特特性两个角度来考虑 :将业务相近或者相关、粒度相同的数据设计为一个逻辑或者物理模型:将高概率同时访问的数据放一起 ,将低概率同时访问的数据分开存储。
--分享解读:请注意,是两个角度,业务特性和访问特性兼顾。这里在数据治理里专门有人做模型离散度治理,这个是保障模型好用健康的一个度量方式。
2)核心模型与扩展模型分离:建立核心模型与扩展模型体系,核心模型包括的宇段支持常用的核心业务,扩展模型包括的字段支持个性化或少量应用的需要 ,不能让扩展模型的宇段过度侵人核心模型,以免破坏核心模型的架构简洁性与可维护性。
--分享解读:我们重构业务数据中间层的时候,订单事件表就是遵循的这个原则,同时还能保障故障的隔离和SLA能力。
3)公共处理逻辑下沉及单一:越是底层公用的处理逻辑越应该在数据调度依赖的底层进行封装与实现,不要让公用的处理逻辑暴露给应用层实现,不要让公共逻辑多处同时存在。
--分享解读:具体到dd我们惯用的说法是“口径收口”,这个一定要在dwd层和dwm层完成,不允许在应用层做。指标体系治理是做业务支持的数据开发t团队最痛的点,最有效的办法就是"下沉且单一"
4)成本与性能平衡:适当的数据冗余可换取查询和刷新性能,不宜过度冗余与数据复制。
--分享解读:我们业务数据中间层重构前的dwd_order_event_d就太多的照顾了业务的个性化需求,而没有遵循这一点,导致平均每个订单数据行数膨胀6倍。极大的影响了数据运算和产出效率。
5)数据可回滚:处理逻辑不变,在不同时间多次运行数据结果确定不变。
--分享解读:作为程序员这是基本自觉.
6)一致性:具有相同含义的字段在不同表中的命名必须相同,必须使用规范定义中的名称。
--分享解读:说起来容易做起来难,做到全局一致性是不可能的,但是局部一致性是我们要努力做的事情。只有规范很难落地,需要结合具体的管控工具和考核办法去协力完成。
7)命名清晰、可理解:表命名需清晰、一致,表名需易于消费者理解和使用。
--分享解读:没什么可说的,如果命名规范限制了你对含义的本身理解,那规范不是一个好规范。
模型实施流程
0)业务调研和需求分析:熟悉对应的业务系统业务,收集整合运营人员,分析师对数据和报表的需求集合。了解了业务系统的业务后并不代表就可以进行实施了,此刻要做的就是收集数据使用者的需求,可以去找分析师、业务运营人员了解他们有什么数据诉求, 此时更多的就是报表需求。
--分享解读:数据建模他不是一个纯“技术”活,但是对技术人员要求又很高,业务调研和需求分析做的好坏直接决定了数据模型的质量,上来就讲解数据表具体是什么有什么内容是不高级的。
1)高层模型:直接产出目标是创建高层维度模型图,它是对业务过程中的维表和事实表的图形描述。确定维表创建初始属性列表, 为每个事实表建立度量。
--分享解读:其实就是需要消化吸收并将业务内化转换成一个数据模型的过程,将业务过程或者维度进行合理的抽象,这一步要产出一个数据资产总图,模型的形式上是什么样的,需要包含哪些内容。
2)详细模型:为高层模型填补缺失的信息,解决设计问题,并不断测试模型能否满足业务需求,确保模型的完备性。确定每个维表的属性和每个事实表的度量,并确定信息来源的位置、定义,属性和度量如何填人模型的初步业务规则。
--分享解读:这一部分要做好数据探查,详细定义每一个字段,明确维度、原子指标、衍生指标。很多同学有个误区是上来就干数据探查,我们要明白数据建模是为业务目标服务的,一定要先拆解分析业务目标,做好高层设计,再进行这一步,也许会有tradeoff发生。
3)模型审查、再设计和验证:本阶段主要召集相关人员进行模型的审查和验证,根据审查结果对详细维度进行再设计。
--分享解读:关键模型要做好交叉review甚至发cr meeting,这里主要是审查维度和指标定义是否符合业务需求和规范要求。
4)提交 ETL 设计和开发
--分享解读:就是干,建表开发吧。
维度设计
几个核心概念
1)维度&维度属性:我们环境描述为“维度”,维度是用于分析事实所需要的多样环境,作用一般是查询约束、分类汇总以及排序等。维度所包含的表示维度的列,称为维度属性。
--分享解读:环境比较抽象,简单说就是看分析问题的视角是什么什么就是维度,维度一般是我们的主键。维度属性和维度知识看问题的角度不一样,他们可以互相转换。
3)代理键和自然键:它们都是用于标识某维度的具体值,但代理键是不具有业务含义的键, 一般用于处理缓慢变化维,自然键是具有业务含义的键。
--分享解读:代理键和自然键是相对概念。商品ID对于业务系统来说是自然键,对数据库是代理键。
4)缓慢变化维:维度的属性并不是静态的,它会随着时间的流失发生缓慢的变化。这种随时间发生变化的维度我们一般称之为缓慢变化维。
--分享解读:在数据仓库建设过程中,虽然有代理键这个概念去处理缓慢变化维,具体技术是SCD表,也就是拉链表,但是一般情况下我们能不用就尽量不用这项技术。目前大家看到公司上万张表也几乎没有这类型表。
维度设计的基本方法
维度的设计过程就是确定维度属性的过程,如何生成维度属性,以及所生成的维度属性的优劣,决定了维度使用的方便性,成为数据仓库易用性的关键。正如 Kimball 所说的,数据仓库的能力直接与维度属性的质量和深度成正比。
--分享解读:这个过程最重要的是梳理业务系统与业务逻辑,这也是需要占用大部分工作时间做的事情。
1)选择或者定义一个维度,维度必须是唯一的。
2)确定主维表
3)确定相关维度表
4)确定维度属性:
①尽可能生成丰富的维度属性:字段要多
②尽可能多地给出包括一些富有意义的文字性描述:ID和名称都要有。
③区分数值型属性和事实,数值型宇段是作为事实还是维度属性,可以参考字段的一般用途。
④尽量沉淀出通用的维度属性:有些维度属性获取需要进行比较复杂的逻辑处理,有些需要通过多表关联得到,或者通过单表的不同宇段混合处理得到,或者通过对单表的某个字段进行解析得到。此时,需要将尽可能多的通用的维度属性进行沉淀。一方面,可以提高下游使用的方便性,减少复杂度;另一方面,可以避免下游使用解析时由于各自逻辑不同而导致口径不一致。
维度设计会遇到的问题
1)维度层级处理:维度是有层次结构的,例如大区->省->城市->区县这个层级结构,不同层级结构下,是实例化成多个维度还是放在最细的维度下作为维度属性存在呢?当属性层次被实例化为一系列维度,而不是单一的维度时,被称为雪花模型(规范化)将维度的属性层次合并到单个维度中的操作称为反规范化。分析系统的主要目的是用于数据分析和统计,如何更方便用户进行统计分析决定了分析系统的主要是做反规范化。
2)一致性维度和交叉探查:构建企业级数据仓库不可能一蹦而就, 一般采用迭代式的构建过程。 而单独构建存在的问题是形成独立型数据集市,导致严重的不一致性。 Kimball 的数据仓库总线架构提供了一种分解企业级数据仓库规划任任务的合理方法,通过构建企业范围内一致性维度和事实来构建总线架构。下面总结维度一致性的几种表现形式:
① 共享维表:特定维度有且只有一个
② 一致性上卷:其中一个维度的维度属性是另一个维度的维度属性的子集,且两个维度的公共维度属性结构和内容相同。
③ 交叉属性 :两个维度具有部分相同的维度属性。
有了一致性维度就可以做数据探查了,而将不同数据域的商品的事实合并在一起进行数据探查 ,如计算转化率等,称为交叉探查。
--分享解读:一致性维度是一个特别难的一个事情,只要说一致性就是一个难题也是一个重点。
维度整合与拆分
数据由面向应用的各类异构和有历史包袱和背景的操作型环境进人数据仓库后,需要进行数据集成。将面向应用的数据转换为面向主题的数据仓库数据,本身就是一种集成。通常有以下几种整合方式:采用主从表的设计方式:将两个表或多个表都有的字段放在主表中(主要基本信息),从属信息分别放在各自的从表中。主表中的主键通常建议采用复合主键的方式生成。直接合并:共有信息和个性信息都放在同一个表中。如果表 字段的重合度较低,则会出现大量空值,对于存储和易用性 会有影响,需谨慎选择。不合并:因为源表的表结构及主键等差异很大,无法合并, 使用数据仓库里的多个表存放各自的数据。
1)水平整合:即不同的来源表包含不同的数据集,不同子集 之间无交叉,也可以存在部分交叉。
--分享解读:UNION成高表
2)垂直整合:即不同的来源表包含相同的数据集,只是存储的信息不同。
--分享解读:JOIN成宽表
有整合就有拆分,到底是整合还是拆分,由多种因素决定。下面两 节讨论维度的水平拆分和垂直拆分。
1)水平拆分:
将维度的不同分类实例化为不同的维度,同时在主维度中保存公共属性还是维护单一维度,包含所有可能的属性。在数据模型设计过程中需要考虑的因素有很多,基本不可能满足各个特性指标的最优化。在设计过程中需要重点考虑扩展性、效能、易用性,从建模设计思想上要考虑:
① 维度的不同分类的属性差异情况
① 业务的关联程度
--分享解读:因为网约车业务场景相对单一(高耦合高相似就是单一)我们一般没有水平拆分的需求
2)垂直拆分:在维度设计内容中,我们提到维度是维度建模的基础和灵魂,维度 属性的丰富程度直接决定了数据仓库的能力。在进行维度设计时,依据 维度设计的原则,尽可能丰富维度属性,同时进行反规范化处理。对于 具体实现时可能存在的问题,一是在“水平拆分”中提到的,由于维度分 类的不同而存在特殊的维度属性,可以通过水平拆分的方式解决此问题。 二是某些维度属性的来源表产出时间较早,而某些维度属性的来 表产出时间较晚;或者某些维度属性的热度高、使用频繁,而某些维度 属性的热度低、较少使用 或者某些维度属性经常变化,而某些维度属 性比较稳定。在“水平拆分”中提到的模型设计的三个原则同样适合解 决此问题。
--分享解读:我们中间层重构的订单表和司机表就是基于垂直拆分的思想,核心考量的其实就是SLA。
维度的变化
1)缓慢变化维:有三种处理缓慢变化维的方式
① 重写维度值
① 插人新的维度行
① 添加维度列
--分享解读:根据不同的需求做不同的维度变化应对动作,一般我们都会tradeoff,基本不用以上三种方式,而是使用维度快照。
维度快照
处理缓慢变化维的一般生产用方法是采用快照方式,原因是
1)简单而有效,开发和维护成本低,足够满足需求用
2)使用方便,理解性好。
拉链表、微型维度这些概念生产不用就不讲了。
特殊维度
1)递归层次维度:
① 层次结构扁平化:对于均衡层次结构,降低递归层次使用复杂度的最简单和有效的方 法是层次结构的扁平化通过建立维度的固定数数级别的属性来实现,可以在一定程度上解决上钻和下钻的问题。
②层次桥接表:对于非均衡层次结构,可以采用桥接表的方式来解决,不需要预先知道所属层级,不需要回填,也可解决非均衡层次结构的问题。灵活性好;但复杂性高,使用成本高。
--分享解读:对于层次桥接表也就是“递归套娃”模式,对于无法预见的将来你只能这么做。
2)行为维度:不细讲,及时通过计算得到的维度,处理方式为一种是将其冗余至现有的维表中, 另一种是加工成单独的行为维表
--分享解读:比如司机常驻城市就是一个行为维度, 中间层重构主要是基于第二种方式,但是为了满足业务做了tradeoff。
3)多值维度:事实表的一条记录在某维表中有多条记 录与之对应。一般有三种处理方式
①降低事实表的粒度
②采用多字段
③采用较为通用的桥接表。
--分享解读:感觉这个命名和释义很别扭,难以接受,不过总是可以理解的,现实中,如何可以一般用第一种处理方式,其他两种用起来个人感受比较难受。
3)多值属性:维表中的某个属性字段同时有多个值,称之为“多值属性”,它是多 值维度的另一种表现形式。一般有三种处理方式
①保持维度主键不变,将多值属性放在维度的一个属性字段中,用map形式存放。
②保持维度主键不变,但将多值属性放在维度的 多个属性字段中。
③维度主键发生变化, 个维度值存放多条记录。
--分享解读:个人喜欢第三种,第二种简直就是灾难,第一种是懒人模式,当然达到数下是tradeoff
杂项维度
杂项维度是由操作型系统中的指示符或者标志宇段组合而成 的,一般不在一致性维度之列,如订单的交易类型字段,它们在源系统中直接保存在交易表中。个事实表中可能会存在多个类似的字段,如果作为事实存放在事 实表 中,则会导致事实表占用空间过大 如果单独建立维表,外键关联 到事实表,则会出现维度过多的情况;如果将这些字段删除,则会有人不同意。这时,通常的解决方案就是建立杂项维度 ,将这些字段建立到 维表中,在事实表中只需保存一个外键即可
--分享解读:最tradeoff的东西,我们一般直接退化到事实表或者维度表了,不单独搞。
事实表设计
事实表作为数据仓库维度建模的核心,紧紧围绕着业务过程来设计,通过获取描述业务过程的度量来表达业务过程,包含了引用的维度和与业务过程有关的度量。
几个核心概念
1)粒度:事实表中一条记录所表达的业务细节程度被称为粒度,通常粒度可以通过两种方式来表述:一种是维度属性组合所表示的细节程度:一种是所表示的具体业务含义。
2)事实:一般为整型或浮点型的十进制数值,有可加性、半可加性和不可加性三种类型。可加性事实是指可以按照与事实表关联的任意维度进行汇总。半可加性事实只能按照特定维度汇总不能对所有维度汇总。还有一种度量完全不具备可加性,比如比率型事实。
3)退化维度:维度属性也可以存储到事实表中,这种存储到事实表中的维度列被称为“退化维度”。
4)事务事实表:用来描述业务过程,跟踪空间或时间上某点的度量事件,保存的是最原子的数据,也称为“原子事实表”。 举例:发单做单表
5)周期快照事实表:以具有规律性的、可预见的时间间隔记录事实 ,时间间隔如每天、每月、每年等。
6)累积快照事实表:用来表述过程开始和结束之间关键步骤事件,覆盖过程的整个生命周期,通常具有多个日期字段来记录关键时间点, 当过程随着生命周期不断变化时,记录也会随着过程的变化而被修改。
--分享解读:①事务事实表:发单做单表 ②周期快照事实表:常见的聚合事实表属于此类 ③累积快照事实表:v_order_base表,后面会详细讲到他们分别存在的意义和适用场景。一般的我们明细的事实表基本上就是这几种方式建设,还有聚合型事实表我们后面会介绍
事实表设计原则
1)尽可能包含所有与业务过程相关的事实
2)只选择与业务过程相关的事实
3)分解不可加性事实为可加的组件
4)在选择维度和事实之前必须先声明粒度:粒度越细越好(灵活性),明细事实一般用业务描述表示粒度,聚合事实一般用维度表达粒度。
5)在同一个事实表中不能有多种不同粒度的事实
6)事实的单位要保持一致
7)对事实的 null 值要处理
8)使用退化维度提高事实表的易用性
--分享解读:
关于第3条:也就是我们常说的要存分子分母不要存比例,大家以后纠结要不要加一个比率的字段的时候就想想原则
关于第4条,在设计之初一定要把表达粒度的字段放到最前面以便于理解
关于第5条:这么做事为了能正常进行汇总计算,举个例子,订单包含过个行程,那“计费时长”这个事实表达的粒度为订单级别,而不是行程级别的,对于拼车单,想要计算乘客的行程计费时长显然是错误的。应该从行程粒度的事实去计算。
关于第6条:主要为了易用,始终如一
关于第7条:这个可能有争议,原本资料想表达的是为了SQL使用的时候不因为null的特殊性导致使用出错,建议用0代替,但是这么做有带来了0的含义的定义,而且不同的字段本身含义和类型也不同且0本身又有自己的含义,目前公司层面没有强规范要求,这个我们也没法一定说这么做是合适的,要不要处理最起码要和第6条一样,要始终如一,一个表要处理及所有字段都处理,要不就都别处理。
关于第8条:退化维度使用的爽,但是也不是一味的退化,尤其要注意几点:
①退化到事实表的维度是不是易变的:举例:司机常驻城市如果退化到订单表其实就不合适
②逐层退化可能导致数据错误:举例:每个订单对应有个driver_id 对应有当时的车辆gvid,如果把司机当前绑定的gvid退化到订单表就会产生错误,为了避免这种错误可能有命名了一个bind_gvid字段,但是这又带来了理解成本,这个bind_gvid是司机当前绑定的gvid呢还是订单时的gvid呢?
虽然设计是妥协的艺术,但是我们的dwd_order_evend_d 为了满足大家毫无理性的需求几乎违反了所有的设计原则。
事实表设计方法
1)选择业务过程及确定事实表类型
2)声明粒度
3)确定维度
4)确定事实
5)冗余维度
--分享解读:设计完回头看看设计原则,除了第8条,其他都没得商量。
事务事实表
订单作为交易行为的核心载体,直观反映了交易的状况。订单的流转会产生很多业务过程,而发单、完单、支付这几个业务过程是整个订单的关键节点。对这几个业务过程的数据统计也是数据分析的重点,事务事实表设计可以很好地满足这个需求。
1)单事务事实表:顾名思义,即针对每个业务过程设计一个事实表。
--分享解读:什么算一个业务过程,这个本身是一个建模层面的抽象,不是一个客观的定义,例如我们数仓的:dwd_order_call_grab_d,dwd_order_make_d,dwd_order_pay_sucess_d表,
2)多事务事实表:将不同的事实放到同一个事实表中,即同一事实表包含不同的业务过程。多事务事实表在设计时有两种方法进行事实的处理:
①不同业务过程的事实使用不同的事实字段进行存放
②不同业务过程的事实使用同一个事实字段进行存放,但增加一个业务过程标识
--分享解读:我们中间层重构2.0的dwd_ord_core_event_di表就基本上是多事务事实表,使用第1种处理方式,一般的,个人认为不使用第二种方式,这种复用字段做成高表的方式从实际业务的可行性和理解使用上都是有很大隐患的。第1种处理方式存在的问题主要可能是0值过多或者重复字段过多的问题
3)具体使用单事务事实表还是多事务事实表主要考量如下因素:
①业务过程:先需要分析不同业务过程之间的相似性和业务源系统的关系
--分享解读:比如订单这个事实,发单、接单、完单、支付这些业务过程在不同的业务源系统,他们天然的需要在最底层分别构建一个单事务事实表。
②粒度和维度:在确定好业务过程后,需要基于不同的业务过程确定粒度和维度,当不同业务过程的粒度相同,同时拥有相似的维度时,此时就可以考虑采用多事务事实表。
③事实:对于不同的业务过程,事实往往是不同的,单事务事实表在处理事务实现上比较方便和灵活,仅仅体现同一个业务过程的事实即可,而多事务事实表由于有多个业务过程,所以有更多的事实需要处理。如果单事务过程的事实较多,同时不同业务过程的事实又不相同,则可以考虑使用单事务事实表,处理更加清晰。若使用多事务事实表,会导致事实表零值或空值字段较多。
④下游使用场景。
--分享解读:公共层数仓建设可能大家会关注更多的建模规范,也就是业务过程、粒度和维度、事实等的逻辑,但在业务数据建设中,更多的是我了满足需求方的预期,再回头看我们重构前的订单事件表,就可以理解他为什么演变成那个样子了。
⑤存储计算成本。
4)事实的设计准则:完整性、一致性、可加性。
周期快照事实表
当需要一些状态度量时,则需要聚集与之相关的事务才能进行识别 ;或者聚集事务无法识别 ,比如温度等。对于这些状态度量,事务事实表是无效率的,而这些度量也和度量事务本身一样是有用的 ,因此,维度建模理论给出了第二种常见的事实表一一周期快照事实表,简称“快照事实表”。快照事实表在确定时间间隔内对实体的度量进行抽样,这样可以很容易地研究实体的度量值,而不需要聚集长期的事务历史。
快照事实表的设计有一些区别于事务事实表设计的性质。事务事实表的粒度能以多种方式表达,但快照事实表的粒度通常以维度形式声明事务事实表是稀疏的。但快照事实表是稠密的,事务事实表中的事实是完全可加的,但快照模型将至少包含一个用来展示半可加性质的事实。
--分享解读:我们很多的事实表一定程度上可以理解为事务事实表,一定程度上也是快照事实表,但是我们的dwd表一般为事务事实表,我们部分dwm表为周期快照事实表。快照本事并不是事实表的属性,快照表和可以是维度表,目前我们dd数仓建设的维度表大多数是维度快照表,很少有bizdata.dim_trip_city_region_mapping 大区映射表这样单纯的维度表,快照本身核心在于记录”变化“和”状态“
周期快照表的一些特性
1)用快照采样状态
2)快照粒度:可以简单地理解为快照需要采样的周期以及什么将被采样。
3)密度与稀疏性:快照事实表和事务事实表的关键区别在密度上。事务事实表是稀疏的,只有当天发生的业务过程,事实表才会记录该业务过程的事实, 如下单、支付等;而快照事实表是稠密的,无论当天是否有业务过程发生,都会记录行。稠密性是快照事实表的重要特征,如果在每个快照周期内不记录行,比如和事务事实表一样 ,那么确定状态将变得非常困难。
--分享解读:翻译一下就是:比如司机维度指标的聚合表,我们每天都记录每个实际的完单量指标,如果某个司机没有完单量,我们记为0,但实际上基于各种原因的考量我们可能并不是这么做的,如果司机当天没有完单,我们的表里当天的分区就没有这个司机这个纪律,其实这严格上就违反了这个快照的定义。但是维度快照表我们就不能也没有违反过这个定义,核心是这样做也能解决问题,也能被接受和理解。
4)半可加性:在快照事实表中收集到的状态度量都是半可加的。与事务事实表的可加性事实不同,半可加性事实不能根据时间维度获得有意义的汇总结果。但快照事实表在每个采样周期内是不能对状态度量进行汇总的
--分享解读:这个半可加性和半可加指标不是一个意思,这个指的是不能对周期快照表指标做完全累加。举例:将司机聚合表的每天的history_gmv字段进行累加sum(history_gmv)没有任何统计学的意义。
累积快照事实表
累积快照事实表的典型特征是多业务过程日期,用于计算业务过程之间的时间间隔 ,对于类似于研究事件之间时间间隔的需求,采用累积快照事实表可以很好地解决。事务事实表记录事务发生时的状态,对于实体的某一实例不再更新,而累积快照事实表则对实体的某一实例定期更新。
--分享解读:区别于多事务事实表,只追加“记录”,类似日志,而累积快照是回“回溯”更新的,在事实粒度上是一个事实是唯一的,会被不断刷新,典型的gulfstream_dw.dw_v_order_base就是一个累积快照事实表。
对于累积快照事实表,还有一个重要作用是保存全量数据,一存放加工后的事实,并将各维度常用属性和订单 杂项维度退化到此表中。通常用于数据探查、统计分析、数据挖掘等。
--分享解读:这样的场景是合理的,但是一般情况下这种快照表要保证数据的准确性和完整性,是有一定的时间滞后性的,滞后的时间长短取决于业务的场景,因此在做历史行为分析等方面有作用,大多数业务场景最多容忍一天延迟的需求场景,这类场景这种表使用起来就很难受了。
累积快照表的实现方式:
1)全量表的形式:此全量表一般为日期分区表 ,每天的 分区存储昨天的全量数据和当天的增量数据合并的结果,保证每条记录 的状态最新。
2)全量表的变化形式:此种方式主要针对事实表数据量 很大的情况。较短生命周期的业务实体 般从产生到消亡都有一定的时 间间隔,可以测算此时间间隔,或者根据商业用户的需求确定一个相对 较大的时间间隔
3)以业务实体的结束时间分区:每天的分区存放当天 束的数据,设计一个时间非常大的分区,比如 3000-12-31 ,存放截至当 前未结束的数据。
--分享解读:每一种实现方式都有各自解决的问题和引入的新问题,根据需要tradeoff
三种事实表的比较
事务事实表 | 周期快照事实表 | 累积快照事实表 | |
---|---|---|---|
时间 | 离散事务时间点 | 有规律的,可预测的间隔产生快照 | 用于时间跨度不确定的不断变化的工作流 |
日期维度 | 事务日期 | 快照日期 | 相关业务过程涉及的多个日期 |
粒度 | 每行代表实体的一个事务 | 每行代表某时间周期的一个实体 | 每行代表一个实体的生命周期 |
事实 | 事务事实 | 累积事实 | 相关业务过程事实和时间间隔事实 |
事实表加载方式 | 插入 | 插入 | 插入与更新 |
事实表更新方式 | 不更新 | 不更新 | 业务过程变更时更新 |
无事实的事实表
在维度模型中,事实表用事实来度量业务过程,不包含事实或度量的事实表称为“无事实的事实表”。虽然没有明确的事实,但可以用来 支持业务过程的度量。
常见的无事实的事实表主要有如下两种: 第一种是事件类的,记录事件的发生,但不在乎其事实。第二种是条件、范围或资格类的,记录维度与维度多对多之间的系。
聚集型事实表
数据仓库的性能是数据仓库建设是否成功的重要标准之一。聚集主要是通过汇总明细粒度数据来获得改进查询性能的效果。通过访问聚集数据,可以减少数据库在响应查询时必须执行的工作量,能够快速响应用户的查询,同时有利于减少不同用户访问明细数据带来的结果不一致问题。
--分享解读:聚合表是我们应用产品方最喜欢的数据表,但是也是最难做好的表。一般就是这种_d _7d 30d _MTD结尾的表,我们一般很少做。
1)聚集的基本原则:
①-致性:聚集表必须提供与查询明细粒度数据 致的查询结果。
② 避免单一表设计:不要在同个表中存储不同层次的聚集数据否则将会导致双重计算或出现更糟糕的事情。
③聚集粒度可不同:聚集并不需要保持与原始明细粒度数据同样的粒度,聚集只关心所需要查询的维度。
2)聚集的基本步骤:
①确定聚集维度:这时候需要确定根据什么维度聚集。
②确定一致性上钻:这时候要关心是按月汇总还是按天汇总,按司机汇总还是按城市汇总,我们要做的只是了解用户需要什么,然后按照他们想要的进行聚集。
③确定聚集事实:在原始明细模型中可能会有多个事实的度量,比如在交易中有交易额、交易数量等,这时候要明确是按照交易额汇总还是按照成交数量汇总。
--分享解读:聚合的维度一定要首先明确,而不是通过一些trick的方式表达当指定什么条件的情况下按照什么维度聚合否则就是什么聚合。这个在当前中间层设计也有这个问题
3)聚集的一些说明:
①聚集是不跨越事实的:聚集是针对原始星形模型进行的汇总,为了获取和查询与原始模型 一致的结果,聚集的维度和度量必须与原始模型保持一致,因此聚集是不跨越事实的。横向钻取是针对多个事实基于一致性维度进行的分析, 很多时候采用融合事实表,预先存放横向钻取的结果,从而提高查询性能。因此融合事实表是种导出模式而不是聚集。
--分享解读:我们实际生产中大量使用的其实是融合事实表,而不是聚合表,但是命名上他们是一致的。
①聚集带来的问题:聚集会带来查询性能的提升,但聚集也会增加 ETL 维护的难度,当上游依赖发生变更时,先前存在的、已经被汇总到聚集表中的数据需要被重新调整。这一额外工作随着业务复杂性的增加,会导致多数 ETL 人员选择简单强力的方法,删除并重新聚集数据。
参考学习资料
1.大数据之路:阿里巴巴大数据实践 第10章和第11章
2.课外参考资料:美团点评酒旅数据仓库建设实践(不会在这里出题)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!