跳转至

数仓理论总结

组件和架构

架构

lambda架构

顾名思义,形似lambda,也就是离线和实时两条线并行。

整体分为批处理,流处理两个分支。其中流处理层负责快速计算,获得想要的结果,而批处理层负责大批量精确处理所有数据,并且最终可以将流处理层的非精确处理数据替换掉。

两者的计算结果最终都输出到服务层,服务层通过返回预先计算的数据视图,来相应app的查询。

kappa架构

也就是纯流式处理,去掉了批处理层,延迟更低。

但是与此同时带来两个问题

  • 整个系统需要保持端到端的exactly-once
  • 系统处理历史数据的压力越来越大

流批一体

也就是将流数据和批数据放在同一个框架中,进行一体化处理。

  • Spark
  • 批处理:SparkSQL
  • 流处理:StructStreaming
  • Flink:可同时流批处理,通过改变计算图的触发时机来控制。
  • Doris:也可以做流批一体,这个在官网和一本书上都看到过。

数仓建设

数据库类别

OLTP

online-transcation-processing,是面向当前数据的,以事务为核心的分析处理系统。最典型的就比如MySQL等关系型数据库。通过前端触发后端相应,从而驱动数据库的状态改变。

OLAP

online-analysis-processing,是面向当前数据,以及海量历史数据的,以主题为核心的分析处理系统。整个数据仓库系统就是一个OLAP。当然,我感觉一般说OLAP的话特指的是Doris这类的OLAP引擎。

分层

原因

  • 减少重复开发。可以将常用的表沉淀下来,减少不必要的开发,从而减少资源消耗。
  • 数据血缘追踪。追踪每个表的上下游情况,表owner是谁,方便运维管理。
  • 解耦。而不是烟囱式开发-直接从ods穿透。方便整体数据的修改和整理。
  • 视角不同。不同的人关注不同粒度的数据,所以必然需要分层,这是必要性。不可能给每个职位的人同样一个粒度的数据报告。

内容

主要分为三大层,也就是ODS,CDM,ADS

  • ODS 也称为操作数据层、数据贴源层。需要将不同数据源的数据同步到一起,进行简单的统一整理即可(比如两个数据源的同一个含义的字段使用不同类型进行存储)。
  • CDM 公共维度模型层。用于存放明细事实数据,维度表数据,以及公共指标汇总数据。其中明细数据表,维度表通过ODS层数据加工而来,公共指标汇总数据通过明细数据表,维度表加工而来。
  • DWD层:明细数据层,同时可以采用维度退化手段(空间换时间),提高明细数据表的易用性。
  • DWS层:加强指标的维度退化,采用更多的宽表化手段来构建,提高公共指标的复用性,减少重复加工。一般是按照周期、维度来聚合成指标较多的宽表。需要在本层完成指标口径统一(比如xxx_1d,xxx_7d,xxx_td)表。
  • ADS
  • 按照应用域划分,存放数据产品的特化统计指标,其通过CDM层数据以及ODS层数据加工而来。
  • 当然,如果多个应用使用同一个特化指标,可以将其沉淀到CDM层方便复用。

建模方法论

ER模型

也就是实体-关系模型。具体的话可以从1NF开始到3NF。

  • 每个属性都不可再分
  • 非主字段完全依赖于主键(复合主键的整体),不能单独依赖于其中的一部分
  • 非主字段不能依赖于其他非主字段

这里一般说的是OLTP中的ER模型,其是面向某个具体业务流程的实体对象关系的抽象。而其实OLAP中也有ER模型,但是好像都不用这个。

维度模型

kimball提出,通常有两种实现-星型模型和雪花模型。

  • 星型模型
  • 对数据做了冗余
  • 效率较高
  • 雪花模型
  • 对数据拆到没有冗余
  • 效率低下

建模流程如下

  1. 选择需要进行分析决策的业务过程。这个业务过程可以是单个业务事件,比如支付,退款。也可以是多个事件组成的业务流程,或者某个事件的状态。
  2. 选择粒度。通常,选择多个维度组合起来上卷,组成自己想要的粒度。
  3. 识别维表。通过需要的粒度组织必须的维度信息。
  4. 选择事实(具体数字)列,来确定分析需要衡量的指标。

建模流程

名词术语

数据域

面向业务分析,将业务过程或者维度进行抽象的集合。

业务过程

指的是企业的业务活动时间,比如下单,支付,退款。是一个不可拆分的行为事件。

度量

