目录
前言
主要包括数据模型设计规范、数仓公共开发规范、数仓各层开发规范、数仓命名规范。
一、数据模型设计规范
1.1 数仓分层原则
优秀的数仓体系需要清晰的数据分层结构,即要保证数据层的稳定又要屏蔽对下游的影响,并且要避免链路过长。数仓分层没有最好,只有最合适。一个好的分层架构,要有以下好处:
- 数据血缘追踪:厘清表/任务上下游依赖关系、把握数据流向,方便问题溯源及bug定位。
- 屏蔽业务侧改造对下游的直接影响:
- 一旦业务系统改造,涉及到ods原始层表变动,会导致下游依赖链路级联改动。
- 如果直接从ods原始层取数,存在业务侧数据质量问题污染下游的风险。
- 减少重复开发:公共的指标口径(ads层)下沉至dws层、提升逻辑复用性、减少后期不必要的开发,从而减少资源消耗,保障口径、数据统一。
- 复杂问题简单化:每一层都有他的作用域和职责,使用表的时能更方便的定位和理解;
数仓分层要结合公司业务进行,基于维度建模理论,一般将数仓架构分为:ODS源数据层、DWD明细数据层、DWS轻度汇总层、ADS应用层。对于每一层的职责、边界、和建模标准进行了清晰地定义。如下图所示:
分层架构 | 层次职责 | |
原始层ODS | 与业务系统基本同构;目的: 保留历史数据,解耦业务数据库。 | |
明细数据层DWD | 1.数据清洗,脱敏,规范化,一般保持和ODS层一样的数据粒度,并且提供一定的数据质量保证 2.为了提高数据明细层的易用性,该层会采用维度退化的手法,将维度退化到事实表中,减少维表和事实表之间的关联。 | 维度层: 1.维度用于描述业务实体所处的环境; 2.常见的维度一般有时间维度、省份维度、用户维度等; |
汇总数据层DWS | 又称为宽表层或数据集市。按照业务划分。例如订单,用户,商家,商品等。基于各个主题进行轻度汇总,如统计各个主题7天、30天、90天的用户购买行为等。DWS是在DWD基础上关联DIM维度数据得到的汇总数据。 | |
数据应用层ADS | 1.该层级的主要目的是支持业务进行某些专题的分析。这里的数据指标会按照业务的具体需求进行设计和包装; 2.一般会根据特定的数据统计口径进行不同交叉维度的计算,用于其他系统的底层数据支持、数据看板可视化展示; 3.该层的数据一般会落到olap引擎用于快速的查询分析。 |
ps: 有的数仓会专设temp层去存储每一层的临时表。
有上述可知,数仓数据链路层次,自下到上,一般分为ods --> dwd --> dws ---> ads层,ods源数据同步及dwd明细数据的加工清洗,一般在数仓建设前期,借助数据平台相对完善的工作机制,基本可以保障数据质量。大部分数据加工、数据处理都是在dws层/ads层完成的,并且相对于其他层级而言,日常改动、迭代更为频繁,出现问题的风险会比较大。因此对于质量把控来说,最核心的主要在于两个部分,dws层和ads层。
1.2 主题域划分原则
数仓主题域:主题域通常是联系较为紧密的数据主题的集合,根据业务需求分析的视角进行划分抽象归类。主题域划分的方法一般有以下几种:
- 按照业务过程划分
一个业务过程抽象出一个主题域,比如业务系统中的商品、交易、物流等。
- 按照业务部门划分
一个业务部门抽象出一个主题域,比如中台部门、业务运营部门、供应链部门等。
- 按照业务系统划分
一个业务系统抽象出一个主题域,比如搬家系统、erp系统等。
1.3 数据模型设计原则
数据模型:组织数据的方式,模型设计一般遵循以下几个原则:
- 高内聚、低耦合、强复用
含义:主题内部高内聚、 不同主题间低耦合,适度通过中间表的方式实现逻辑复用。
将业务相近的数据设计为一个逻辑模型或者物理模型。例如订单有很多来源,包括小米商城、小米网、有品商城以及三方数据等。在 DW层会整合为同一个订单表,同时会对一些缺失字段进行默认处理,保证所有来源的数据最终在 DW 层是统一的,从而实现高内聚。订单和物流被划定为不同的主题,以减少其耦合度。
- 核心模型和扩展模型要分离
建立核心模型与扩展模型体系,核心模型包括的字段支持常用的核心业务,扩展模型包括的字段支持个性化或少量应用的需要。尽量不要让扩展模型的字段过度侵入核心模型,以免破坏核心模型的架构简洁性与可维护性。
模型健壮性评估:既能高效的呈现现有业务的数据组织方式,也能灵活的支撑新增业务接入时的主题扩展需求。
- 公共逻辑下沉及单一
将公共逻辑下沉到中间层(例如:dws,dwm层)开发udf函数的方式进行逻辑封装),不要让公共的处理逻辑暴露给应用侧,不要让公共逻辑在多处同时存在,避免数据不一致。
公共的处理逻辑尽量放在数仓底层(例如:dws,dwm层)去处理,对下游使用方尽量屏蔽复杂的业务逻辑,从而做到口径统一。
例如在订单处理过程中,会有很多无效的订单,识别无效订单的核心逻辑在 DWM 层,这样下游业务方就可以直接使用加工后的标识字段。
上图的牛奶数仓分层方式:数仓分层最底层是 ODS 层,它是贴源数据,与业务数据保持一致。在 ODS 之上是 DW 层,DW 层可以细分为两层:一层是 DWD 基础数据,主要做清洗和规范化,不对数仓团队外部开放使用。另一层是 DWM 层通用数据:基于DWD的数据做关联和聚合,会将核心的逻辑实现放在这一层,用于提升公共数据的复用性,可以开放给外部团队使用。数仓中还有 DIM 层(维度层),DM 层(宽表层),ADS 层(应用数据层),以及 TMP 层(存放临时表)
- 成本与性能平衡
适当的数据冗余可换取查询和数据重刷性能,不宜过度冗余与数据复制。数据冗余带来的成本和关联查询的性能要综合考虑。
例如:在区域维表设计中,针对国家、省份、城市、区县,通过一个区域层级字段将其分类,虽然数据是冗余的,但用户使用起来会比较方便,并且查询更快速。
- 数据可回滚
代码处理逻辑不变,在不同时间段多次运行代码,输出的数据结果不变。不同时间执行数仓调度,历史数据计算出的结果是一致的。
例如:针对日志数据,回溯数据得到的历史指标是不变的 。
- 一致性
在数仓建模过程中,同一业务实体在不同物理表的字段名称、字段含义和命名规范是统一的,这样可以降低理解和使用的成本。同一个字段或命名规范在不同地方代表的含义是一致的,避免增加使用成本案例: tm是字符串时间字段后缀,ts是数值时间戳字段后缀。
1.4 数据模型管理的目标
- 扩展性
提升模型变化的兼容性,让底层的业务变动与上层需求变动对模型冲击最小化,以业务需求支持效率和降低核心模型表数量为目标。
- 易用性
降低下游使用门槛,复杂逻辑前置;通过冗余维度和事实表,公共计算逻辑下沉,明细与汇总共存等为业务提供灵活性,以数仓丰富度为目标。
- 成本
避免烟囱式的重复建设,节约计算、存储成本,人力成本。
- 时效性
提升数据模型产出时效以及需求响应的速度。
1.5 数仓建模的方法
1.5.1 维度建模
按照事实表、维表来构建数据仓库模型的方法,称为维度建模。根据维度表与事实表之间的链接方式,分为星型模型和雪花型模型。
- 星型模型
1)概念:
- 是一种多维的数据关系,由一张事实表(Fact Table)和一组维表(Dimension Table)组成。
- 星型架构是一种非正规化的结构,多维数据集的每一个维度都直接与事实表相连接,不存在渐变维度,所以数据有一点的冗余。
- 星型模型强调的是对维度进行预处理,将多个维度集合到一个事实表,形成一个宽表。
- hive中的大宽表一般都是事实表,其中包含了维度关联的主键和一些度量信息,而维度表则是事实表中维度的具体属性信息,使用的过程中一般通过join来组合数据,对OLAP分析场景支持的更好。
2)特点:
- 星型模型因为数据的冗余,所以很多统计查询不需要做外部的连接,一般情况下效率比雪花模型要高。
- 星型模型不用考虑很多规范化的因素,设计与实现都比较简单。
- 雪花模型
1)概念:
- 雪花模型是对星型模型的扩展,是对星型模型的维表进一步层次化。具体表现为:一个或多个维表没有直接连接到事实表上,而是通过其他维度表间接连接到事实表上时,其形状类似雪花,故称雪花模型。
2)特点:
- 通过最大限度地减少数据存储量以及联合较小的维表来改善查询性能,雪花型结构去除了数据冗余。
- 数据关联分析时候,操作比较复杂,join的基表比较多,其性能并不一定比星型模型高。
-
星型模型 VS 雪花模型
数据仓库建设中大部分场景比较适合借助星型模型去构建底层数据hive表,通过一定程度的冗余来提升查询效率,星型模型对olap的分析引擎支持比较友好。
1.5.2 三范式建模
遵循三范式建模(第一范式:每个属性都不可再分,第二范式:非主键字段都完全依赖于主键,第三范式:非主键字段不能依赖于其他非主键字段)。
1.5.3 三范式与维度建模区别
- 考虑角度不同
- 三范式严格遵循每一范式内容,按照范式内容建模;
- kimball建模,按照多个维度进行分析,更多按照星形模型;
- 出发点不一样
- 3NF建模(三范式建模),考虑自上而下建模(这里的【上】指的是上游数据源,先拥有dw层再往上进行设计,瀑布模型,不易于后期扩展);
- kimball建模(维度建模),考虑自下而上建模(这里的下指的是数据集市),先拥有数据集市来设计dw层,敏捷模型,易于扩展易于后期维护及使用);
- 模型精度不一样
- 三范式模型由于没有分层概念、冗余低、数据精度高;
- kimball建模(维度建模),由于多层建设导致冗余高、数据精度低;
二、数仓公共开发规范
2.1 层次调用规范
标准数据流向应当是ODS原始层–> DWD明细层–> DWS公共层–> ADS应用层,应用层应优先调用公共层数据,不允许应用层跨过公共层从 ODS 层重复加工数据,ODS穿透率是衡量数仓建设好坏的指标之一。
2.2 数据类型规范
ODS层的数据类型应基于源系统的数据类型映射转换。StarRocks中的数据类型参见官网。基于ODS层的字段加工,衍生出来的字段按照以下标准执行:
- 金额:double或者decimal(28,6)控制精度等,明确单位还是分或者元。
- 字符串:string
- Id类和整形数值:bigint
- 时间类:一般string,如果有特殊的格式要求,可以选择性使用date、datetime
- 状态:string
2.3 数据冗余规范
一个表做宽表冗余维度属性时,应该遵循以下建议准则:
- 冗余字段要使用高频,下游3个或以上原则;
- 冗余字段引入不应造成本身数据产生过多的延迟;
- 冗余字段和已有字段的重复率不应过大,原则上不应超过60%;
2.4 空值处理原则
- 汇总指标的空值:空值处理、填充为零。
- 维度属性值为空:汇总到对应维度上时,对于无法对应的统计事实、记录行会填充为-99(未知),对应维表会出现一条-99(未知)的记录。
2.5 指标定义规范(待补充)
三、数仓各层开发规范
3.1 ods层设计的规范
- 同步规范
- 全量初始化同步和增量同步处理逻辑要清晰;
- 以统计日期和时间进行分区存储;
- 目标表字段在源表不存在时要自动填充处理。
- 数据质量
- 全量表必须配置唯一性字段标识;
- ods表数据量级和记录数做环比监控;
3.2 dim层设计的规范
公共维度层设计准则有:
- 一致性
公共维度在不同的物理表中的字段名称、数据类型、数据内容需要保持一致(历史原因导致的不一致的话,需要做好版本控制)。
- 维度的组合与拆分
- 组合原则
如果两个维度具有强关联性,可以将其组合后一起查询。
- 拆分成核心表、扩展表原则
根据业务关联性及下游使用频率等因素,将维表分为核心表、扩展表进行设计;核心表相对字段较少,刷新产出时间较早。扩展表字段较多,且可以冗余核心表部分字段,刷新产出时间较晚,适合数据分析人员使用。
- 适当冗余原则
数据记录数较大的维度表(例如:用户表),可以适当冗余一些子集合,以减少下游join次数(以空间换时间)
3.3 dwd层设计的规范
事实表可以分为:事务性事实表、累积性事实表、周期性事实表。(待补充)
- 事务型事实表设计准则
- 累积性事实表设计准则
- 周期性事实表设计准则
3.4 dws层设计的规范
- 公共汇总层的设计原则
- 不跨数据域
数据域是在较高层次上对数据进行分类聚集的抽象。
- 区分统计周期
在表的命名上要能说明数据的统计周期,如_1d表示最近1天,_td表示截至当天、nd 表示最近n天。
- 汇总的步骤
- 第一步:确定聚集维度
维度可以理解为指标分析的角度
- 第二步:确定一致性上卷
“钻”相对于“维度”而言,作用在于其可以改变维度的层次,变换分析的粒度。向上钻取就是上卷,向下钻取就是下钻。举例:将下单金额按照时间维度向上聚集得到汇总数据,如最近一个月的GMV;把交易流水沿着时间维度向下细探到每个用户产生的明细流水数据,这就叫做下钻。
- 第三步:确定聚集事实
确定聚集的度量值,例如:GMV交易额、商品销售总量等。
四、数仓各层命名规范
4.1 ODS层的命名规范
表命名规则:{层次}.{源系统表名}.{时间单位与增全量},i表示增量,f表示全量,d表示天,h表示小时。
- 增量数据:{project_name}.s{源系统表名}_di
- 全量数据:{project_name}.s{源系统表名}_df
- ODS ETL过程的临时表:{project_name}.tmp{临时表所在过程的输出表}{从0开始的序号}
- 按小时同步的增量表:{project_name}.s{源系统表名}_hi
- 按小时同步的全量表:{project_name}.s{源系统表名}_hf
- 字段命名规范:字段默认使用源系统的字段名
- 字段名与关键字冲突时,在源字段名后加上_col,即源字段名_col
- 同步任务命名规范:任务名建议和表名保持一致
4.2 DIM层的命名规范
公共维度表的命名规则:{project_name}.dim{/pub}{维度定义},其中的pub与具体业务无关,代表公共维度在各个业务系统都可以共用,例如时间维度可以命名为dim_pub_time。
4.3 DWD层的命名规范
通常需要遵照的命名规范为:dwd_{业务板块/pub}{数据域缩写}{业务过程缩写}[_{自定义表命名标签缩写}] _{单分区增量全量标识},pub表示包括多个业务板块的数据。单分区增量数据用i表示,全量数据用f表示。例如承包地库的承包地块事实表(全量)可以命名为:dwd_cbd _cbdk _df
4.4 DWS层的命名规范
公共汇总事实表命名规范:dws_{业务板块缩写/pub}{数据域缩写}{数据粒度缩写}[{自定义表命名标签缩写}]{统计时间周期范围缩写}。关于统计实际周期范围缩写,离线计算包括最近一天(_1d),最近N天(_nd)和历史截至当天(_td)三个表。对于小时表(无论是天刷新还是小时刷新),都用_hh 来表示。对于分钟表(无论是天刷新还是小时刷新),都用_mm来表示。
总结:数仓建设的规范性评估从以下几个角度去衡量: