Bootstrap

数仓建设规范

一、 数据模型架构原则

1. 数仓分层原则

一个好的分层架构,要有以下好处:

  • 清晰数据结构;
  • 数据血缘追踪;
  • 减少重复开发;
  • 数据关系条理化;
  • 屏蔽原始数据的影响。

数仓分层要结合公司业务进行,并且需要清晰明确各层职责。
数仓建模是在DW层进行,所以DW层是数仓建设的核心层

(1) 数据源层:ODS(Operational Data Store)
ODS 层,是最接近数据源中数据的一层,为了考虑后续可能需要追溯数据问题,因此对于这一层就不建议做过多的数据清洗工作,原封不动地接入原始数据即可。

(2) 数据仓库层:DW(Data Warehouse)
数据仓库层是我们在做数据仓库时要核心设计的一层,在这里,从 ODS 层中获得的数据按照主题建立各种数据模型。

DW 层又细分为 DWD(Data Warehouse Detail)层、DWM(Data WareHouse Middle)层和 DWS(Data WareHouse Servce) 层。

1) 数据明细层:DWD(Data Warehouse Detail)
该层一般保持和 ODS 层一样的数据粒度,并且提供一定的数据质量保证。DWD 层要做的就是将数据清理、整合、规范化、脏数据、垃圾数据、规范不一致的、状态定义不一致的、命名不规范的数据都会被处理。
同时,为了提高数据明细层的易用性,该层会采用一些维度退化手法,将维度退化至事实表中,减少事实表和维表的关联。

另外,在该层也会做一部分的数据聚合,将相同主题的数据汇集到一张表中,提高数据的可用性 。

2) 数据中间层:DWM(Data WareHouse Middle)
该层会在 DWD 层的数据基础上,数据做轻度的聚合操作,生成一系列的中间表(原子指标层),提升公共指标的复用性,减少重复加工。
直观来讲,就是对通用的核心维度进行聚合操作,算出相应的统计指标。

在实际计算中,如果直接从 DWD 或者 ODS 计算出宽表的统计指标,会存在计算量太大并且维度太少的问题,因此一般的做法是,在 DWM 层先计算出多个小的中间表,然后再拼接成一张 DWS 的宽表。由于宽和窄的界限不易界定,也可以去掉 DWM 这一层,只留 DWS 层,将所有的数据再放在 DWS 亦可。

3) 数据服务层:DWS(Data WareHouse Servce)
DWS 层为公共汇总层,会进行轻度汇总,粒度比明细数据稍粗,基于 DWD 层上的基础数据,整合汇总成分析某一个主题域的服务数据,一般是宽表。DWS 层应覆盖 80% 的应用场景。又称数据集市或宽表。

按照业务划分,如主题域流量、订单、用户等,生成字段比较多的宽表,用于提供后续的业务查询,OLAP 分析,数据分发等。

一般来讲,该层的数据表会相对比较少,一张表会涵盖比较多的业务内容,由于其字段较多,因此一般也会称该层的表为宽表。

(3) 数据应用层:APP(Application)
在这里,主要是提供给数据产品和数据分析使用的数据,一般会存放在 ES、 PostgreSql、Redis 等系统中供线上系统使用,也可能会存在 Hive 或者 Druid 中供数据分析和数据挖掘使用。比如我们经常说的报表数据,一般就放在这里。

(4) 维表层(Dimension)
如果维表过多,也可针对维表设计单独一层,维表层主要包含两部分数据:

  • 高基数维度数据:一般是用户资料表、商品资料表类似的资料表。数据量可能是千万级或者上亿级别。
  • 低基数维度数据:一般是配置表,比如枚举值对应的中文含义,或者日期维表。数据量可能是个位数或者几千几万。
2. 主题域划分原则

(1) 按照业务或业务过程划分
业务:就是指的功能模块/业务线。

业务过程:指企业的业务活动事件,如下单、支付、退款都是业务过程。不过需要注意的是,一个业务过程是一个不可拆分的行为事件,通俗的讲,业务过程就是企业活动中的事件。

(2) 按照数据域划分
数据域是指面向业务分析,将业务过程或者维度进行抽象的集合。其中,业务过程可以概括为一个个不可拆分的行为事件,在业务过程下,可以定义指标,维度是指度量的环境,如买家下单事件,买家是维度。为保障整个体系的生命力,数据域是需要抽象提炼,并且长期维护和更新的,但不轻易变动。在划分数据域时,既能涵盖当前所有的业务需求,又能在新业务进入时无影响地被包含进已有的数据域中和扩展新的数据域。

3. 数据模型设计原则

(1) 高内聚、低耦合
即主题内部高内聚、 不同主题间低耦合。明细层按照业务过程划分主题,汇总层按照“实体+ 活动”划分不同分析主题,应用层根据应用需求划分不同应用主题。

(2) 核心模型和扩展模型要分离
建立核心模型与扩展模型体系,核心模型包括的字段支持常用的核心业务,扩展模型包括的字段支持个性化或少量应用的需要,不能让扩展模型的字段过度侵入核心模型,以免破坏核心模型的架构简洁性与可维护性