也成为原子指标。是某一个业务事件行为的度量,比如下单了xxx元,也即支付金额等。

维度

维度是度量(原子指标)的环境,其属于一个数据域。通常有地理维度,或者时间维度。

派生指标

通常指的是一个原子指标 + 多个修饰词 + 时间周期。比如最近一天的某用户的消费总额。

构建流程

  1. 需求调研。面向不同主题的数据需求,是驱动数据仓库建设的根本。通常通过和业务结合最近的数分来收集。
  2. 数据域划分。数据域是面向业务分析,将业务过程和维度进行抽象的集合。比如可以构建出商品域,日志域,交易域等。以交易域为例子,其中由包含加购,下单,支付,退款,收获等业务过程。
  3. 构建总线矩阵。做两件事情,分别是明确每个数据域的业务过程集合,以及每个业务过程所关联的维度。所以这个矩阵的纵轴是数据域下的业务流程,横轴是所有数据域的全局一致性维度。
  4. 规范定义,明确每个指标的口径(具体计算逻辑)。
  5. 模型设计。

维度设计

维度是维度建模的核心

来源

来源于和业务方的交谈,通常出现在group by / order by语句之后。

维表设计

首先,从ODS中抽取一个来源于后台数据库的核心维度表,也称为主维表。

如果是数仓中的商品维度,则可以直接取业务数据库的商品维度作为主维表。

然后,确定相关维表。也就是通过分析,得出该维度表可能和哪些表有关系,比如商品表可能和商家,用户等维度有关系,可以将它们直接通过外键JOIN过来。

通常这个过程,就是维度表的反规范化,也就是将主维表,相关维表有用信息合并起来成为一张表。

最后,将这个大维度表进行筛选和列裁剪,取自己关心的最小集即可。

下钻

通过某个维度,可以对事实表进行下钻统计。也就是从最高类目 -> 一级类目 -> 二级类目等,细化粒度。

维度变化

数据仓库是要做历史统计的。但是维度可能随着时间的流逝,发生变化。比如商品维度中,某个商品之前是A类目,但是现在被划分到了B类目中。那么如何在一个汇聚了所有历史数据的数仓中处理这个维度变化呢?

有三种方式:

  • 重写维度值:也就是直接将维度表的对应位置修改为最新值即可,之后无论新旧事实数据,所有的关联维度取的都是最新维度。
  • 插入新的维度行:新加一个维度行,并增加两个时间戳字段,让新旧历史数据的维度有效分开。
  • 添加新的维度列:新加一个维度列,JOIN的时候可以根据条件判断要新的还是旧的,从而可以在不同维度上卷。

极限存储(拉链存储)

使用的就是第二种方式,也就是插入新的维度行的方式。

也就是商品维度变更的时候,并不直接原地更新,而是拆分为两段。比如:

  • t1-t2,类型1
  • t2-now,类型2

其实思路类似于流表理论中的思想,记录变化而不是直接汇总得出结果。其实WAL也是类似思想。

如何对用户无感知呢?

阿里是直接在语法树部分改的,也就是对语法树遍历的时候生成AST树的时候,内部算子的条件会做自动的修改,做到对用户透明。

事实表设计

整体流程

  1. 识别业务过程
  2. 选择事实表类型
  3. 声明粒度和维度
  4. 确定度量值
  5. 维度退化

类型

事实表分为三种类型,分别是事务型事实表,累积快照事实表,周期快照事实表。

事务事实表-DWD层

一般一行代表一种业务过程的事务。

  • 单事务事实表,一个表对应一种业务过程的事务。比如下单/签收。
  • 多事务事实表(其实和下面的累积快照事实表类似),一个表对应多个业务过程的事务组合,比如从下单到签收。

适用于长生命周期的实体,比如用户。

累积快照事实表-DWD层

一行代表一个实体所设计到的多个业务过程的组合(反应完整的生命周期)。最重要的是记录每个流程的时间。

比如子订单从下单-支付-发货-收获的完整过程的时间组合。

其适用于短周期的实体,比如交易订单等。

周期快照事实表-DWS层

也就是最长td表,3d表等经过汇总的数据,通过定期汇总,来压缩为周期的,不同粒度的快照数据。

事实表也有拉链存储,具体和维度表的拉链存储一样。

其他

数据域和主题域

数据域是数仓从上游数据源拿到数据之后,对数据的抽象组织。

而主题域是从下游数据应用层接到需求之后,对数仓自己所提供的数据服务领域的划分。

简单说,一个是从下开始,一个是从上开始。