数据治理4-企业数仓开发标准与规范
数据标准是数仓一致性建设的基础:事实一致性和维度一致性
一、数仓开发流程规范SOP
二、企业数仓架构|层级规范与治理实践
1. 数仓基础知识回顾
- ODS 层:Operational Data Store,原始数据层,又叫贴源层。一般以增量或者全量方式,以分区方式维护历史数据的长期保存,并遵从数据安全规范标准,针对未加密或者漏加密数据完成物理层的二次加密。ODS层一般由基建团队统一负责数据的接入,采用增量/全量的数据同步方式,保障数据不丢不重地高效接入,核心数据确保1点前产出
- DWD 层:Data Warehouse Detail,明细数据层,与ODS层粒度一致,对数据进行清洗、转换、补全等操作,保障数据质量。DWD层基于数据域划分,抽象核心业务过程,采用事务事实表(增量)和累积快照表(全量)的方式,建设数据域内高内聚数据域之间低耦合的稳定易用的明细层,核心表确保在3点前产出
- DWS 层:Data Warehouse Summary,汇总数据层。基于 DWD 层明细事实数据及维度模型数据,完成轻度汇总主题数据及主题宽表数据。遵循数据域-业务过程-原子指标-衍生指标-复合指标的建设规范,从各类数据应用场景中梳理并拆解指标体系,并以数据域+粒度的视角整体建设DWM层,核心表确保在4点前产出
- DM 层:数据集市层,集市层一般按照业务主题构建主题数据、一般为高度聚合或者高度汇总数据。
- DIM层:实体基于数据域划分,抽象出具有公共属性的业务,采用主表和扩展表的设计方式,建设一致性维度,兼顾易用性的同时重点保障数据一致性和产出时效,核心DIM层表确保在2点前产出
2. 某企业真实的数仓分层架构
-
复制层(SSA,system-of-records-staging-area,对标ODS)SSA 直接复制源系统(比如,从mysql中读取所有数据导入到hive中的同结构表中,不做处理)的数据,尽量保持业务数据的原貌;与源系统数据唯一不同的是,SSA 中的数据在源系统数据的基础上加入了时间戳的信息,形成了多个版本的历史数据信息。SSA的数据主要是为了对源数据在hive中进行原样备份,供多个部门在SOR层进行数据ETL.
-
原子层(SOR,system-of-record,对表dwd):SOR 是基于模型开发的一套符合 3NF 范式规则的表结构,它存储了数据仓库内最细层次的数据,并按照不同的主题域对数据分类存储;比如高校数据统计服务平台根据目前部分需求将全校数据在 SOR 层中按人事、学生、教学、科研四大主题存储;SOR 是整个数据仓库的核心和基础,在设计过程中应具有足够的灵活性,以能应对添加更多的数据源、支持更多的分析需求,同时能够支持进一步的升级和更新.
-
汇总层(SMA,summary-area,也有叫DPA层,对标dws):SMA 是 SOR和DM(集市层) 的中间过渡,由于 SOR 是高度规范化数据,此要完成一个查询需要大量的关联工作,同时DM 中的数据粒度往往要比 SOR 高很多,对要生DM 中的汇总数据需要进行大量的汇总工作,此,SMA 根据需求把 SOR 数据进行适度的反范(例如,设计宽表结构将人员信息、干部信息等多表的数据合并起来)和汇总(例如,一些常用的头汇总、机构汇总等);从而提高数据仓库查询性能。
-
集市层/展现层(DM, data mart对标ADS):DM 保存的数据供用户直接访问的;可以将 DM 理解成最终用户接最终想要看的数据;DM 主要是各类粒度的事数据,通过提供不同粒度的数据,适应不同的数访问需求;
3. 通用的数仓分层与架构(重要)
3.1. 企业数仓层级规范:
-
禁止逆向调用
-
避免同层调用
-
优先使用公共层
-
避免跨层调用
-
稳定业务按照标准的数据流向进行开发,即ODS → DWD → DWB → DWS → ADS
-
非稳定业务或探索性需求可以遵循ODS → DWD → ADS 或者 ODS → DWD → DWB → ADS 两个模型数据流
3.1.1. 数仓为啥禁止逆向调用,跨层调用等?
主要目的是为了维护数据仓库的结构和层次性,确保数据流的正确性和可维护性。
-
数据流的一致性:逆向层级调用可能导致数据流的混乱和不一致。在一个层级中,数据应该是单向流动的,从下层流向上层。逆向层级调用会导致数据的逆向流动,可能导致数据重复处理、冗余计算和不一致的结果。比如DWS层级的任务依赖ADS的任务,ADS直接修改了数据,,会造成DWS层的数据也被修改,如果DWS的任务也可能被其他任务调用,这可能导致数据不一致。禁止逆向层级调用可以降低这种风险,确保数据在每个层级上的一致性。
-
数据隔离和解耦:禁止逆向层级调用有助于实现数据的隔离和解耦。每个层级应该具有独立的功能和目的,通过禁止逆向层级调用,可以确保每个层级的数据流是单向的,避免层级间的数据交织和混淆。禁止逆向层级调用可以保持数据仓库的结构清晰,使每个层级的任务和功能保持一致。
-
提高代码可维护性:逆向层级调用会增加代码的复杂性和难以维护性。当任务可以逆向调用其他层级的任务时,代码的调用关系变得复杂,难以理解和调试。通过禁止逆向层级调用,可以简化代码的调用关系,提高代码的可维护性。
-
数据仓库的可扩展性和灵活性:禁止逆向层级调用可以提高数据仓库的可扩展性和灵活性。如果允许逆向层级调用,当数据仓库需要进行扩展或调整时,可能需要修改和调整大量的任务和调用关系(比如数仓升级迁移任务等,痛点)。通过禁止逆向层级调用,可以减少对任务的修改和调整,使数据仓库更易于扩展和灵活应对变化。
3.2. 企业各业务线层级规范:
-
所有原始数据进入ODS,就按照业务与进行拆分库。
-
所有业务线(事业部),每条业务线一个生产库,一个测试库,整条流程自行把控。
-
对应开发和leader负责该业务线的全部建设(如有数据质量问题,自行负责)。
-
跨业务线数据调取,直接找对应业务线开发和leader即可。
4. 数仓架构与层级规范相关治理实践
4.1. 数仓可能存在哪些问题?(重要)
-
跨层调用:数仓不规范或者早起建设时,数仓开发结果导向型,跨层调用库表,比如DM层直接从ods层取数加工处理,这种叫法也叫层级穿透。
-
逆向调用:比如数仓公共层依赖业务线数据,DWS层依赖业务线DM层数据,任务逆向依赖配置
-
尽量避免大量同层调用:数仓因为公共层规划的不够好,造成大量同层调用。
4.2. 如何排查这些问题?(重要)
排查数仓中的跨层调用任务需要结合多种方法和工具,包括日志分析、数据血缘分析、元数据管理、代码管理等。通过综合运用这些方法,可以更全面地了解任务之间的依赖关系,并发现和解决跨层调用的问题。在数仓中排查出跨层调用的任务,通常可以按照以下步骤进行:
-
确定任务依赖关系:首先,了解数仓中各个任务之间的依赖关系。根据任务调度工具(如Airflow、Oozie,DS等)或任务管理平台的日志,查找任务的调度情况和依赖关系,确定哪些任务是跨层调用的。
-
任务依赖图:绘制任务依赖图可以帮助你更直观地了解任务之间的依赖关系。将任务以节点的形式表示,通过有向边连接它们之间的依赖关系。通过分析任务依赖图,可以找到跨层调用的任务。
-
数据血缘分析:进行数据血缘分析可以帮助你追踪数据在数仓中的流动路径,从而确定任务之间的调用关系。通过分析数据血缘关系,可以找到跨层调用的任务。
-
元数据管理工具:使用元数据管理工具可以记录和管理数仓中的元数据信息,包括任务的调用关系。通过查询元数据,可以获取任务之间的依赖关系和调用路径,进而确定跨层调用的任务。
-
检查任务代码:检查任务的代码,特别是任务之间的调用逻辑。查看任务代码中的函数调用、API调用等,确定是否存在跨层调用的情况。
-
数据流跟踪:在数仓中,数据流通常是按层次结构组织的,可以通过跟踪数据流来确定是否存在跨层调用的任务。观察数据的输入输出路径,找出是否有任务直接或间接地跨越了不同层次。
-
代码审查和代码版本管理:定期进行代码审查,特别关注任务之间的调用逻辑。同时,使用代码版本管理工具可以帮助你追踪任务代码的变更历史,找到跨层调用的任务。
4.3. 如何治理这些问题?(重要)
-
跨层调用的解决方案
解决ODS穿透问题:找出跨层引用ODS层数据的应用层报表,直接切换对应的CDM层模型,或者重新构建相应的CDM层,并在上线新的DWD/DWS数据表后完成引用切换 -
逆向调用的解决方案
直接建立对应层级的模型表,比如DWD,DWB层等,斩断调用,切换到新的模型。 -
同层调用的解决方案
严格按照数仓层级设计,尽量避免同级调用;注意禁止同层调用并不意味着完全隔离各个层次的任务。在某些特定情况下,同层调用可能是必要的,例如某个任务需要获取同一层次其他任务的计算结果。但是,这样的情况应该尽量避免,以保持数仓的整体结构清晰和简洁。
三、企业数仓模型命名与标准规范
数据模型的标准化治理主要从4个方面
- 数据模型规范化:
要考虑数据模型的设计是否符合模型设计的规范(如第三范式等)。应从业务需求、应用范围、数据结构、实体属性设计、实体关系设计等方面来进行规范化评价,例如主键是否唯一,索引是否重复,主外键关联是否合理等。 - 数据模型标准性
要考虑数据模型是否遵循统一的命名规则,包括包名称、数据表名称、属性名称等。统一的命名规则能够规范模型,避免名称不一致造成的概念混淆,省去内容标准程度、完整性等方面的确认。 - 数据模型一致性
要考虑数据模型中的元数据和数据是否一致;数据模型中的实体、属性含义等是否定义清晰、完整、准确;数据模型中的术语、标准、用法、属性和业务规则是否与实际情况保持一致,例如数据名称、数据属性、业务规则、属性格式及规则、外键与主键是否与实际情况保持一致。 - 数据模型可读性
要考虑数据模型是否方便查阅,布局是否合理,是否方便浏览查阅。模型方面确保大而复杂的模型被分成多个子模型,模型中不包含过多层级的继承关系。实体方面包括合理的颜色及布局、关键实体的重点标注等。属性方面涉及名称和归类。
3.1. 数仓库的命名及使用
按数仓分层架构设计,共有ods、dwd、dws、dm层及dim维表管理模块组成,库的规范化使用,遵循如下规范:
-
数仓ods贴源层,库名ods_{xx}, xx表示源系统缩写。
-
数仓dwd层,不同数据领域使用不同的dwd库管理对应的表,库名定义为dwd_{xx},xx表示业务域简称缩写。
-
数仓dws层,不同数据领域使用不同的dws库管理对应的表,库名定义为dws_{xx},xx表示业务域简称缩写。
-
数仓dim维度管理,不同数据领域使用统一的dim库管理维表,数据库使用dim库。
-
数仓dm层,根据各数据领域需求为每个业务线创建单独集市层数据库,库名定义为dm_{xx},xx表示业务域简称缩写。
3.2. 数仓表的命名规范
-
基本准则
采用英文字母(小写)、数字、下划线’_'组成,不以数字或者下划线开头,表名禁止使用数据库关键字命名,如:select、insert、table、time、password等;
表必须填写描述信息,如表的描述、字段描述等,每层表名的命名遵循如下规则:
-
表命名组成的元素
表命名记录元信息,让用户快速找表、理解数据。事实表名称:由层级(dwd/dws)、数据域/主题域、业务内容(业务过程描述)、表类型、分区策略组成;
维表名称:由层级(dim)、维度内容、表类型(拉链表或快照表)、分区策略组成。
数据域/主题域缩写规则分为:分为继承类缩写和专业名词缩写类两类,-
继承类缩写沿用公司内通用的缩写名词使用,如:运单 waybill ;
-
专业名词类缩写要结合数据域/主题域的英文,长度<=5取全称,长度>5取单词的核心字母作为缩写简称。另外针对不同业务域存在名称相同的数据域/主题域,需加字母区分,超出如下表格内容上架构组决议。
-
3.3. 数据域、主题域、分区策略、表类型等标准规范
公司内部维护的
3.4. 数仓各层级表的命名规范
-
ods表命名规范
表的命名规则:{源系统表名}举例: ods_cx.complain
-
dwd表命名规范
表的命名规则:{层级}{数据域英文缩写名}{业务内容}_{分区类型}举例:dwd.dwd_pd_waybill_info_di 收派运单信息表
-
dws表命名规范
表的命名规则:{层级}{主题域英文缩写名}{业务内容}[时间粒度]{分区类型}举例: dws.dws_pd_emp_eff_7d_di 收派效能汇总表
-
dim维表命名规范
表的命名规则:{层级}{维度内容}{分区类型}_{表类型}(快照/拉链)注:拉链英文缩写chain,快照类型表名可省略表类型
举例:dim.dim_prod_info_df 产品维表、dim.dim_prod_info_df_chain 产品维度拉链表
-
tmp临时表命名规范
表的命名规则:{目标表名}_tmp{数字编码}举例:tmp_dwd.dwd_pd_waybill_info_di_tmp01
-
中间表的命名规范
表的命名规则:{目标表名}{表类型}{数字编码}举例: dwd.dwd_pd_waybill_info_di_mid01 收派运单中间表01
3.5. 数仓表的字段名称规范
中大厂一般都有自己的词根和编码库,平台化给大大家查询的,在建模的时候查询使用
四、企业数仓模型设计方法论与规范
4.1. ODS层模型开发规范
4.1.1. ODS层模型设计规范
ODS 层,最接近源数据的一层,考虑数据溯源问题,不建议做过多的数据清洗工作,原封不动地接入原始数据即可,对于数据去噪、去重、异常值等处理建议放在 DWD 层来做。
- ODS层不管是增量数据还是全量数据必须按日期分区(pt[yyyyMMdd]) 。
- ODS层尽量与业务库表保持表结构的统一,不做数据整合和JOIN处理 。
- 必要的数据清洗及转换放在ODS层处理,如脏数据的处理、日期的转换、空值处理,不要将这些清洗转换的逻辑放到DWD层处理 。
- 如果有unix格式的时间字段, 将Unix时间格式化为”yyyy-MM-dd HH:mm:ss”形式, 字段类型为string类型.如果有毫秒值得在后面拼接毫秒值.。
- 分区字段使用pt 命名,内容格式为 yyyyMMdd
某企业ods层建设参考
4.1.2. ODS层数仓开发实践分享
业务背景:某企业收入结算数据涉及21个源系统,共计48张表,其中27张表来自oracle库,21张表来自mysql 。为确保下游数据应用准确性和及时性,依据收入数据特点(每天新增结算运单及红冲历史数据),ODS不对历史记录直接做更新,采用增量模式抽数,每日须在1点50分之前完成。在大数据平台,申请离线数据接入,按要求填写接入数据源、表字段映射、运行参数即可。例如:同城结算收入申请接入,如下图
4.1.3. 离线数据接入核心四个步骤
第一步:确定抽数任务启动时间和参数设置
确定表的抽数任务启动时间,基于表量级完成datax参数设置,如总作业速率、单个channel作业率、源业务系统无数据启动报警、调度节点等;
例如:表 ods_cls.etl_order_day //ods命名规则:{层级}{源系统简称}{源系统表名}
任务启动时间 :1:45
日增数据量 : 600W
总作业速率 : 30 MB/S
单个channel作业率 : 10 MB/S
调度节点 : BDP_ETL
第二步:确定抽数任务同步方式
确定表抽数任务同步方式 (小时增量、日增量、日全量等),确定源表抽数条件,根据源表业务时间确定ods表分区字段;
例如:表 ods_cls.etl_order_day //ods命名规则:{层级}{源系统简称}{源系统表名}
同步方式 :日增量
抽数条件 : (inc_day >=‘[time(yyyy−MM−dd,−1d)]′andincday<′[time(yyyy-MM-dd,-1d)]' and inc_day <'[time(yyyy−MM−dd,−1d)]′andincday<′[time(yyyy-MM-dd)]’)
分区字段 : 根据抽数条件设置分区 inc_day=$[time(yyyyMMdd,-1d)] //日分区:inc_day
第三步:确定数据抽取逻辑
字段类型格式转换,对源表字段进行清洗,如将(varchar2、date)转换成string类型,将number类型转换成double
例如:表 ods_cls.etl_order_day //ods命名规则:{层级}{源系统简称}{源系统表名}
将源端 mysql_cls_tc_etl.tt_ order_day中的字段product_code varchar >> hive端 ods_cls.etl_order_day product_code string 产品代码;
将源端 mysql_cls_tc_etl.tt_ order_day中的字段sending_tm date >> hive端 ods_cls.etl_order_day sending_tm string 签收日期;
确定源表需要加密的字段,对相应的字段进行加密,如手机号、证件号、地址等信息,例如:表 ods_cls.etl_order_day //ods命名规则:{层级}{源系统简称}{源系统表名}
使用udf函数对字段shop_phone加密 : phone_encrypt_pro(shop_phone)
第四步:告警及数据质量监控
对抽数任务设置任务报错及超时告警;
例如:表 ods_cls.etl_order_day //ods命名规则:{层级}{源系统简称}{源系统表名}
失败告警:任务启动或运行中报错,以电话、丰声、短信等形式触发告警。
任务超时告警:任务达到设定时间还没有结束,以电话、丰声、短信等形式触发告警。
4.2. DWD层建模与设计规范
4.2.1. DWD层模型设计方法论
DWD层模型设计有3种,概念模型,逻辑模型和物理模型。
步骤一:梳理核心业务环节及核心数据实体
识别该业务线/业务板块的核心业务运营环节,梳理各业务环节下核心数据实体,指导数据域分类,例如:顺丰速运业务的核心业务环节和数据实体包括:
- 产品设计及营销: 产品规划及设计-> 客户拓展 -> 客户签约-> 客户下单。相关核心数据实体:产品、客户、合同、订单等
- 营运:路由规划 -> 揽收 -> 中转-> 运输-> 派送 -> 指挥调度。相关核心数据实体:小哥、网点、运单、车辆、飞机、驾驶人员、中转场等
- 售后: 客诉->定责→理赔。相关核心数据实体:客诉单、理赔单等
- 后台支持: 财务,人资,采购及综合。相关核心数据实体:账单、人员、组织、供应商等
步骤二:数据域分类及架构设计
根据识别出的核心数据实体,结合其归属业务部门、跨部门共用性等,明确数据域的分类及架构。数据域核心分类/构建逻辑为:
- 在每个业务环节下识别数据实体(数据生产或者数据承载实体), 如:在“产品规划”环节识别出三个数据实体: 产品、客户、合同
- 相对个性化的数据,按数据生产部门(通常是业务部门)单独成为一个数据域,比如: 收派域
- 相对公用的数据,单独成为一个数据域,如运单域、托寄物域
- 实体与数据域的匹配原则: 以”核心实体”所在的数据域为第一优先归属,如果都是”辅助实体”,遵循”实例触发关系就近原则”
步骤三:单数据域下逻辑ER图构建
根据不同数据域的内容、实体、关联关系、事件,构建各域下的逻辑ER图(参考 ER图绘制规范)。收派域逻辑ER图示例如下:(仅供参考)
- 明确单域下的所有实体,包含:收派员、运单、网点、aoi、物资、线下渠道、仓管等
- 明确各实体之间的关系,关系一般分为归属型关系和动作型关系。如:收派员归属网点管理,“归属”就是收派员和网点之间的关系;收派员收派运单,“收派”就是收派员和运单之间的关系
- 明确各实体的相关属性,如:收派员的属性,岗位、职级、组织归属、学历、电话等
步骤四:物理模型设计
物理模型包括实体相关的物理表(一个实体可能关联多张表)、主键、外键、字段、表的关联关系等,DWD层收派域物理模型示例:(仅供参考)
4.2.2. DWD层模式设计
第一步:梳理业务域相关的实体
如运单域:核心实体运单、引用关联实体产品、网点、客户、渠道、托寄物等实体。
确定数据域相关实体关系,如下图
第二步:dwd层数据域物理维度建模过程
-
确定业务过程
业务过程即业务活动中所有的事件,通常为不可拆分的事件。确认业务过程,是为了从顶层视角,规范业务中的事务内容的类型及唯一性。例如: 以顺丰券基表为例,它描述了全网顺丰券的发放及使用情况,以及客户是通过哪些渠道获得并且消费的。
-
确定粒度
定义业务流程中的数据粒度。例如:以运单基表为例,它的粒度为运单号
例如: 以顺丰券基表为例,它的粒度为虚拟券号
-
确定维度
确定用于事实表表行的维度。例如: 以运单基表为例,以揽收员工号、揽收网点编码、派送员工号、派送网点编码、运费月结卡号、产品代码、派送aoi_id等维度。
例如: 以顺丰券基表为例,它的维度为网点、会员、员工工号等。
-
确定事实
确定用于形成每个事实表的数字型事实。例如: 以运单基表为例,运单号、寄件时间、签收时间、寄件电话、收件电话、运费、总费用、保价费、声明价值、体积、总长、总宽、总高等。
例如:以顺丰券基表为例,事实为券号、券使用状态、券使用时间、抵扣金额等。
-
冗余字段
冗余相关的维度属性字段,已满足使用的扩展性例如:运单基础模型中关于产品维度信息,扩展产品板块、产品系列方便多场景的分析使用。
-
输出事实维度关系图
完成上述步骤内容后,即可输出事实维度关系图。
第三步:最后的模型文档提交,代码文档提交归档等
4.3. DWS层建模与设计规范
4.3.1. DWS层建模方法论
步骤一:识别关键业务场景并明确主题域
DWS各主题域是面向各业务分析场景的整合数据,为DM层提供公共汇总数据,并提高全链路计算效率,减少Job运行时间
主题域构建核心逻辑:
- 基于核心业务环节,识别关键业务分析场景
- 相对独立分析的细分场景单独成为一个主题域
- 需要经常关联分析的细分场景合并成为一个主题域
主题域分类示例:(仅供参考)
步骤二:单主题域下梳理商业分析逻辑并明确数据实体
明确各主题域下核心数据实体
针对每个业务分析场景,梳理商业分析主要逻辑,明确分析的核心实体以及其他关联实体。
步骤三:单主题域下构建逻辑ER图
根据不同主题域的内容、实体、关联关系、事件,构建各域下的逻辑ER图,终端主题域逻辑模型示例如下:
步骤四:物理模型设计
物理模型包括实体相关的物理表(一个实体可能关联多张表)、主键、外键、字段、表的关联关系等,DWS层终端主题域物理模型示例:(仅供参考)
明确DWS主题域与DWD数据域关联关系
- 主题域:面向业务分析和业务运营的数据集合,一般会有多个核心管理和检测视角,需要关联多个数据域。
- 数据域:业务流程中的各环节收集的明细数据集合(通过某种联系或者ID拉通聚合,形成描述某个业务流程(或者实体,或者以实体和关系连接事实事件)的数据集合。
DWS主题域与DWD数据域关联关系示例(仅供参考):
4.3.2. DWS层模型设计规范
第一步:dws主题域逻辑模型建模过程
- 梳理事实表、维度、指标关系
如客户逾期事实表、可关联信息包含月结客户维度、人员维度、财务组织维度、财务科目维度,指标包含逾期金额、逾期天数、逾期占应收比。 - 确定数据域相关实体关系
第二步:dws主题域物理模型建模过程
物理模型一般采用维度建模,模型上以星型模型为主。
-
确认dws层模型所对应的维度和度量信息
例如: 以各时点派件环节监控指标表为例,它通过班次日期、计算时点、班次、产品类型、流向类型这5个维度,统计已出仓票数、已派送票数、2h派送票数等度量指标。 -
确定度量所进行的衍生计算方式
如:sum、count、avg等 例如: 以各时点派件环节监控指标表为例,度量指标的计算方式为count -
确定数据的刷新频率
例如:以各时点派件环节监控指标表为例,每小时刷新当天数据 -
输出物理模型关系
第三步:dws层模型开发交付文档
最后模型开发文档提交,代码文档提交归档等
4.4. DM/ADS层数仓建模规范
数据集市管理公司范围内各个业务领域不同数据应用场景的数据,场景中会以分析主题的方式建立相关的明细表、汇总表及应用类数据表,这些场景的数据会从数仓dwd层或者dws层获取数据。
数据集市的数据应用有多种形式:报表、指标、数据分析、数据挖掘等。模型表的建模规范一般会在数据集市内部采用小三层的设计原则。
4.4.1. 明细层数据的构建
明细层数据的构建,一般会基于dwd层的明细数据完成分析主题数据的构建。如:
派件异常明细分析表:
4.4.2. 汇总层数据的构建
4.4.3. 应用层数据的构建
应用层的表设计更多依赖业务的需求或者展示形式,灵活性比较高,设计规范不做强制要求。
4.5. DIM层维度层建模规范
4.5.1. DIM层模型设计规范
-
维度表主要分为两类:通用维表和专业维表。通用维表指全网共用的维表,应用于多个业务域的数据分析;专业维表指维度内容上比较独立,一般仅在某个业务领域单独使用的维表。
-
通用维的特征(重要)
- 基于统一的规范来建全网共同需要用的维表 。
- 维表的优化/修改需要多方共识 。
- 可以由多团队建设(负责方可以是不同的团队)。
-
专业维的特征
不同团队基于统一的规范建设并负责管理。
4.5.2. 维度设计原则
维表的组成一般包含维度主键和维度属性,基于公司各业务线的管理和使用上可分为通用维表和专有维表两类。结合使用和存储特性可分为快照型、拉链型。
在终端业务场景下指标中,收派件量的统计会根据网点的维度统计,客诉量的统计也会根据网点统计,如果统计网点维度包含内容不⼀致(如:选择了不同的网点维表),最终会导致⼀些地区没办法精准分析,所以构建维度的核心就是统一维度。
维度统⼀核心在维表如何设计,一般遵循以下原则:
- 维度属性存在通用维度属性和专业维度属性,建议拆成两个维表,如:月结客户维表和月结客户黑名单维表。
- 产出时间相差较⼤的维度属性拆分单独的维表,⽐如有些维度属性产出时间在凌晨2点,有些维度属性产出时间在凌晨6点,那2点和6点的就可以拆成两个维表,确保核⼼维表尽早产出。如:供应商维表,可拆分成供应商(采购)维表和供应商(供应链)维表。
- 出于维表稳定性产出的考虑,你可以将更新频繁的和变化缓慢的进⾏拆分,访问频繁的和访问较少的维表属性进⾏拆分,如:会员维表
4.5.3. 维度表设计基本步骤
维度表包含了事实表所记录的业务过程的度量的上下文和环境,通常包含了很多描述属性字段,每个维度表都包含了单一的主键列。维度表的设计包含了四个步骤:
-
确定主维度
主维度一般是业务系统同步而来,是事实分析过程中描述的最基础,最频繁的维度属性集合。如:网点维表的主维度为网点编码。 -
定义维度关联属性
基于主维度选择维度相关属性。如网点维表主维度是网点编码,关联维度例如:网点类型、网点层级、归属组织等。 -
维护ER关系
参照下图
-
输出物理表
物理维表策略上主要包含两种:快照表和拉链表,针对无变化维或者剧烈变化维,采用快照方式存储,针对缓慢变化维结合数据量情况,经验值数据量小于10000,采用快照模式,数据量大于10000,采用快照加拉链表模式(具体结合存储成本考虑),就目前场景涉及拉链表的维度表,都会配套对应的快照表(定期清理数据),以满足下游任务的高时效要求。- 快照表,结合实际情况,一般日分区(inc_day)
- 拉链表,处理缓慢变化方式很多,一般采用dw_star_date(生效日期)、dw_end_date(失效日期),通过更新失效日期的模式更新维度状态,见下图
4.5.4. 完善维度管理
护维表管理清单,重点注意维度列、维度表名、维表类型、主责方。
五、企业指标定义与管理规范治理
5.1. 为什么数仓一定要做指标管理?
使用一致的数据指标,避免一些因为信息差导致的沟通工作,保证大家使用数据指标时的简易度和准确性,
-
统一数据语言
当出现大家对同一个数据指标名称有不同理解时,往往会造成沟通效率低。统一数据语言,解决同义不同名/同名不同义的问题,用精确的可定量的业务语言来定义指标,可以降低工作中的沟通成本,提高沟通效率。
-
统一数据生产
同一个数据指标名有多种不同的取数口径,会出现数据差异的存在,导致数据可信度不高,核对成本较高。统一数据的生产需要保证同一个数据指标,从加工到落地是一样的生产方式,这样可以保证整个数据指标体系是规范的不变形的。统一数据生产可以帮我们解决同名同义不同数的问题,保证需求从加工到落地到使用都符合规范,提升数据的准确性和可信度。 -
统一指标使用
数据指标治理后,需要在页面中进行引导,并进行营销推广,让业务使用起来。统一指标使用,是要解决指标长期无人使用的问题,保证业务、研发都能看懂,提高数据指标的使用率。
5.2. 企业指标管理系统的使用
如何做好指标管理,主要包括三个部分:业务过程指标化、指标管理标准化、指标使用运营化。
5.2.1. 业务过程指标化
业务过程指标化主要包括以下环节:
理解业务场景:理解业务的底层逻辑,了解业务当前的发展阶段以及后续重点策略方向。
转换业务指标:根据业务场景,将原子化的指标进行组合,合理评估业务表现结果。
对齐指标口径:与 BA、业务方充分沟通,共同讨论指标定义和计算口径。
理解指标体系:将业务目标根据策略逐层拆解,保证每一个关键动作都有指标可以评估。
5.2.2. 指标管理标准化
在实际工作中经常遇到指标命名不规范,口径和算法不统一,或是一些已经过时的指标仍然在维护。针对这些问题,我们就需要在指标定义中明确,命名标准化,口径管理标准化,并进行生命周期管理。在数据服务方面,开发规范要标准化,对数据分层管理。数据应用要保证多产品同源,在不同看板中同一个指标的值应该是相同的。
①指标命名标准化
基础指标是某一个业务行为下事件的度量,是比较固定的基础指标。这类指标应该是表示单一业务概念的基本单元,在名称中应剔除多余的限制条件和维度信息,直接表达出指标的基本含义即可。指标命名规范为:业务修饰词_{实体修饰词_}基础词根,例如交易订单量。对于专有名词,例如行业"黑话",优先考虑以专有名词进行命名,这样可以降低业务人员的理解成本。
复合指标是在基础指标上增加了一些修饰词或一些维度。业务指标是在基础指标上增加一些四则运算。指标命名规范为:{日期修饰词+}[环境/专题修饰词]+{聚合修饰词+}业务修饰词+{实体修饰词+}基础词根,例如近 30天小程序交易订单量。
② 口径管理标准化
口径管理标准化,避免沟通、开发的过程中产生歧义或传递的缺失,导致需求反复。管理内容主要包括:指标名称,指标领域,指标定义,计算公式和计量单位。但这里所列的并不一定是完整的管理内容,大家可以根据实际场景,增加管理内容,比如关联的埋点信息、精度等等。
③生命周期管理
指标需要进行生命周期的管理,制定完整的规范机制以避免二次治理和重复劳动。包括制定指标新增、删除、修改的流程,明确指标负责人,分级管理指标等。
5.2.3. 指标使用运营化
5.3. 指标体系的运营归属?
包括基础信息、技术信息和衍生信息,由不同角色进行维护管理。
-
基础信息对应指标的业务信息,由业务管理人员、数据产品或 BI 分析师维护,主要包括归属信息(业务板块、数据域、业务过程),基本信息(指标名称、指标英文名称、指标定义、统计算法说明、指标类型(去重、非去重)),业务场景信息(分析维度,场景描述);
-
技术信息对应指标的物理模型信息,由数据研发进行维护,主要包括对应物理表及字段信息;
-
衍生信息对应关联派生或衍生指标信息、关联数据应用和业务场景信息,便于用户查询指标被哪些其它指标和数据应用使用,提供指标血缘分析追查数据来源的能力。
六、企业模型与代码开发管理规范
数仓开发准则
- 禁止反向数据依赖。
- 任务幂等性、数据可回滚原则,禁止使用insert into语句。
- 公共处理逻辑下沉化处理。
- 核心模型与扩展模型的分离。
- 不允许引用其他任务的过程临时表。
- 禁止一个任务更新多个目标表。
6.1. SQL代码开发规范原则
- 要求脚本代码行清晰、整齐,具有一定的可观赏性;
- 要求脚本功能,源表,目标表描述及其修改记录等齐全;
- 脚本代码编写要充分考虑执行速度最优的原则;
- 脚本代码行整体层次分明、结构化强;
- 脚本代码中应有必要的注释以增强代码的可读性。
6.2. 某企业SQL代码开发规范
SQL代码的编码原则如下:
- 禁止使用select * 操作,所有操作必须明确指定列名。
- 代码功能完善。
- 代码行清晰、整齐,代码行的整体层次分明、结构化强。
- 代码编写充分考虑执行速度最优的原则。
- 代码中需要添加必要的注释,以增强代码的可读性。
- 规范要求并非强制性约束开发人员的代码编写行为。实际应用中,在不违反常规要求的前提下,允许存在可以理解的偏差。
- SQL代码中应用到的所有SQL关键字、保留字都需使用全大写或小写,例如select/SELECT、from/FROM、where/WHERE、and/AND、or/OR、union/UNION、insert/INSERT、delete/DELETE、group/GROUP、having/HAVING和count/COUNT等。不能使用大小写混合的方式,例如Select或seLECT等方式。
- 4个空格为1个缩进量,所有的缩进均为1个缩进量的整数倍,按照代码层次对齐。
- 对应的括号要求在同一列的位置上。
- SQL代码禁止单独使用 JOIN 的语法。JOIN 应当显式标明是 INNER JOIN、LEFT JOIN、LEFT SEMI JOIN、FULL JOIN 的类型。
- 分区字段或脚本中引用的变量,应当使用单引号 ‘$insert_day’ 进行包裹。
- 插入数据应当使用 INSERT OVERWRITE TABLE 。
- 禁止使用 INSERT INTO TABLE。
- SQL 语句应当避免对大表的全表扫描,对大表的操作应尽量明确起始和结束分区,并尽可能降低单次查询的分区数量。
- SQL 语句应避免使用 ORDER BY 做全局排序,如果确实需要使用全局排序,请使用 DISTRIBUTE BY 和 SORT BY 的组合方式。
- 在标识字段为空值 null 时,若字段类型为 string 类型,禁止使用 ‘null’ 、 ‘NULL’ 、 ‘Null’ 等字符串的方式进行标识,应直接使用 null 的方式。
- SQL 中表和字段的别名,尽量取的通俗易懂。
- SQL 关键字推荐使用大写。
- A LEFT JOIN B 时,如果B表存在限制条件。例如需要 B.day=xxx ,则需要使用子查询,不推荐使用 : A LEFT JOIN B where B.day=xxx
6.3. 阿里巴巴的SQl开发管理规范
SQL代码的编码规范如下:
-
代码头部
代码头部添加主题、功能描述、作者和日期等信息,并预留修改日志及标题栏,以便后续添加修改记录。注意每行不超过80个字符,模板如下。-- MaxCompute(ODPS) SQL --************************************************************************** -- ** 所属主题: 交易 -- ** 功能描述: 交易退款分析 -- ** 创建者 : 有码 -- ** 创建日期: 20170616 -- ** 修改日志: -- ** 修改日期 修改人 修改内容 -- yyyymmdd name comment -- 20170831 无码 增加对biz_type=1234交易的判断 --**************************************************************************
-
字段排列要求
- SELECT语句选择的字段按照每行1个字段的方式编排。
- 首个选择的字段与SELECT之间隔1个缩进量。
换行缩进2个缩进量后,添加逗号再输入其它字段名。 - 2个字段之间的逗号分隔符紧跟在第2个字段的前面。
- AS语句应与相应的字段在同一行,多个字段的AS建议尽量对齐在同一列上。
-
INSERT子句排列要求:INSERT子句写在同一行,请勿换行。
-
SELECT子句排列要求
SELECT语句中所用到的from、where、group by、having、order by、join和union等子句,需要遵循如下要求: -
换行编写。
-
与相应的SELECT语句左对齐编排。
-
子句首个单词后添加2个缩进量,再编写后续的代码。
-
WHERE子句下的逻辑判断符and、or等,与WHERE左对齐编排。
-
超过2个缩进量长度的子句加1个空格后,再编写后续代码,例如order by和group by等。
-
-
运算符前后间隔要求
算术运算符、逻辑运算符前后要保留1个空格,并写在同一行(超过每行80个字符长度的限制除外)。 -
-
CASE语句的编写
CASE语句可以用于SELECT语句中对字段值进行判断取值的操作。CASE语句编排的规则如下:- WHEN子语在CASE语句的同一行,并缩进1个缩进量后开始编写。
- 每个WHEN子句尽量在1行内编写,如果语句较长可以换行。
- CASE语句必须包含ELSE子语,ELSE子句与WHEN子句对齐。
-
查询嵌套编写规范
在数据仓库系统ETL开发中经常使用子查询嵌套,其编写规范示例如下。
-
表别名定义约定
一旦在SELECT语句中给操作表定义了别名,在整个语句中对此表的引用都必须以别名替代,所以需要给所有的表添加别名。- 表别名采用简单字符命名,建议按a、b、c、d…的顺序进行命名,并避免使用关键字。
- 多层次的嵌套子查询别名之前要体现层次关系,SQL语句的别名需要分层命名,从第1层次至第4层次,分别用P(Part) 、S(Segment)、 U(Unit) 和D(Detail)表示。您也可以用a、b、c、d来表示第1层次到第4层次。
- 对于同一层次的多个子句,在字母后加1、2、3、4……区分,并根据情况对表别名添加注释。
-
SQL注释
- 每条SQL语句均应添加注释说明。
- 每条SQL语句的注释单独成行,并放在语句的前面。
- 字段注释紧跟在字段后面。
- 对不易理解的分支条件表达式添加注释。
- 对重要的计算添加注释,说明其功能。
- 过长的函数实现,应将其语句按实现的功能分段,添加注释进行说明。
-添加常量及变量的注释时,应注释被保存值的含义(必选),合法取值的范围(可选)。
-
分区表的使用
分区表禁止全表扫描,分区表执行必须加约束条件
6.4. UDF函数使用规范
- 对于处理单个字段逻辑特别复杂,如字段清洗等,建议封装使用UDF,逻辑较为复杂,未来通用性较强,建议封装成可公共使用的UDF。
- 平台管理下UDF管理已存在大量可用的UDF,可结合描述申请使用。
6.5.常用的Hive调优参数
参考《Hive调优》
七、集群任务部署开发管理规范
7.1. 任务部署调度管理规范
为了统一后期管理和维护,工作流(任务流)一般不建议员工自己任意创建命名,如果是维护任务的话,一般将任务放在对应存在的任务流中;
如果是新开发任务,任务比较多。可以按规范命名自己的任务流。并且及时更新在wiki。
7.2. 调度任务管理规范
- ETL 脚本名称务必与产出的表名相同
- 每个 ETL 脚本只允许产出一张结果表,(ads层部分特殊需求可合并,一般情况下也只允许一对一产出)
高内聚,低耦合 - 数据链路不宜过长(ODS至ADS最高不超过7层)
- 数据采集、数据推送脚本尽可能标识数据去向
脚本头需要加上分割线、作者、日期、目的、描述等信息 - ETL脚本格式、备注清晰,避免大范围、格式杂乱的脚本,合理利用临时表
7.3. 调度任务配置准则建议
- 全局参数:调度任务参数配置使用全局参数,如:队列名称、SQL任务名称。
- 任务等级:对于核心重要任务需将任务配置为S级,并配置相应的电话告警。
- 任务依赖:任务必须配置正确的依赖关系,以免造成数据错误。
- 任务优先级:按照任务重要性给任务配置相应的优先级,包含紧急、重要、普通、次要。
- 重试机制:任务配置重试次数为3,避免其他因素造成任务失败。
- 告警机制:任务必须配置相应的开发人员/运维人员,异常处理优先级为:开发人员>运维人员。
- 调度周期:调度任务周期配置,根据实际业务场景配置小时、日、周、月等周期。
- 版本管理:发布版本说明:每次发布时要详细填写修改的内容。
7.4. 大数据开发关于任务运维需要做哪些事?(面试题)
当开发人员根据需求将代码发布上线后,还需要及时处理数据、程序、调度、监控告警等的异常事件,保障数据产出时效、程序高效运行和生产稳定性。
- 程序异常处理、性能优化。
- 调度异常处理。
- 数据质量监控规则异常分析、规则优化。
- 数据异常的核查。
- 运维阶段的流程包括分析影响、制定与实施方案和验证实施方案。
7.5. 集群资源队列使用规范
计算资源依赖yarn队列资源,资源的使用不规范会影响重要任务的时效问题,同时也会造成不必要的资源浪费,于是针对资源使用必须统一化和规范化。规范化使用如下:
- 禁止调度任务不指定队列,使用默认default队列
- 禁止在调度任务中使用常量队列名,如:set mapreduce.job.queuename=root.next(同时spark任务也是如此:–queue root.paas_test),而应该是set mapreduce.job.queuename=${queue_name},具体变量名可在调度任务参数列表指定。
八、数据标准与规范治理常见面试题
-
如何确保数据源字段枚举值注释改变,通知到数仓及下游应用?
可以从两个角度回答第一数据治理推动业务系统开发规范,任何系统变更及时通知下有系统,
第二,结合数据质量监控角度回答,如通过配置相关数据质量规则实现监控
-
如何确保数仓严格遵守了词根规范?
确保数仓严格遵守词根规范可以采取以下几个步骤:-
明确定义词根规范:明确数仓中的词根规范,包括命名约定、命名规则、命名长度等。这可以通过编写规范文档或者制定规范手册来实现,或者提供词根库对外提供服务。
-
培训和教育:对数仓团队成员进行培训,确保他们了解词根规范的重要性以及如何正确应用规范。培训可以包括规范的解释、示例和练习。
-
自动化工具支持:使用自动化工具来辅助词根规范的实施和检查。这些工具可以帮助验证命名是否符合规范,并提供修复建议。
-
代码审查和审核:在数仓开发过程中,进行代码审查和审核,确保所有的命名都符合词根规范。这可以通过定期的代码审查会议或者使用代码审核工具来实现。
-
定期检查和监控:定期对数仓进行检查和监控,确保词根规范的持续遵守。可以设置警报机制,一旦发现规范违规的情况,及时采取纠正措施。
-
持续改进:根据实际情况和反馈,不断改进词根规范。定期与数仓团队进行沟通和讨论,了解他们在实践中遇到的问题,并根据需要进行相应的调整和更新。
通过以上步骤,可以确保数仓严格遵守词根规范,提高数据一致性和可维护性,减少命名混乱和错误,提高数据管理效率。
-