数据模型架构原则

数仓分层原则

分层目标

  • 清晰数据结构,每个层有自己的作业和职责
  • 减少重复开发,灵活高效应对业务需求
  • 复用中间结果,提升数据处理速度
  • 屏蔽原始数据的影响

    建议分层结构

  1. 数据源层:ODS(Operational Data Store)
    1. 把来源于其他系统的数据几乎无处理地存放在数据仓库中
    2. 数据同步:结构化数据增量或全量同步到数据计算平台
    3. 结构化:非结构化(日志)结构化处理并存储到数据计算平台
  2. 数据明细层:DWD(Data Warehouse Detail)
    1. 一般保持和 ODS 层一样的数据粒度,并且提供一定的数据质量保证
    2. DWD 层要做的就是将数据清理、整合、规范化、脏数据、垃圾数据、规范不一致的、状态定义不一致的、命名不规范的数据都会被处理
    3. 为了提高数据明细层的易用性,该层会采用一些维度退化手法,将维度退化至事实表中,减少事实表和维表的关联
  3. 数据服务层:DWS(Data WareHouse Servce)
    1. 会进行轻度汇总,粒度比明细数据稍粗
    2. 整合汇总成分析某一个主题的服务数据,一般是宽表
    3. DWS 层应覆盖 80% 的应用场景。又称数据集市
  4. 数据应用层:APP(Application)
    1. 主要是提供给数据产品和数据分析使用的数据
    2. 一般会存放在 ES、 PostgreSql、Redis 等系统中供线上系统使用,也可能会存在 Hive 或者 Druid 中供数据分析和数据挖掘使用
  5. 维表层:DIM(Dimension)
    1. 高基数维度数据:一般是用户资料表、商品资料表类似的资料表。数据量可能是千万级或者上亿级别。
    2. 低基数维度数据:一般是配置表,比如枚举值对应的中文含义,或者日期维表。数据量可能是个位数或者几千几万。

      主题域划分原则

  • 按照业务划分,就是指的功能模块/业务线
  • 按照业务过程划分,业务过程指企业的业务活动事件,如下单、支付、退款都是业务过程。不过需要注意的是,一个业务过程是一个不可拆分的行为事件,通俗的讲,业务过程就是企业活动中的事件

    数据模型设计原则

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

  • 核心模型和扩展模型要分离:建立核心模型与扩展模型体系,核心模型包括的字段支持常用的核心业务,扩展模型包括的字段支持个性化或少量应用的需要,不能让扩展模型的字段过度侵入核心模型,以免破坏核心模型的架构简洁性与可维护性。
  • 公共处理逻辑下沉及单一:越是底层公用的处理逻辑越应该在数据调度依赖的底层进行封装与实现,不要让公用的处理逻辑暴露给应用实现,不要让公共逻辑多处同时存在。
  • 成本与性能平衡:适当的数据冗余可换取查询和刷新性能,不宜过度冗余与数据复制。
  • 数据可回滚:处理逻辑不变,在不同时间多次运行数据结果确定不变。

    数仓公共开发规范

    层次调用规范

  • DWS 和 APP 中禁止直接使用 ODS 的表, ODS 的表只能被 DWD 引用

  • 禁止出现反向依赖,例如 DWD 的表依赖 DWS 的表
  • DWD 可以被 DWS 和 ADS 调用
  • DWS 只能被 ADS 调用

    数据类型规范

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

  • 金额:double 或 使用 decimal(28,6) 控制精度等,明确单位是分还是元

  • 字符串:string
  • id类:bigint
  • 时间:string
  • 状态:string

    指标口径规范

    通过数据分层,提供统一的数据出口,统一对外输出的数据口径,保证主题域内,指标口径一致,无歧义。
    1) 指标梳理
    我们将需求梳理到的所有指标进行进一步梳理,明确其口径,如果存在两个指标名称相同,但口径不一致,先判断是否是进行合并,如需要同时存在,那么在命名上必须能够区分开。

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

  • 原子指标:原子指标是对具体业务过程的度量或对具体维度/属性的计数,具有明确的业务含义且在逻辑层面不可再拆分。
    • 需要维护指标的名称、函数、注释等
  • 修饰词:修饰词是对原子指标进行修饰限定的词汇,对应着明确的业务场景和业务规则,用于圈定原子指标业务统计的范围。
  • 派生指标:派生指标是原子指标与一些维度或者修饰词的组合。

    数据表处理规范

  • 增量表

    • 新增数据,增量数据是上次导出之后的新数据。
    • 记录每次增加的量,而不是总量;
    • 增量表,只报变化量,无变化不用报;
    • 每天一个分区。
  • 全量表
    • 每天的所有的最新状态的数据。
    • 全量表,有无变化,都要报;
    • 每次上报的数据都是所有的数据(变化的 + 没有变化的)
    • 只有一个分区。
  • 快照表
    • 按日分区,记录截止数据日期的全量数据。
    • 快照表,有无变化,都要报;
    • 每次上报的数据都是所有的数据(变化的 + 没有变化的);
    • 一天一个分区。
  • 拉链表

    • 记录截止数据日期的全量数据。
    • 记录一个事物从开始,一直到当前状态的所有变化的信息;
    • 拉链表每次上报的都是历史记录的最终状态,是记录在当前时刻的历史总量;
    • 当前记录存的是当前时间之前的所有历史记录的最后变化量(总量);
    • 只有一个分区。

      数仓各层开发设计规范

      ODS层设计规范

  • 一个系统源表只允许同步一次;

  • 全量初始化同步和增量同步处理逻辑要清晰;
  • 以统计日期和时间进行分区存储;
  • 目标表字段在源表不存在时要自动填充处理。
  • 不可再生的永久保存
  • 对历史变化进行保留
  • ods的etl过程中的临时表, 建议用完即删,下次使用再生成
  • 对枚举类型字段,进行枚举值变化和分布监控
  • ods表数据量级和记录数做环比监控
  • ods全表都必须要有注释

    DIM公共维度层设计规范

  • 公共维度在不同的物理表中的字段名称、数据类型、数据内容必须保持一致

  • 针对重要性,业务相关性、源、使用频率等可分为核心表、扩展表
  • 将维度与关联性强的字段进行组合,一起查询,一起展示,两个维度必须具有天然的关系,如:商品的基本属性和所属品牌。

    DWD明细层设计规范

  • 选用事件的发生日期或时间作为分区字段,便于扫描和裁剪

  • 明细层事实表维度退化,减少后续使用join成本

    DWS公共汇总层设计规范

  • 区分统计周期。在表的命名上要能说明数据的统计周期

  • 任务支持多次重跑而输出不变,不能有 insert into 语句,要有 overwrite
  • 表数据存储格式采用parquet的格式
  • 表采用snappy压缩

    数仓命名规范

    词根设计规范

    词根:可以用来统一表名、字段名、主题域名等等,把可能会多次用到的短语,集中命名,保证全局范围内的命名含义一致性

  • 比如:一部分业务是关于交易的,英文名是:trade, trade 就是一个词根,那就在所有的表、字段等用到的地方都叫 trade。这就是词根的作用,用来统一命名,表达同一个含义。指标体系中有很多“率”的指标,都可以拆解成 XXX+率,率可以叫 rate,那我们所有的指标都叫做 XXX+rate。

  • 普通词根:描述事物的最小单元体,如:交易-trade。
  • 专有词根:具备约定成俗或行业专属的描述体,如:美元-USD。

    表命名规范

  • 数仓层次前缀

    • 公用维度:dim
    • ODS层:ods
    • DWD层:dwd
    • DWS层:dws
    • ADS层:ads
  • 表类型
    • 全量: _full
    • 增量: _delta
    • 快照: _snap
    • 拉链: _zipper
  • 表命名规范:

    • ODS:ods[业务库名]{业务库原始表名}[_delta]
    • DWD:dwd{主题缩写}{业务过程缩写}[自定义标签缩写]{单分区增量全量标识}
    • DWS:dws{数据域缩写}[自定义标签缩写]_{刷新周期标识}
    • ADS:ads [业务应用缩写][维度][自定义标签缩写]_{刷新周期标识}
    • DIM:dim_{维度定义}

      指标命名规范

      公共规则

  • 所有单词小写

  • 单词之间下划线分割(反例:appName 或 AppName)
  • 可读性优于长度 (词根,命名一致性)
  • 禁止使用 sql 关键字,如字段名与关键字冲突时 + col
  • 数量字段后缀 _cnt 等标识…
  • 金额字段后缀 _price 标识
  • 天分区使用字段 dt,格式统一(yyyy-mm-dd)
  • 小时分区使用字段 hh,范围(00-23)
  • 分钟分区使用字段 mi,范围(00-59)
  • 布尔类型标识:is_{业务},不允许出现空值

    指标命名规范

    结合指标的特性以及词根管理规范,将指标进行结构化处理。

  • 原子指标命名规范可由业务修饰词 + 词根组成

  • image.png
  • 衍生指标:对原子指标业务统计范围的确定。由一个原子指标+修饰词+时间周期组成
  • image.png

    修饰词的规范

    为了规范指标的命名,我们可以对词根、时间周期等修饰词进行约定,比如:
    常用的【词根】可以做如下约定:
