盘点数据仓库建设需要知道的那些事
@
建设规范
为何要有规范
-
无规矩不成方圆,建立规范的目的也是为了提升开发效率,可以很快的追踪数据链路,最终保障交付质量。数据仓库是数据工程师的无形产品。
-
数据规范是数仓体系建设的"语言",是数据使用的说明书和翻译官,同时也是数据质量的保驾护航者。为了数据体系能够长久健康的发展,数仓管理,应该从人治逐步转变到制度化、规范化、工具化的道路上了来。
-
在数据仓库开发的过程中,遵循一定的规范能够避免我们的开发偏离原有设计的方向,也能够保证数据安全。
规范如何落地
- 规范制定:由Leader 或架构师充分考虑公司实际情况,参考行业标准或约定俗成的规范,综合统一制定。也可以将规范拆分后交由各个部分核心开发人员编写(比如模型设计师负责模型设计规范,ETL 工程师负责 ETL 开发规范,BI开发人员制定前端开发规范), Leader 或架构师统一整合,总体上初稿应该尽量保证规范的完整性和各个部分间的兼容性。
- 规范讨论:初稿完成后由 Leader 牵头组织部分核心成员进一步完善各个细节,纠正初稿的不足。
- 规范推行:定稿后规范已具备全面推广的条件,可以下发给所有团队成员。分发宣讲后进入执行阶段,所有人必须严格遵守,为了确保规范的贯彻落实,除了通过以上两点引起全员重视外,还需要组织、制度、流程上的多方面保障。
- 数据模型应该有统一归口,比如数据架构师,架构师定期检查模型是否合理合规。
- 组织数据开发人员,定期 Review 每个人的代码,目的是通过对比和讨论让大家明白什么样的才是好代码,最终使“写好代码”成为基本素养。如果觉得采用局部思路也可以由 Leader 负责定期检查,有问题的私下指出来帮助相应的组员逐渐规范。
- 规范的执行监督,最好引入相应的工具加强监管。比如在有指标体系元数据、有词根(可以用来统一表名、字段名、主题域名等等)库元数据、有建表的元数据、有 ETL 流程的元数据等时,基于数据标准、数据质量监控如备注是否为空、字段或表命名里的词根是否都在词根库里存在、表或页面等用到的指标是否都存在于指标体系、数据血缘中是否存在闭环或者孤立的节点。
- 规范完善:在宣讲阶段、执行阶段遇到问题,发行稿应该根据实际情况对规范做出调整,唯有经过实践检验才能愈发完善进而降低沟通成本、提高开发效率、保证交付质量。
有哪些规范
-
设计规范:包括数据模型设计、命名规范、代码设计规范、指标体系设计、词根库。
-
流程规范:主要是从数仓管理的角度,对数仓场景下的各种流程进行约束。核心流程一共提炼出来五类:需求提交、模型设计、ETL开发、前端开发、上线流程。
- 需求提交流程
- 需求对接人;
- 需求提交途径;
- 需求澄清、评审会。
- 模型设计流程
- 模型评审会沟通
- ETL开发流程
- 数据接入方式,数据接入工具
- 前端开发规范
- 报表风格;
- 更新时间监控。
- 上线流程
- 确定上线时间;
- 确定上线途径;
- 确定上线后验证。
- 需求提交流程
- 质量管理规范:针对从数据源到应用层的数据质量问题,主要是从数据流动的角度实现,包括源端管控、数仓管理、应用管控。
- 源端管控
- 监控数据源接入任务是否正常执行;
- 监控数据源数据是否正常。
- 数仓管理
- 监控模型任务是否正常执行;
- 监控模型数据是否正常。
- 应用管控
- 监控报表任务是否正常执行;
- 监控报表数据是否正常。
- 源端管控
- 安全规范:安全规范对外是为了防止数据通过网络泄露,对内是通过权限的管理实现数据权限最小化;主体分为网络安全、账号安全、数据安全。
- 网络安全
- 考虑数据应用层是否需要外网使用。
- 账号安全
- 一个一账号原则,可以与公司内部账号绑定,遵循数据权限最小化。
- 数据安全
- 涉及到个人信息的数据加密处理;
- 必须要明文展示的敏感数据掩码处理;
- 前端报表页面加水印显示数据使用人信息。
- 网络安全
数仓分层
分层原则
数仓分层既要保证数据层的稳定,又要屏蔽对下游的影响,并且要避免链路过长,数仓分层总结如下:
- 不能为了分层而分层,没有最好的,只有最适合的。
- 分层是以解决当前业务快速的数据支撑为目的,为未来抽象出共性的框架并能够赋能给其他业务线,同时为业务的发展提供稳定的、准确的数据支撑,并能够按照已有的模型为新业务发展提供方向,也就是数据的驱动和赋能。
好的数仓分层架构会带来以下好处:
- 清晰的数据结构;
- 数据血缘追踪;
- 减少重复开发;
- 数据关系条理化;
- 屏蔽原始数据的影响;
常见分层
数仓分层要结合公司业务进行,并且需要清晰明确各层职责,一般采用如下分层结构:
- ODS层:数据源层,仅导入业务方数据,不做任何处理,相当于大数据平台前的快照;
- DW层:数据明细层,对数据进行主题划分,分为事实表和维度表,并对数据进行规范处理,如数据清洗等操作;
- DM层:数据轻汇总层,建设通用性维度和指标,主要表数据还是明细数据,部分数据为汇总数据,主要增强指标复用性;
- APP层:数据应用层,面向不同部门,不同业务需求进行定制化开发,提供报表数据;
数仓建模在那层建设呢?我们以维度建模为例,建模是在数据源层的下一层进行建设,就是在DW层进行数仓建模,所以DW层是数仓建设的核心层。
- STG:为ODS全量表提供增量变化的数据,某种意义上和ODS有重叠。
- 数据源层:ODS(Operational Data Store),是最接近数据源中数据的一层,为了考虑后续可能需要追溯数据问题,因此对于这一层就不建议做过多的数据清洗工作,原封不动地接入原始数据即可,至于数据的去噪、去重、异常值处理等过程可以放在后面的 DWD 层来做。
- 数据仓库层:DW(Data Warehouse)是我们在做数据仓库时要核心设计的一层,从 ODS 层中获得的数据按照主题建立各种数据模型。DW 层又细分为 DWD(Data Warehouse Detail)层、DWM(Data WareHouse Middle)层和 DWS(Data WareHouse Servce) 层。
- 数据明细层:DWD(Data Warehouse Detail),该层一般保持和 ODS 层一样的数据粒度,并且提供一定的数据质量保证。DWD 层要做的就是将数据清理、整合、规范化、脏数据、垃圾数据、规范不一致的、状态定义不一致的、命名不规范的数据都会被处理。同时,为了提高数据明细层的易用性,该层会采用一些维度退化手法,将维度退化至事实表中,减少事实表和维表的关联。另外,在该层也会做一部分的数据聚合,将相同主题的数据汇集到一张表中,提高数据的可用性 。
- 数据中间层:DWM(Data WareHouse Middle),该层会在 DWD 层的数据基础上,数据做轻度的聚合操作,生成一系列的中间表,提升公共指标的复用性,减少重复加工。直观来讲,就是对通用的核心维度进行聚合操作,算出相应的统计指标。在实际计算中,如果直接从 DWD 或者 ODS 计算出宽表的统计指标,会存在计算量太大并且维度太少的问题,因此一般的做法是,在 DWM 层先计算出多个小的中间表,然后再拼接成一张 DWS 的宽表。由于宽和窄的界限不易界定,也可以去掉 DWM 这一层,只留 DWS 层,将所有的数据再放在 DWS 亦可。
- 数据服务层:DWS(Data WareHouse Servce),DWS 层为公共汇总层,会进行轻度汇总,粒度比明细数据稍粗,基于 DWD 层上的基础数据,整合汇总成分析某一个主题域的服务数据,一般是宽表,DWS 层应覆盖 80% 的应用场景。按照业务划分,如流量、订单、用户等,生成字段比较多的宽表,用于提供后续的业务查询,OLAP分析,数据分发等。一般来讲,该层的数据表会相对比较少,一张表会涵盖比较多的业务内容,由于其字段较多,因此一般也会称该层的表为宽表。
- 数据应用层:APP(Application),也有叫DM(数据集市)或ADS。主要是提供给数据产品和数据分析使用的数据,一般会存放在 ES、 PostgreSql、Redis 等系统中供线上系统使用,也可能会存在 Hive 或者 Druid 中供数据分析和数据挖掘使用。比如经常说的报表数据,一般就放在这里。
- 维表层(Dimension):如果维表过多,也可针对维表设计单独一层,维表层主要包含两部分数据
- 高基数维度数据:一般是用户资料表、商品资料表类似的资料表。数据量可能是千万级或者上亿级别。
- 低基数维度数据:一般是配置表,比如枚举值对应的中文含义,或者日期维表。 数据量可能是个位数或者几千几万。
主题域划分原则
- 按照业务或业务过程划分
- 业务容易理解,就是指的功能模块、业务线。
- 业务过程:指企业的业务活动事件,如下单、支付、退款都是业务过程。不过需要注意的是,一个业务过程是一个不可拆分的行为事件,通俗的讲,业务过程就是企业活动中的事件。
- 按照数据域划分
- 数据域是指面向业务分析,将业务过程或者维度进行抽象的集合。其中,业务过程可以概括为一个个不可拆分的行为事件,在业务过程下,可以定义指标,维度是指度量的环境,如买家下单事件,买家是维度。为保障整个体系生命力,数据域是需要抽象提炼,并且长期维护和更新的,但不轻易变动。
- 在划分数据域时,既能涵盖当前所有的业务需求,又能在新业务进入时无影响的被包含进已有的数据域中和扩展新的数据域。
数据模型设计原则
- 高内聚、低耦合:即主题内部高内聚、不同主题间低耦合。明细层按照业务过程划分主题,汇总层按照“实体+活动”划分不同分析主题,应用层根据应用需求划分不同应用主题。
- 核心模型和扩展模型要分离:建立核心模型与扩展模型体系,核心模型包括的字段支持常用的核心业务,扩展模型包括的字段支持个性化或少量应用的需要,不能让扩展模型的字段过度侵入核心模型,以免破坏核心模型的架构简洁性与可维护性。
- 公共处理逻辑下沉及单一:越是底层公用的处理逻辑越应该在数据调度依赖的底层进行封装与实现,不要让公用的处理逻辑暴露给应用实现,不要让公共逻辑多处同时存在。
- 成本与性能平衡:适当的数据冗余可换取查询和刷新性能,不宜过度冗余与数据复制。
- 数据可回滚:处理逻辑不变,在不同时间多次运行数据结果确定不变。
数据类型规范
需统一规定不同的数据的数据类型,严格按照规定的数据类型执行:
金额 : double 或使用 decimal(28,6) 控制精度等,明确单位是分还是元
字符串: string
id: bigint
时间: string
状态 : string
数据冗余规范
针对宽表的冗余字段要确保:
- 冗余字段要使用高频,下游3个或以上使用。
- 冗余字段引入不应造成本身数据产生过多的延后。
- 冗余字段和已有字段的重复率不应过大,原则上不应超过60%,如需要可以选择join或原表拓展。
表规范
处理规范
- 增量表:新增数据,增量数据是上次导出之后的新数据。
- 记录每次增加的量,而不是总量;
- 增量表,只报变化量,无变化不用报;
- 每天一个分区。
- 全量表:每天的所有的最新状态的数据。
- 全量表,有无变化,都要报;
- 每次上报的数据都是所有的数据(变化的 + 没有变化的);
- 只有一个分区。
- 快照表:按日分区,记录截止数据日期的全量数据。
- 快照表,有无变化,都要报;
- 每次上报的数据都是所有的数据(变化的 + 没有变化的);
- 一天一个分区。
- 拉链表:记录截止数据日期的全量数据。
- 记录一个事物从开始,一直到当前状态的所有变化的信息;
- 拉链表每次上报的都是历史记录的最终状态,是记录在当前时刻的历史总量;
- 当前记录存的是当前时间之前的所有历史记录的最后变化量(总量);
- 只有一个分区。
命名规范
- 表名、字段名采用一个下划线分隔词根(示例:clienttype->client_type)。
- 每部分使用小写英文单词,属于通用字段的必须满足通用字段信息的定义。 尽量用英文简写,部分可以汉语拼音首字母标准缩写如中国制造zgzz。
- 表名、字段名需以字母为开头。
- 命名不宜过长,表名、字段名最长不超过 64 个英文字符。
- 优先使用词根中已有关键字(数仓标准配置中的词根管理),定期 Review 新增命名的不合理性。
- 在表名自定义部分禁止采用非标准的缩写。
模型层 :卡券主题域中卡券购买主题 dwd_ride_package_user_ride_cashcoupon_record_df。分解 :dwd-层次 ride_package-主题域 user_ride_cashcoupon_record-主题 d-按天 f-全量
贴源层以及以下: 领养收益表ods_mysql_adoptdb_adopt_order_income_di。分解 :ods-层次 mysql-数据库类型 adoptdb-库名 order_income-业务表名 d-按天i-增量
生命周期管理
通过对历史数据的等级划分与对表类型的划分生成相应的生命周期管理矩阵。
- 主要将历史数据划分为P0、P1、P2、P3四个等级,其具体定义如下:
- P0: 非常重要的主题域数据和非常重要的应用数据,具有不可恢复性,如交易、日志、集团KPI数据、IPO关联表。
- P1: 重要的业务数据和重要的应用数据,具有不可恢复性,如重要的业务产品数据。
- P2: 重要的业务数据和重要的应用数据,具有可恢复性,如交易线ETL产生的中间过程数据。
- P3: 不重要的业务数据和不重要的应用数据,具有可恢复性,如某些SNS产品报表。
- 表类型划分
- 事件型流水表(增量表):指数据无重复或者无主键数据,如日志。
- 事件型镜像表(增量表):指业务过程性数据,有主键,但是对于同样主键的属性会发生缓慢变化,如交易、订单状态与时间会根据业务发生变更。
- 维表:包括维度与维度属性数据,如用户表、商品表。
- Merge全量表:包括业务过程性数据或者维表数据。由于数据本身有新增的或者发生状态变更,对于同样主键的数据可能会保留多份,因此可以对这些数据根据主键进行Merge操作,主键对应的属性只会保留最新状态,历史状态保留在前一天的分区中。例如,用户表、交易表等都可以进行Merge操作。
- ETL临时表:指ETL处理过程中产生的临时表数据,一版不建议保留,最多7天。
- TT临时数据:TT拉取的数据和DbSync产生的临时数据最终会流转到DS层,ODS层数据作为原始数据保留下来,从而使得TT&DbSync上游数据成为临时数据。这类数据不建议保留很长时间,声明周期默认设置为93天,可以根据实际情况适当减少保留天数。
- 普通全量表:很多小业务数据或者产品数据,BI一般是直接全量拉取,这种方式效率快,对存储压力也不是很大,而且表保留很长时间,可以根据历史数据等级确定保留策略。
通过上述历史数据等级划分与表类型划分,生成相应的声明周期管理矩阵,如下表所示:
指标管理
指标定义
指标是用于衡量事物发展程度的单位或方法,也常被称作度量,通常情况下也是报表统计的字段,例如:人口数、营业收入、用户数、利润率、成功率、失败率、覆盖率等。
指标构成
- 数据域
- 数据域是统一数仓层的顶层划分,是一个较高层次的数据归类标准,是对企业业务过程进行抽象、提炼、组合的集合,面向业务分析,一个数据域对应一个宏观分析领域,比如采购域、供应链域、HR域等。
- 数据域是抽象、提炼出来的,并且不轻易变动,既能涵盖当前所有业务需求,又能在新业务进入时无影响地将其分配到已有的数据域中,只有当所有分类都不合适时才会扩展新的数据域。
- 数据域是有效归纳、组织业务过程的方式,同时方便定位指标/度量。
- 业务过程
- 业务过程是一种企业的业务活动事件,且是企业经营过程中不可拆分的行为事件,比如下订单、银行转账、账号注册都是业务过程。
- 业务过程产生度量,并且会被转换为最终的事实表中的事实。业务过程一般与事实表一一对应,也有一对多或者多对一的特殊情况,比如累计快照事实表就会把多个业务过程产生的事实在一张表中表达。
- 统计周期
- 统计周期即统计数据的时间范围,例如历史至今、最近7天、最近30天、最近1年等(类似于SQL中where后的时间条件)。
- 公共定义仅支持定义统计周期,定义时与数据域、业务过程、事实/维度表是否定义无关,在此仅作计算逻辑定义。
- 业务限定
- 业务限定是指除统计维度以外对指标进行限定抽象的业务场景修饰词,限定统计的业务范围,筛选出符合业务规则的记录(类似于SQL中where后的条件,不包括时间区间)。
- 业务限定也有归属的数据域,某个业务限定来源于一张事实表或维度表,继承来源表的数据域,比如限定词“江苏省”、“部门-销售事业部”等。
- 维度
- 维度是度量的环境,用来反映业务的一类属性,这类属性的集合构成一个维度。维度属于一个数据域,如组织维度(其中包括产品线、部门、科室、车间等)、时间维度(其中包括年、季、月、周、日等)。
指标分类
数仓指标分类主要为原子指标、派生指标、复合指标、应用指标。
- 原子指标:是针对某一业务事件行为的度量,是一种不可拆分的指标,具有明确业务含义,比如支付金额。原子指标有确定的字段名称、数据类型、算法说明、所属数据域和业务过程。原子指标名称一般采用“动作+度量”方式命名,比如支付金额、注册用户数。
- 派生指标:可以理解为对原子指标业务统计范围的圈定,比如最近1年销售事业部销售金额(“最近1年”是统计周期,“销售事业部”是业务限定,“销售金额”是原子指标),1个派生指标=1个原子指标+统计周期+业务限定。
- 复合指标:是基于已经设计好的派生指标,设定复合计算逻辑而构成的指标。例如,一个已保存的派生指标A为最近1年销售事业部销售金额,另一个已保存的派生指标B为历史至今销售事业部在职员工人数,A/B即可以统计最近一年销售事业部人均销售金额。
- 应用指标:通常指从客户处调研得到,满足业务需要,最终要形成报表的指标,一般来源于派生指标或者复合指标。
命名规范
-
公共规则
- 所有单词⼩写
- 单词之间下划线分割 (反例:appName 或 AppName)
- 可读性优于长度 (词根,避免出现同⼀个指标,命名⼀致性)
- 禁止使用 sql 关键字,如字段名与关键字冲突时 +col
- 数量字段后缀 _cnt 等标识...
- ⾦额字段后缀 _price 标识
- 天分区使⽤字段 dt,格式统⼀ (yyyymmdd 或 yyyy-mm-dd)
- ⼩时分区使⽤字段 hh,范围 (00-23)
- 分钟分区使⽤字段 mi,范围 (00-59)
- 布尔类型标识:is_{业务},不允许出现空值
-
指标命名规范:结合指标的特性以及词根管理规范,将指标进⾏结构化处理。
- 基础指标词根,即所有指标必须包含以下基础词根:
- 业务修饰词,用于描述业务场景的词汇,例如 trade-交易。
- 日期修饰词,用于修饰业务发生的时间区间。
- 聚合修饰词,对结果进⾏聚集操作。
- 基础指标,单⼀的业务修饰词+基础指标词根构建基础指标,例如:交易⾦额 -trade_amt。
- 派⽣指标,多修饰词+基础指标词根构建派⽣指标。派⽣指标继承基础指标的特性,例如:安装门店数量-install_poi_cnt。
- 普通指标命名规范,与字段命名规范⼀致,由词汇转换即可以。
-
基础指标: 业务修饰词+基础指标词 如 交易金额 trade_cost
-
派生指标: 多修饰词+ 基础指标词 如 安装门店数量 install_poi_cnt
-
日期类型指标: 业务修饰词+基础指标词+日期修饰词 如 七日交易额 trade_cost_7d
-
聚合类型指标:业务修饰+基础指标词+聚合修饰词+日期修饰词 如 七日平均交易额 trade_cost_avg_7d
-
本人博客网站IT小神 www.itxiaoshen.com