(3) 公共处理逻辑下沉及单一
越是底层公用的处理逻辑越应该在数据调度依赖的底层进行封装与实现,不要让公用的处理逻辑暴露给应用实现,不要让公共逻辑多处同时存在。

(4) 成本与性能平衡
适当的数据冗余可换取查询和刷新性能,不宜过度冗余与数据复制。

(5) 数据可回滚
处理逻辑不变,在不同时间多次运行数据结果确定不变。

二、 数仓公共开发规范

1. 层次调用规范

稳定业务:按照标准的数据流向进行开发,即 ODS –> DWD –> DWS –> APP。
非稳定业务或探索性需求:可以遵循 ODS -> DWD -> APP 或者 ODS -> DWD -> DWM ->APP 两个模型数据流。

  • 正常流向:ODS -> DWD -> DWM -> DWS -> APP,当出现 ODS -> DWD -> DWS -> APP 这种关系时,说明主题域未覆盖全。应将 DWD 数据落到 DWM 中,对于使用频度非常低的表允许 DWD -> DWS。
  • 尽量避免出现 DWS 宽表中使用 DWD 又使用(该 DWD 所归属主题域)DWM 的表。
  • 同一主题域内对于 DWM 生成 DWM 的表,原则上要尽量避免,否则会影响 ETL 的效率。
  • DWM、DWS 和 APP 中禁止直接使用 ODS 的表, ODS 的表只能被 DWD 引用。
  • 禁止出现反向依赖,例如 DWM 的表依赖 DWS 的表。
2. 数据类型规范

需统一规定不同的数据的数据类型,严格按照规定的数据类型执行:

  • 金额:double 或 使用 decimal(28,6) 控制精度等,明确单位是分还是元。
  • 字符串:string。
  • id类:bigint。
  • 时间:string。
  • 状态:string
3. 数据冗余规范

宽表的冗余字段要确保:

  • 冗余字段要使用高频,下游3个或以上使用。
  • 冗余字段引入不应造成本身数据产生过多的延后
  • 冗余字段和已有字段的重复率不应过大,原则上不应超过60%,如需要可以选择join或原表拓展。
4. NULL字段处理规范
  • 对于维度字段,需设置为-1
  • 对于指标字段,需设置为 0
5. 指标口径规范

保证主题域内,指标口径一致,无歧义。

通过数据分层,提供统一的数据出口,统一对外输出的数据口径,避免同一指标不同口径的情况发生。

(1) 指标梳理
指标口径的不一致使得数据使用的成本极高,经常出现口径打架、反复核对数据的问题。在数据治理中,我们将需求梳理到的所有指标进行进一步梳理,明确其口径,如果存在两个指标名称相同,但口径不一致,先判断是否是进行合并,如需要同时存在,那么在命名上必须能够区分开。

(2) 指标管理
指标管理分为原子指标维护和派生指标维护。

原子指标:

  • 选择原子指标的归属产线、业务板块、数据域、业务过程
  • 选择原子指标的统计数据来源于该业务过程下的原始数据源
  • 录入原子指标的英文名称、中文名称、概述
  • 填写指标函数
  • 系统根据指标函数自动生成原子指标的定义表达式
  • 系统根据指标定义表达式以及数据源表生成原子指标SQL

派生指标:

  • 在原子指标的基础之上选择了一些维度或者修饰限定词。
6. 数据表处理规范

(1) 增量表

  • 新增数据,增量数据是上次导出之后的新数据。
  • 记录每次增加的量,而不是总量;
  • 增量表,只报变化量,无变化不用报;
  • 每天一个分区。

(2) 全量表

  • 每天的所有的最新状态的数据。

  • 全量表,有无变化,都要报;

  • 每次上报的数据都是所有的数据(变化的 + 没有变化的);

  • 只有一个分区。

(3) 快照表

  • 按日分区,记录截止数据日期的全量数据。

  • 快照表,有无变化,都要报;

  • 每次上报的数据都是所有的数据(变化的 + 没有变化的);

  • 一天一个分区。

(4) 拉链表

  • 记录截止数据日期的全量数据。

  • 记录一个事物从开始,一直到当前状态的所有变化的信息;

  • 拉链表每次上报的都是历史记录的最终状态,是记录在当前时刻的历史总量;

  • 当前记录存的是当前时间之前的所有历史记录的最后变化量(总量);

  • 只有一个分区。

四、数仓命名规范

1. 词根设计规范

词根属于数仓建设中的规范,属于元数据管理的范畴,现在把这个划到数据治理的一部分。完整的数仓建设是包含数据治理的,只是现在谈到数仓偏向于数据建模, 而谈到数据治理,更多的是关于数据规范、数据管理。

表命名,其实在很大程度上是对元数据描述的一种体现,表命名规范越完善,我 们能从表名获取到的信息就越多。比如:一部分业务是关于货架的,英文名是:rack, rack 就是一个词根,那我们就在所有的表、字段等用到的地方都叫 rack,不要叫成 别的什么。这就是词根的作用,用来统一命名,表达同一个含义。

指标体系中有很多“率”的指标,都可以拆解成 XXX+率,率可以叫 rate,那我 们所有的指标都叫做 XXX+rate。

词根:可以用来统一表名、字段名、主题域名等等。

参考文章:
[1] 数仓建设规范指南

;