词根 命名规范 类型 说明
次数/数量 cnt bigint

| | 金额 | amt | Decimal |

| | 首次 | fst |

| 类型根据具体度量确定 | | 末次 | lst |

| 类型根据具体度量确定 | | 平均 | avg |

| 类型根据具体度量确定 | | 比率 | rate | Decimal |

| | 时间戳 | timestamp | bigint |

| | 时间 | time | string | yyyy-MM-dd HH:mm:ss | | 日期 | date | string | yyyy-MM-dd | | 加密 | encry | string |

| | 描述 | desc | string |

| | 人民币 | RMB | Decimal |

| | 美元 | USD | Decimal |

| | 前N | topN |

| 类型根据具体度量确定 | | 升序 | asc |

| 类型根据具体度量确定 | | 降序 | desc |

| 类型根据具体度量确定 | | 时长 | duration | Decimal |

|

常用的【时间周期】可以做如下约定:

时间周期 简称 说明
最近1天 _1d d:day
最近3天 _3d
最近N天 _Nd
最近7天 _1w w:week
最近14天 _2w
最近30天 _1m m:30天
b:before
y:year
最近60天 _2m
最近90天 _3m
最近180天 _6m
最近一年 _1y
180天以前 _b6m
未来7天 _p1w p:predict;w:week
未来4周 _p1m p:predict;m:month
历史截至当日 _std std:start to day
最近1小时 _1h h:hour
0点截至当前小时 _dth day to hour

公共字段规范

字段描述 缩写 字段类型
年龄 age string
性别 gender string
城市 city string
省份 province string
国家 country string
用户id user_id string
出生日期 birth_date string
地址 addr string
邮箱 email string
昵称 nick_name string
设备id dev_id string
操作系统 os string
操作系统版本 os_version string
app版本 app_version string