数仓
数仓是一个面向主题的、集成的、稳定的、时变的,存储历史数据的仓库。
面向主题的
:数仓中的数据按照主题进行存储,每个主题都是决策层分析的一个角度;
集成的
:不同来源的数据会统一整合后存入数仓中;
稳定的
:数据一旦进入仓库后不会轻易发生改变,就算数据本身需要变化也轻易不会改动原数据,会根据分析需求考虑数据的更新策略;
时变的
:随着时间的推移,长时间不更新的数据会逐渐失去时效性,失去时效性的数据一般会被导出到外部压缩存储。目前常用的策略是"7年13个月",即保存维度信息的拉链表不保存七年前的数据,保存流水信息的事实表不保存13个月前的数据。
当然,上述保存策略也是根据情况决定,利用价值较低的原始数据可能只保存一个周期就被导出,高度聚合的数据可能保存更长的时间。
1. 数据分层
数仓往往分为三层,ods、dw、dm,而dw层又可以根据业务细分为dwd、dws、dwa等多层.
1.1 ods层
操作型数据层,存放的是从不同来源进入数仓的原始数据,ods层往往只存放少量加工的原始.数据,因此这里的数据不是集成的。
1.2 dw层
数据仓库的核心,它根据数仓架构可能再次细分多层:
1.2.1 dwd层
数据细节层。将ods层的数据统一整合后,依照各
主题需要将数据拆分存储,常见的星型模型和雪花模型就是在这一层。
1.2.2 dws层
数据服务层。按照范式存储的数据在分析时往往需要进行多表join,这样的分析效率很低,因此需要将dwd层的数据按照分析需求提前进行整合。由于主题之间的重合,该层的设计是反三范式的,存在数据冗余。
除了上述分层以外,dw还有基础数据层、轻度汇总层等等,根据数仓架构而定。
1.2.3 dim层
维度层。有些数仓会将dwd层中的维度表单独抽离出来维护。
以上 ODS 层和 dw(EDS) 层使用 Spark 代码处理数据,然后利用 SparkSQL 读取 ODS 层数据,保存到 Hive 的 EDS 层。
1.3 dm层
存放使用DW层数据进行业务统计的结果,它们可能被用于线上可视化的指标分析,也可能用于进一步的数据挖掘使用。
DM 层的数据有一部分是存储在 Hive 表中,或者保存分析结果到 MySQL、HBase 等。
分层作用:复杂问题简单化、减少重复计算、血缘追踪、架构更清晰
EDS(DW) 层数据是 parquet 格式的数据,放在 Hive 的主要原因是后期使用 Kylin 查询一些业务,数据放 MySQL 的都是结果数据,放在 HBase 的原因是设涉及到大表的明细查询。
2. 表的种类和特征
事务事实表:可以看做是保存某一事务的日志数据,事务一旦被提交就成为历史数据,只能以增量的方式维护。
维度表:从某个角度观察事实数据的窗口,存储的数据用来从某个角度描述事实。
全量表:保存每天所有的最新状态的数据
增量表:当数据改变时,将这个改变和改变后的结果记录下来,就是增量表。(a账户分两次存了100块,增量表显示为a账户金额100,200,并分别记录变化时间)
拉链表:用特定字段维护缓慢变化维度的表
流水表:记录表中所有改变的表。
周期快照表:按固定周期对事实表进行统计生成的表,按时间段保存记录,增量更新。
3. 拉链表
使用SCD策略维护特定字段实现。SCD1:不保存历史数据,直接覆盖更新SCD2:通过维护一个记录时间和一个过期时间来保存变化历史,增量更新SCD3:通过维护一个历史字段来保存上次的数据,更新数据时,先检查旧数据是否存在,如果存在就把旧数据的最新值保存到新数据的旧值字段,采用覆盖更新的方式存储数据。SCD4:单独建立一个历史维度表为该字段维护历史变化。SCD5:混合使用123的维护策略。
4. 数据建模
4.1 业务建模
这部分建模工作,主要包含以下几个部分:
- 划分整个单位的业务,一般按照业务部门的划分,进行各个部分之间业务工作的界定,理清各业务部门之间的关系。
- 深入了解各个业务部门的内具体业务流程并将其程序化。 提出修改和改进业务部门工作流程的方法并程序化。
- 数据建模的范围界定,整个数据仓库项目的目标和阶段划分。
根据业务部门进行划分,理清部门之间的关系,然后将各个部门的具体业务程序化,与业务部门开会协商出需求的指标、保存年限、维度等等。总体来讲,就是要知道他们需要哪些指标以及他们能提供哪些数据。业务建模的时间最长,而且与公司实际的业务环境息息相关
,因此在这里需要根据实际生产环境和业务需求确认好数据仓库使用的工具和平台。
4.2 领域概念建模
这部分得建模工作,主要包含以下几个部分:
- 抽取关键业务概念,并将之抽象化。
- 将业务概念分组,按照业务主线聚合类似的分组概念。
- 细化分组概念,理清分组概念内的业务流程并抽象化。
- 理清分组概念之间的关联,形成完整的领域概念模型。
将业务模型抽象化,分组合并类似的概念,细化概念,抽象出实体与实体之间的联系,理清各组概念之间的联系。说白了就是画图
,把指标需要的哪些数据封装到一个实体里,实体与实体之间的关联等等用ER图表示出来。先画出局部ER图,最后再综合画出全局ER图
。
4.3 逻辑建模
这部分的建模工作,主要包含以下几个部分:
- 业务概念实体化,并考虑其具体的属性
- 事件实体化,并考虑其属性内容
- 说明实体化,并考虑其属性内容
将概念模型实体化,具体考虑概念对应的属性,事件考虑事实属性,维度考虑维度属性。总体来说就是建表
,前面已经画出了关系图,这里只要将表里头有哪些字段考虑出来就可以,如果是事实表就考虑事实字段和业务主键,如果是维度表就考虑维度属性,SCD策略等等。在这里需要确定数据粒度,如果多个指标都用到一个字段,则取粒度最小的指标。如果不确定指标的量度,则取毫秒级作为粒度。
4.4 物理建模
综合现实的大数据平台、采集工具、etl工具、数仓组件、性能要求、管理要求等多方面因素,设计出具体的项目代码,完成数仓的搭建。
- 针对特定物理化平台,做出相应的技术调整
- 针对模型的性能考虑,对特定平台作出相应的调整
- 针对管理的需要,结合特定的平台,做出相应的调整
- 生成最后的执行脚本,并完善之。
5. 数据模型
5.1 星型模型
数仓(具体说是dwd层)中只有一张包含历史数据且不冗余的事实表和一组附属维度表,每个维度一张。事实表与维度表之间通过外键和主键关联。星型模型的维度表可能存在冗余,因此是反三范式的,这种模型在数据维护上较麻烦,但是性能更高,业界普遍使用星型模型。星型模型的难点在于拉链表的维护,拉链表一般不能有冗余。
5.2 雪花模型
针对星型模型的维度表进行扩展的模型,将维度表拆解成维度表+说明表,说明表又可以进一步拆分,最终形成事实表-维度表-说明表的多次连接。雪花模型的表一般遵循三范式,在数据的维护上会很方便,但是多表join影响性能。
5.3 星系模型
多个事实表采用星型模型共享维度表,就形成了一个星系。
5.4 Data Vault模型
从上述模型中我们不难看出,如果解决了拉链表的维护问题,星型模型的缺陷就已经可以忽略。Data Vault模型由中心表、链接表、附属表、PIT表组成,这里的中心表,事实上就是维度表,链接表就是事实表、附属表是拉链表。Data Vault模型就是通过将拉链表从维度表中分离出来,来达到方便维护的目的。首先,中心表是一组业务生命周期内绝不会变的维度表,打个比方就是java里头的常量,常量再怎么冗余也不会有影响。链接表则是保存流水类数据的事实表,它通过外键与多张中心表连接,但不会连接附属表。附属表则是从维度表中抽出来的可能会发生变化的字段或表,这一部分就采用拉链表的方式创建,中心表则通过外键关联附属表的主键。
从同一维度表拆出来的字段根据变化维度不同可能还要分成多表存储,为了避免时效不一致,所以还会建立一张PIT表,用于维护附属表的变化历史。中心表通过外键与PIT表相连,而PIT表则为每个附属表的主键都准备了一个时间字段保存数据的更新时间。
6. 建模方法
6.1 范式建模法(ThirdNormal Form,3NF)
- 每个属性值唯一,不具有多义性 ;
- 每个非主属性必须完全依赖于整个主键,而非主键的一部分 ;
- 每个非主属性不能依赖于其他关系中的属性,因为这样的话,这种属性应该归到其他关系中去。
范式是基于整个关系型数据库的理论基础之上发展而来的
优点:从关系型数据库的角度出发,结合了业务系统的数据模型,能够比较方便的实现数据仓库的建模。
缺点:由于建模方法限定在关系型数据库之上,在某些时候反而限制了整个数据仓库模型的灵活性,性能等,特别是考虑到数据仓库的底层数据向数据集市的数据进行汇总时,需要进行一定的变通才能满足相应的需求。
6.2 维度建模法
按照事实表,维表来构建数据仓库,数据集市。这种方法的最被人广泛知晓的名字就是星型模式(Star-schema)。
优点:针对3NF 的建模方法,星型模式在性能上占据明显的优势。
非常直观,紧紧围绕着业务模型,可以直观的反映出业务模型中的业务问题。不需要经过特别的抽象处理,即可以完成维度建模。
缺点:由于在构建星型模式之前需要进行大量的数据预处理,因此会导致大量的数据处理工作。而且,当业务发生变化,需要重新进行维度的定义时,往往需要重新进行维度数据的预处理。而在这些与处理过程中,往往会导致大量的数据冗余。
如果只是依靠单纯的维度建模,不能保证数据来源的一致性和准确性,而且在数据仓库的底层,不是特别适用于维度建模的方法。
维度建模的领域主要适用与数据集市层,它的最大的作用其实是为了解决数据仓库建模中的性能问题。维度建模很难能够提供一个完整地描述真实业务实体之间的复杂关系的抽象方法
。
6.4 3.实体建模法
实体建模法并不是数据仓库建模中常见的一个方法,它来源于哲学的一个流派。从哲学的意义上说,客观世界应该是可以细分的,客观世界应该可以分成由一个个实体,以及实体与实体之间的关系组成。那么我们在数据仓库的建模过程中完全可以引入这个抽象的方法,将整个业务也可以划分成一个个的实体,而每个实体之间的关系,以及针对这些关系的说明就是我们数据建模需要做的工作。
虽然实体法粗看起来好像有一些抽象,其实理解起来很容易。即我们可以将任何一个业务过程划分成3 个部分,实体,事件和说明,如下图所示:
上图表述的是一个抽象的含义,如果我们描述一个简单的事实:“小明开车去学校上学”。以这个业务事实为例,我们可以把“小明”,“学校”看成是一个实体,“上学”描述的是一个业务过程,我们在这里可以抽象为一个具体“事件”,而“开车去”则可以看成是事件“上学”的一个说明。
使用的抽象归纳方法其实很简单,任何业务可以看成3 个部分:
实体
,主要指领域模型中特定的概念主体,指发生业务关系的对象。
事件
,主要指概念主体之间完成一次业务流程的过程,特指特定的业务过程。
说明
,主要是针对实体和事件的特殊说明。
由于实体建模法,能够很轻松的实现业务模型的划分,因此,在业务建模阶段和领域概念建模阶段,实体建模法有着广泛的应用。从笔者的经验来看,在没有现成的行业模型的情况下,我们可以采用实体建模的方法,和客户一起理清整个业务的模型,进行领域概念模型的划分,抽象出具体的业务概念,结合客户的使用特点,完全可以创建出一个符合自己需要的数据仓库模型来。
实体建模法也有着自己先天的缺陷,由于实体说明法只是一种抽象客观世界的方法,因此,注定了该建模方法只能局限在业务建模和领域概念建模阶段。因此,到了逻辑建模阶段和物理建模阶段,则是范式建模和维度建模发挥长处的阶段。
在创建自己的数据仓库模型的时候,可以参考使用上述的三种数据仓库得建模方法,在各个不同阶段采用不同的方法,从而能够保证整个数据仓库建模的质量。
7. 数据库和数据仓库区别
操作上:数据库是面向事务的,往往是行级操作;数仓则是面向分析的,往往是范围操作功能上:数据库提供即时的增删改查,数仓则寻求的是分析数据提供决策支持设计上:数据库基于ER模型,面向业务;数仓基于星型/雪花模型,面向主题数据上:数据库只保存最新的、近期的数据;数仓则保存所有数据性能上:数据库往往依靠索引快速返回;数仓则往往需要大范围磁盘扫描数据量:数据库数据一般为GB级别,数仓的数据则往往上百TB响应速度:数据库是毫秒级,数仓任务的执行时间往往数小时存储上:数据库是真实的物理存储,数仓则是逻辑存储。
8 数据仓库流程
具体数仓甚至数据治理方面可以参考下图
按照数仓分层思想,分为ods贴源层、dw主题层、mid维表层、dm集市层、app应该层
过程如下:
1 数据通过采集或同步落地基于HDFS存储的ods层
2 主题抽取确认
3 如果有此需求,构建基于主题数据的微聚合结果
4 构建维表层数据,如时间、地区、产品类别等数据
5 进行数据集市构建如统计结果、用户画像、TopN热门数据
6 进行集市数据的输出到app进行BI可视化展示