个人笔记
SongPinru 的小仓库
数仓开发规范
前言
1.1 背景
为了避免底层业务变动对上层需求影响过大,屏蔽底层复杂的业务逻辑,尽可能简单、完整的在接口层呈现业务数据,建设高内聚松耦合的数据组织,使数据从业务角度可分割,显得尤为重要。从整个集团业务条线出发,形成数据仓库总体概念框架,并对整个系统所需要的功能模块进行划分,明确各模块技术细节,建设一套完整的开发规范。
1.2 目的
便于数据的统一管理和使用,达到见表识其义,且易于维护,制定此操作规范,此规范针对本部门开发人员,望共同遵守。
1.3 术语
ETL:也即是数据抽取、清理、装载,是数据仓库建设的核心一环。
ODS:操作数据存储ODS(Operational Data Store)是数据仓库体系结构中的一个重要部分,ODS具备数据仓库的部分特征和OLTP系统的部分特征,主要存储原始库表同步过来的数据以及接口上报采集过来的数据。
DW:数据仓库(Data Warehouse), 面向主题的、集成的、相对稳定的、随时间不断变(不同时间)的数据集合。
2 分层规范
统一拉通层:
把DW层的数据做统一的清洗处理。去重、去噪、字典翻译、空值转化,日期格式化等操作。
DWD(明细层):
和ODS粒度一致的明细数据,对数据进行去重,脏数据过滤和砍字段处理,空处理,保证数据质量,简单逻辑通过视图实现,并解决数据的完整度问题。
DWS(服务层):
轻度汇总数据及集市大宽表(按主题)存放数据。
DIM:( 维表层):
通过ods层获取得到。
APP:(应用层):
存放应用类表数据,如标签,各业务部门报表,第三方应用数据,按应用主题存放一般是业务部门,如销售、风控、运营、财务等。
3 表规范
3.1 命名
维表 命名形式:dim_描述 事实表 命名形式:fact_描述_[AB] 临时表 命名形式:tmp_ 正式表名_ [C自定义序号] 桥接表 命名形式:map_主题_描述_[AB] 宽表 命名形式:dws_主题_描述_[AB] 备份表 命名形式:正式表名_bak_yyyymmdd 表命名解释:
1)表名使用英文小写字母,单词之间用下划线分开,长度不超过40个字符,命名一般控制在小于等于6级。
2)其中ABC第一位”A”时间粒度:使用”c”代表当前数据,”h”代表小时数据,”d”代表天数据,”w”代表周数据,”m”代表月数据,”q”代表季度数据, “y”代表年数据。
3)其中ABC的第二位”B”表示对象属性,用”t”表示表,用”v”表示视图。
4)其中ABC的第三位”C”自定义序号用于标识多个临时表的跑数顺序。
5)目前主题缩写为:dev(设备)、user(用户)、log(日志)、book(记账)、bill(账单)、loan(贷款)、fin(理财)、card(卡片)、mkt(营销)。
6)桥接表主要用于一些多值维度,比如用户和设备(存在多对多关联)。
3.2 注释
注释要结合表的英文名,要求注释简洁明了,体现出表的业务出处、主题和用途。
3.3 表分区
在数仓中建立分区表统一用静态分区,一般建立分区表时,将ymd作为一级分区,在dws、dwd层可根据具体业务逻辑,确定使用一级分区,或多级分区。
3.4 存储格式
所谓的存储格式就是在Hive建表的时候指定的将表中的数据按照什么样子的存储方式,如果指定了方式,那么在向表中插入数据的时候,将会使用该方式向HDFS中添加相应的数据类型。在数仓中建表默认用的都是PARQUET存储格式,相关语句如下所示:
STORED AS INPUTFORMAT
‘org.apache.hadoop.hive.ql.io.parquet.MapredParquetInputFormat’
OUTPUTFORMAT
‘org.apache.hadoop.hive.ql.io.parquet.MapredParquetOutputFormat’
3.5 字符集
Hadoop和hive 都是用utf-8编码的,在建表时可能涉及到中文乱码问题,所以导入的文件的字符编码统一为utf-8格式。
3.6 约定
3.6.1 类型
(一) 所有的表都应该使用内部表
和ods场景不同,数仓数据来源于ods,统一使用内部表,location默认位置(无需额外指定)
(二) 分区表必须包含ymd字段
ymd在维表层便于识别数据更新日期,服务层便于查询跑批数据。
(三) 使用动态分区来插数据需要有相关设置
set hive.exec.dynamic.partition=true;
set hive.exec.dynamic.partition.mode=nonstrict;
在进行宽表数据初始化或者其它场景时,可能会涉及到使用动态分区的情况,此时应该对hive进行一些参数的设置。
(四) 会话级临时表
在当前会话期间存在,会话结束后自动销毁。
create TEMPORARY table tablename
会话级的临时表和temp库下的临时表使用场景不一样,temp库下的临时表主要用来放一些需要加工的中间数据,方便跑数时出现问题好回溯,而会话级的临时表一般存放一些简单但数据量大的中间结果,且一般不会被查询使用,用来节省存储空间。
3.6.2 空值
理论上在数仓落地的表不应该出现null未知类型,对于可能出现null的字段,如果为字符型统一为空字符串,如果是数值则给0。
4. 字段规范
4.1 命名
使用英文小写字母,单词之间用下划线分开,长度不超过30个字符,命名一般控制在小于等于4级; 和源数据bdl层表字段名一致,如为新增字段,尽量言简意赅; 英文名尽量专业,符合业界要求,不得使用汉语拼音; 尽量避免使用关键字。如无法避免,使用”`”转义; 指标字段能使用缩写的尽量使用统一的缩写,如申请金额统计apply_amt_sum,放款笔数loan_cnt,平均合同金额avg_contract_amt等,日后会建立一个词根库,用来规范一些缩写名称。
4.2 注释
注释本着简洁、详实、完整的原则,对于有业务含义的字段,在注释中需要枚举并解释其业务含义,如odl_loan_apidata_order_info.order_status 订单状态:3审核中,4申请被退回,41用户取消审核,5审核不通过,6审核通过;
4.3 类型
目前暂时不会涉及到map、array、struct等复杂的数据类型,日期时间等格式统一用string类型,字符串也是用string,数值的话,会根据字段定义来确定,对于有小数点要求的,比如某些金额、利率,需要用到decimal类型,无小数点要求的用浮点类型double和整数类型(int,bigint)。
5.代码规范
5.1 sql编码
1)关键字右对齐,代码注释详尽,查询字段时每行不超过三个字段,缩进时空四格等相关书写规范。
2)服务层依赖于ods层,应用层依赖于数仓层,原则上,不允许跨层查询。
3)相对独立的逻辑块间加空行。
4)如果SQL语句连接多表时,应使用表的别名来引用列。
5)WHERE条件中参数与参数值使用的类型应当匹配,避免进行隐式类型转化。
6)在SELECT语句中只获取实际需要的字段。
5.2 shell脚本
调度脚本主要是通过跑shell脚本,shell脚本的注意点:
1)命名与所跑的目标表名相同,注释要完善,后缀以.sh结尾。
2)脚本头需要加上分割线、作者、日期、数据更新策略、目的、描述等信息。
3)脚本在末尾要给出脚本运行状态,并且需要同步脚本运行状态到门户。
4)脚本里环境、配置等公用信息必须通过配置文件parameter_config。
6.数据管理
6.1 权限管控
因为底层表无法做到行级权限,考虑到后期数据维护和扩展性,不建议通过前端使用界面做数据权限管控,而是通过分表实现。以用户表为例,先处理子表,卡牛和随手记分别加工成对应的目标表,便于作业并行跑批,再union 到总表,并且给出数据来源的标识。
以划分后的项目为条线,创建不同的用户,实现表级权限管控。
6.2 调度配置
数据调度配置如下图所示,目前通过cron调度job:
Id name user_id description type cron is_enable
补充说明:作业配置的基本信息如上图所示,name需要和表名、脚本名字保持一致,描述为对应表的comment,sh_command为所跑的脚本命令,sh_dir为脚本部署的目录,timeout为超时时间,retries为重跑次数。
6.3 更新策略
数仓层目前主要有三种更新方式:标准增量、部分增量以及全量,具体选用哪种方式取决于业务的场景和数据的抽取方式。能用增量尽量不要使用全量
标准增量更新: 数据跑批时,根据ods层表的ymd取前一天增量数据用于更新dws层,相对效率最高;
部分增量更新: 数据跑批时,根据ods层表的ymd取前N天增量数据用于更新dws层;
全量更新: 由于业务场景问题,数据跑批时,根据ods层表必须取全量数据用于更新dws层和dwb层,效率最差;
以用户表为例,数据变化大,bdl层全表全量更新,所以对应的idl层用户数据维表,也只能做全量更新。
7.附录
7.1 主题域
主题域 | 主题缩写 | 涉及业务 |
---|---|---|
设备 | dev | **、渠道投放 |
用户 | user | 注册 |
日志 | log | 行为日志、埋点日志 |
记账 | book | 记账、账本、分类等 |
贷款 | loan | 进件、放款、还款 |
理财 | fin | 投资进件、入金、出金、存管 |
卡片 | card | 办卡,绑卡 |
营销 | mkt | 素材管理、推广计划 |
7.2 词根
词根表示例如下,更多词根表可以逐渐更新
属性/列名称 | 全称 | 简称 | 实例 | 说明 |
---|---|---|---|---|
金额 | amount | amt | contract_amt | 合同金额 |
次数 | count | cnt | apply_cnt | 申请笔数 |
平均值 | average | avg | avg_loan_amt | 平均放款金额 |
汇总 | summary | sum | contract_amt_sum | 合同金额汇总 |
最近/最后 | last | lst | lst_login_time | 最近登陆时间 |
首次/第一次 | first | fst | fst_login_time | 首次登陆时间 |
最大 | maximum | max | max_his_dpd | 历史最大逾期天数 |
最小 | minimum | min | min_user_age | 最小用户年龄 |