数据仓库的核心是展现层和提供优质的服务。ETL 及其规范、分层等所做的一切都是为了一个更清晰易用的展现层。
数仓架构的原则:
1、底层业务的数据驱动为导向同时结合业务需求驱动
2、便于数据分析
屏蔽底层复杂业务
简单、完整、集成的将数据暴露给分析层
3、底层业务变动与上层需求变动对模型冲击最小化
业务系统变化影响削弱在基础数据层(资金订单改造)
结合自上而下的建设方法削弱需求变动对模型的影响
数据水平层次清晰化
3、高内聚松耦合
主题之内或各个完整意义的系统内数据的高内聚
主题之间或各个完整意义的系统间数据的松耦合
4、构建仓库基础数据层
使得底层业务数据整合工作与上层应用开发工作相隔离,为仓库大规模开发奠定基础
仓库层次更加清晰,对外暴露数据更加统一
数仓模型不只是考虑如何设计和实现功能,设计原则应该从访问性能、数据成本、使用成本、数据质量、扩展性来考虑。
如何搭建一个好的数据仓库:
数仓设计的3个维度:
当前主流建模方法为:ER模型、维度模型。
1、ER模型常用于OLTP数据库建模,应用到构建数仓时更偏重数据整合, 站在企业整体考虑,将各个系统的数据按相似性一致性、合并处理,为数据分析、决策服务,但并不便于直接用来支持分析。缺陷:需要全面梳理企业所有的业务和数据流,周期长,人员要求高。
2、维度建模是面向分析场景而生,针对分析场景构建数仓模型;重点关注快速、灵活的解决分析需求,同时能够提供大规模数据的快速响应性能。针对性强,主要应用于数据仓库构建和OLAP引擎低层数据模型。优点:不需要完整的梳理企业业务流程和数据,实施周期根据主题边界而定,容易快速实现demo,而且相对来说便于理解、提高查询性能、对称并易扩展。
作为大数据板块,数据来源更加广泛,针对的业务域也更加宽广,所以维度建模相对来说更加灵活并适用。
在讨论维度建模之前,关注数仓和BI的基本目标是非常有意义的,在做日常的数据需求的时候,经常会遇到如下几个痛点:
基于上面的痛点,就需要搭建一套DW/BI系统(当然现在市面上有很多类似的产品,例如:如:QuickBI、GrowingIO、神策、猛犸等等),但是对于公司而言,适合自己的才是最好的,大部分公司选择自己搭建或者利用开源的软件(例如MateBase),这个系统必须满足:
DW/BI架构:
源事务:业务库或者日志等各个方面的数据源,一般不维护历史信息。
ETL:目的是构建和加载数据到展现区的目标维度模型中,划分维度和事实。
模型:围绕业务过程度量事件进行构建,为满足用户无法预估的需求,必须包含详细的原子数据。
为避免数据的冗余存储造成的浪费和低效,并方便多业务部门查询方便以及同一指标的数据准确性和业务的扩展性,一般采取以下的架构模式:
维度建模:
用于度量的事实表,事实表一般会有两个或者多个外健与维度表的主键进行关联。事实表的主键一般是组合健,表达多对多的关系。
用于描述环境的维度表,单一主键。维度表的属性是所有查询约束和报表标示的来源。维度提供数据的入口点,提供所有DW/BI分析的最终标识和分组。
所以维度建模表示每个业务过程包含的事实表,事实表里面存储事件的数值化度量,围绕事实表的是多个维度表,维度表包含事件发生的实际存在的文本环境。
从图表中能看出来,维度模型(星型模型)比较简单,而且适于变化,各个维度的地位相同。可根据业务情况进行新增或者修改(只要维度的单一值已经存在事实表中)。
雪花模型:
维度建模的主要是4个主要决策:
1、选择业务过程
2、声明粒度
3、确认维度
4、确认事实
其中粒度是非常重要的,粒度用于确定事实表的行表示什么,建议从关注原子级别的粒度数据开始设计,因为原子粒度能够承受无法预估的用户查询,而且原子数据可以以各种可能的方式进行上卷,而一旦选择了高粒度,则无法满足用户下钻细节的需求。
事实是整个维度建模的核心,其中雪花模型或者星型模型都是基于一张事实表通过外健关联维表进行扩展,生成一份能够支撑可预知查询需求的模型宽表,而且最后的查询也是落在事实表中进行。
目前常见的维度模型:
星型模型
每一个维表都与都与事实表相关联。数据冗余量较大
雪花模型
有些维表可能不与事实表直接关联,而是通过其他维表关联到事实表。数据冗余量较小
星座模型
由多个事实表相组合,维表是公共的。企业中一般都是星座模型
注意:
维度建模是一个迭代设计过程,设计工作从总线矩阵中抽取实体级别的初始图形化模型开始,详细建模过程要深入定义、资源、关系、数据质量问题以及每张表的数据转换,主要目标是建立满足用户需求的模型,校验可加载到模型中的数据,为ETL提供明确的方向。
这是一个以客户创建为事实表的售前流程的雪花模型。
事实表:客户创建信息表
维度表:销售信息表、店铺信息表、跟进表/约见表/风控通过表/订单表的维度上卷。
以上面的维度模型可以聚合出创建、跟进、风控等各个维度的上层展现的数据。
扩展:实时即未来
目前不少公司都在尝试以Flink、Kudu为基础的实时数仓架构,里面的数仓分层模型和离线的数仓架构基本相同。
下图为实时数仓架构,离线和实时的差不多,画图好难 ,所以在网上拷贝了这个图,如侵删,具体实时的架构图见:
都在说实时数据架构,你了解多少?
都在说实时数据架构,你了解多少?mp.weixin.qq.com1、ODS原始层是存放原始数据,主要是埋点数据(日志数据)和业务操作数据(binlong),数据源主要是Mysql、HDFS、Kafka等
2、DW中间层主要存放ETL和主题汇总之后的中间层数据,这块又分为:
3、DM数据集市层,以数据域+业务域的理念建设公共汇总层,对于DM层比较复杂,需要综合考虑对于数据落地的要求以及具体的查询引擎来选择不同的存储方式,分为轻度汇总层和高度汇总层。
4、理论上上面还一APP层,应用层,主要是通过这几层之后,生成轻度或者高度汇总的数据,然后根据业务域进行接口封装提供给上层使用。
但是实时数仓面临以下几个实施关键点:
详情见:
高威:实时数仓模型(持续更新ing)zhuanlan.zhihu.com思考:
实时数仓架构和数据中台一样,虽然都是属于当前比较热门的概念,但是对于实时数仓的狂热追求大可不必。
首先,在技术上几乎没有难点,基于强大的开源中间件(例如:Flink、kudu等)实现实时数据仓库的需求已经变得没有那么困难。
其次,实时数仓的建设一定是伴随着业务的发展而发展,武断的认为实时数仓架构最符合当前公司的需求是不对的。实际情况中随着业务的发展数仓的架构变得没有那么非此即彼。
最后,如何顺畅的将传统的离线数仓+实时链路处理流程升级到实时数仓架构是个很大的问题,毕竟中间涉及到很多的数据模式、技术中间件、计算引擎都不太一样。
常见的数仓命名规则:
前缀(ODS/DWD/MID)+主题域(user/shp)+业务类型+自定义表名+后缀(dd/ds/pi)
维度建模的缺点
维度建模的领域主要适用与数据集市层,它的最大的作用其实是为了解决数据仓库建模中的性能问题。维度建模很难能够提供一个完整地描述真实业务实体之间的复杂关系的抽象方法。
当前公司的数仓模型架构:
首先对ETL得到的数据进行ER建模,关系建模,得到一个规范化的公司层面的数据仓库模式。然后用这个中心仓数据库为公司各部门建立基于维度建模的数据集市。
而维度建模都集中在各个DM层里面,也就是针对具体的业务线或者主题域,这样紧紧围绕着业务模型,可以直观的反映出业务模型中的业务问题。
分层的误区
数仓层内部的划分不是为了分层而分层,分层是为了解决 ETL 任务及工作流的组织、数据的流向、读写权限的控制、不同需求的满足等各类问题。
业界较为通行的做法将整个数仓层又划分成了 dwd、dwb、dws、dim、mid 等等很多层。然而我们却始终说不清楚这几层之间清晰的界限是什么,或者说我们能说清楚它们之间的界限,复杂的业务场景却令我们无法真正落地执行。
所以数据分层这块一般来说三层是最基础的:
至于DW层如何进行切分,是根据具体的业务需求和公司场景自己去定义,一般来说需要:
1、分层是解决数据流向和快速支撑业务的目的;
2、必须按照主题域和业务域进行贯穿;
3、层级之间不可逆向依赖。
4、如果依赖ODS层数据可以完成数据支撑,那么业务方直接使用落地层这也有利于快速、低成本地进行一些数据方面的探索和尝试。
5、确定分层规范后,后续最好都遵循这个架构,约定成俗即可;
6、血缘关系、数据依赖、数据字典、数据命名规范等配套先行;
DW 内的分层没有最正确的,只有最适合你的。
宽表的误区
在数仓层开始引入了宽表。所谓宽表,迄今为止并没有一个明确的定义。通常做法是把很多的维度、事实上卷或者下钻之后关联到某一个事实表中,形成一张既包含了大量维度又包含了相关事实的表。
宽表的使用,有其一定的便利性。使用方不需要再去考虑跟维度表的关联,也不需要了解维度表和事实表是什么东西。
但是随着业务的增长,我们始终无法预见性地设计和定义宽表究竟该冗余多少维度,也无法清晰地定义出宽表冗余维度的底线在哪里。
一个可能存在的情况是,为了满足使用上的需求,要不断地将维表中已经存在的列增加到宽表中。这直接导致了宽表的表结构频繁发生变动。
目前我们所采用的做法是:
1、根据主题域和业务域,将某个业务的所有节点梳理清楚;
2、将关键节点的数据作为事实表依据,然后横向扩充其他事实表上卷数据(包含一些统计指标),同时纵向的添加该节点上一些主键对应的维度;
3、宽表的涉及不依赖具体的业务需求而是根据整体业务线相匹配;
4、尽量用维度建模代替宽表;
为什么说尽量用维度建模代替宽表,就算字段和数据会冗余,维度建模的方式也会表全量数据的宽表模式较好,原因:
1、维度建模是以某一个既定的事实为依据,既然是事实表,那么这块的业务如果不变动的情况下,事实表的粒度基本不会改变;
2、事实表和维度表解耦,维度表的变更事实表基本不会影响,结果表也只需要回刷一下数据流程即可;
3、新增维度完全可以按照星型模型或者雪花模型动态添加新维度;
4、维度模型可以作为宽表的基础,一旦确定全部的数据流程,可以通过维度模型再生成对应宽表进行快速的业务支撑;
--------------------------------------分割线-------------------------------------
2020-08-24更新
指标管理
数仓模型中,最重要的模块可能就是数据治理,我们在建立数仓分层的时候,虽然解决 ETL 任务及工作流的组织、数据的流向、读写权限的控制、不同需求的满足等各类问题,但是在给业务方提供不同数据需求的情况下不可避免的会发生一下几个问题:
1、指标定义不够清晰明确,两个页面上的指标定义其实是不同的,但是展示给商家看到的可能是同一个中文名称。又或者同样一个含义的指标在不同的界面上展示的名称却不相同,让人产生歧义。
2、同一个指标因为由不同的数据开发同学来制作,可能会被重复开发,不但造成资源浪费,还会造成维护困难。
3、对于需要新开发的指标,不仅缺少开发工具简化开发流程,甚至该使用哪些表,不该使用哪些表很大程度上都要凭借数据开发同学与数仓同学的经验。如果稍微马虎一点或者缺乏经验,比如使用了某些业务域下特有的表或者不是由数仓提供的统一中间层的表就可能会使用错误的数据,造成后期返工等情况。
而且在数据需求越来越多,数据中台提供的指标也日益丰富。但是指标定义混乱,描述不清会严重影响数据的可信度和数据开发的成本,所以就需要搭建一个指标系统,来维护已有的数据指标,并为未来可能新增的指标建立相应的规范。
如何去建立好这个指标库或者指标系统呢。
一般来说指标系统主要分为:原子指标和派生指标
1、在数仓分层的时候,进行维度建模,那么就必须指定好相应的主题域和事实表处理的最小逻辑(也就是事实),那么在这个基础上可以先定义原子指标。
原子指标:原子指标和度量含义相同,基于某一业务事件行为下的度量,是业务定义中不可再拆分的指标,具有明确业务含义的名词 ,如支付金额。原子指标描述的其实是一种指标的类型,比如订单支付金额,支付订单数,下单订单数,PV,UV 等等。但是仅仅一个原子指标是不能直接取数的。
但业务方更关心的指标,是有实际业务含义,可以直接取数据的指标。比如店铺近1天订单支付金额就是一个派生指标,会被直接在产品上展示给商家看。这个指标却不能直接从数仓的统一中间层里取数(因为没有现成的事实字段,数仓提供的一般都是大宽表)。需要有一个桥梁连接数仓中间层和业务方的指标需求,于是便有了派生指标。
2、派生指标=维度+原子指标+修饰词。当维度,原子指标,修饰词都确定的时候就可以唯一确定一个派生指标,同时给出具体数值。
例如:店铺近1天订单支付金额中店铺是维度,近1天是一个时间类型的修饰词,支付金额是一个原子指标。
业务方制作每一个派生指标都是通过选择维度,原子指标,修饰词三种元数据来定义的,相对于使用名称来区别不同指标,更可以保证指标的唯一性。 如果2个派生指标是不同的,那他们的组成部分一定会有区别,或是不同维度,或是不同原子指标,修饰词。
所以在指标管理的过程中,指标库给予每个指标一个精确且唯一的定义。通过指标库可以快速且规范的查询,开发和使用指标。
指标库主要提供如下服务: