数据仓库概念创始人在《建立数据仓库》一书中对数据仓库的定义是:数据仓库(Data Warehouse)是一个面向主题的(Subject Oriented)、数据集成的(Integrated)、相对稳定(非易失)的(Non-Volatile)、反映历史变化(时变)(Time Variant)的数据集合,用于支持管理决策(Decision Making Support)。
数据仓库是决策支持系统(dss)的结构化数据环境,如下图,决策支持系统基于数据仓库进行联机分析处理 ( OLAP ) 。常用的技术有,HDFS、HBase、Hive、SparkSql,Filnk等。
数据采集, 将源数据采集到数据仓库
基于数据仓库进行数据分析
生成报表
OLTP(On-Line Transaction Processing)即联机事务处理,也称为面向交易的处理过程,其基本特征是前台接收的用户数据可以立即传送到计算中心进行处理,并在很短的时间内给出处理结果,是对用户操作快速响应的方式之一,比如ERP系统,CRM系统,互联网电商系统等,这类系统的特点是事务操作频繁,数据量小。
OLAP(On-Line Analytical Processing)即联机分析处理,有时也称为决策支持系统(DSS),支持复杂的分析操作,侧重决策支持,并且提供直观易懂的查询结果。这类系统的特点是没有事务性操作,主要是查询操作,数据量大。
详细的区别如下:
对比项目 | OLTP | OLAP |
---|---|---|
功能 | 面向交易的事务处理 | 面向分析查询 |
设计 | 面向业务 | 面向主题 |
数据 | 最新数据,二维数据 | 历史数据,多维数据 |
存储 | M,G ( 存储单位 ) | T、P、E |
响应时间 | 快 | 慢 |
用户 | 业务操作人员 | 管理决策人员 |
理解主题的概念可以和数据库应用系统对比理解。
数据库应用是以业务流程来划分应用程序和数据库,比如ERP(Enterprise Resource Planning)包括:进销存系统、人力资源管理系统、财务管理系统、仓库管理系统等,进销存系统管理了进货、销售、存储等业务流程,人力资源系统管理了员工的信息、待遇等相关信息。
数据仓库是以数据分析需求来对数据进行组织划分若干主题,比如销售主题、员工主题、产品主题,主题是一个抽象的概念,可以理解为相关数据的分类、目录等,通过销售主题可以进行销售相关的分析,如年度销量排行、月度订单量统计等。
总之,主题是以分析需求为导向来组织数据,数据库应用系统是以业务流程为导向来组织数据,注意:主题中的数据是跨应用系统的。
主题中的数据是跨应用系统的,也就是说数据是分散在各各应用系统中的,比如销售数据在进销存系统中有,财务系统中也有,为了进行销售分析需要将销售数据进行集成,集成在销售主题中,就可以从销售主题来进行数据分析。
数据库应用系统是根据业务需求进行数据处理和存储,而数据仓库是根据数据分析需求来进行数据存储,数据仓库中的数据用于查询和分析,为了保证数据分析的准确性和稳定性,数据仓库中的数据一般是很少更新的,一般情况下都会将历史快照保存下来。
数据仓库中的数据存储的是历史数据,历史数据是随时间变化的,比如历年的销售数据都会存储到数据仓库中,即使数据仓库中的数据很少更新,但也不能保证没有变化,如下需求:
每年的销售数据会逐渐添加到数据仓库。
数据仓库中的数据会保存很长的时间(5–10年),但也有过期时间,到过期时间会删除过期数据。
为了方便数据分析,根据分析需求会将比较细粒度的数据进行数据聚合存储,这也是时变的一种表现,比如:为了方便统计年度销售额会将销售记录按月进行统计,统计年度销售额时只需要针对月度销售结果进行统计即可。
数据仓库提供企业决策分析的数据环境,数据从哪里获取?数据如何存储到数据仓库?决策分析系统如何从数据仓库获取数据进行分析?我们可以把数据从获取、存储到数据仓库、数据分析的所有部分称为一个数据仓库系统,在这里主要说的是数据仓库系统的工作流程和系统架构。
下图是数据仓库系统的结构图:
以上系统各部分的执行流程是:
确定分析所依赖的源数据。
通过ETL将源数据采集到数据仓库。
数据按照数据仓库提供的主题结构进行存储。
根据各部门的业务分析要求创建数据集市(数据仓库的子集)。
决策分析、报表等应用系统从数据仓库查询数据、分析数据。
用户通过应用系统查询分析结果、报表。
源数据是指用于分析的原始数据,这一步主要是根据分析需求确定源数据,这个数据分布在内部系统和外部分系统中,内部数据主要是企业ERP系统、外部数据是指企业外部分系统所产生的数据,通常是指行业数据。源数据最大的特点是格式不统一,如果要对源数据进行分析需要经过ETL对数据进行集中获取、过虑、转换等处理。
ETL(Extra, Transfer, Load)包括数据抽取、数据转换、数据装载三个过程。
抽取
数据抽取是从各各业务系统、外部系统等源数据处采集源数据。
转换
采集过来的源数据如果要存储到数据仓库需要按照一定的数据格式对源数据进行转换,常见的转换方式有数据类型转换、格式转换、缺失值补充、数据综合等。
装载
转换后的数据就可以存储到数据仓库中,这个过程要装载。数据装载通常是按一定的频率进行的,比如每天装载当天的订单数据、每星期装载客户信息等。
**数据仓库是用于企业整体分析的数据集合,**比如分为:销售主题、客户主题、产品主题等。**数据集市是用于部门分析的数据集合,**从范围上来讲它属于数据仓库的子集,比如:销售部门的数据集市只有销售主题。
为什么会有数据集市的概念?
通常从企业整体出发去建数据仓库比较困难,所涉及到的业务及分析需求比较多,所以提出数据集市的概念,可以先从某个部门开始建设数据仓库,这样效率就比较高。
业界把从企业整体出发建设数据仓库的过程叫自顶向下,把从数据集市开始建设数据仓库再逐渐完善整个数据仓库的过程叫自下向上。通常建议自下向上建设数据仓库,不过呢,到底应该怎么建设,这个在业界也存在一些争议。
数据仓库和数据集市具有什么区别?
范围的区别
数据仓库是针对企业整体分析数据的集合。
数据集市是针对企业中各个部门级别分析的数据集合。
数据粒度不同
数据仓库通常包括粒度较细的数据明细。
数据集市则会在数据仓库的基础上进行数据聚合,这些聚合后的数据就会直接用于部门业务分析(宽表)。
这里的应用系统是指使用数据仓库完成数据分析、数据查询、数据报表等功能的系统。应用系统需要从数据仓库中查询数据、分析数据,比如:OLAP 系统、数据查询系统等。
使用数据仓库系统的用户主要有数据分析人员、管理决策人员(公司高层)等。
对数据进行分析通常采取维度分析,比如:线上教育机构的用户提出分析课程访问量的指标,为了满足不同的分析需求可以从时间维度分析课程访问量,分析每天、每小时的课程访问量;也可以从课程维度来分析课程访问量,分析每个课程、每个课程分类的访问量。
要进行维度分析需要先理解两个术语:指标和维度。
指标
纬度
维度是事务的特征,如颜色、区域、时间等,可以根据不同的维度来对指标进行分析对比。比如根据区域维度来分析不同区域的产品销量,根据时间来分析每个月产品的销量,同一个产品销量指标从不同的维度分析会得出不同的结果。
维度分为定性维度和定量维度两种,
用具体的指标数值, 来度量不同的维度。他俩的关系就像是坐标系中x轴和y轴的关系。
在日常生活中,我们从不同的角度看待事物会有不同的体会,数据分析也如此,比如:一个在线教育的平台,作为运营方会关注按时间段分析课程的访问量,作为教育机构则关注单个课程的访问量,都是课程访问量指标根据不同的维度去分析得到结果不同,这就是维度分析。
比如:按时间分析课程访问量,时间维度是课程访问量的分析依据,时间维度和业务中的课程访问量是对应的,下表列出了课程访问量明细记录:
IP | 访问时间 | 课程ID |
---|---|---|
127.0.0.1 | 2019-10-01 00:00:00 | 10010 |
127.0.0.1 | 2019-10-01 01:00:00 | 10011 |
127.0.0.1 | 2019-10-01 02:00:00 | 10011 |
上表中显示了部分课程访问的记录,每条记录表示一次课程访问,记录内容包括:IP,访问时间、课程ID,根据上边的记录可以按时间统计每天所有课程的访问量,时间就是 一个维度,如下是按时间维度分析的课程访问量:
时间维度(天)
时间(天) | 课程访问量 |
---|---|
2019-10-01 | 10000 |
2019-10-02 | 9000 |
2019-10-03 | 11000 |
… | … |
维度是数据仓库建模的基础,维度是在分析时从多个方面来进行分析,根据上边的例子,将课程访问量作为度量,识别的维度主要是时间。
在真实的统计需求中,识别的维度除了时间外,还可能包括:课程、机构(校区)、学科(课程分类)等,如下图:
将课程购买量作为度量的维度可能包括:
通常在分析结果中首先看到的是一个总数,比如全年课程购买量,然后会详细去看每个季度、每个月的课程购买量,全年、季度、月这些属于时间维度的一个层次,年、季度、月是这个层次的三个级别;再比如按地区分析课程购买量,全国、省、市、县属于地区维度的一个层次,层次中共有四个级别。
相当于将维度进行细分。细分两层,则维度包含一个层次,多个级别。 细分三层,则维度包含多个层次,多个级别。
每个维度至少有一个层次且该层次至少有一个级别。
实体:
实体是指依附的主体,就是我们分析的一个对象,比如我们分析商品的销售情况, 如华为手机近半年的销售量是多少,那华为手机就是一个实体;我们分析用户的活跃度,用户就是一个实体。当然实体也可以现实中不存在的,比如虚拟的业务对象,活动,会员等都可看做一个实体。
实体的存在是为了业务分析,作为分析的一个筛选的维度,拥有描述自己的属性, 本身具有可分析的价值。
纬度
度量
度量是业务流程节点上的一个数值。比如销量,价格,成本等等。
事实表中的度量可分为三类:完全可加,半可加,不可加。
粒度
粒度是业务流程中度量的单位,比如商品是按件记录度量,还是按批记录度量。
在数仓建设中,我们说这是用户粒度的事实表,那么表中每行数据都是一个用户, 无重复用户;例如还有销售粒度的表,那么表中每行都是一条销售记录。
选择合适的粒度级别是数据仓库建设好坏的重要关键内容,在设计数据粒度时,通常需重点考虑以下因素:
口径
口径就是取数逻辑(如何取数的),比如要取的数是 10 岁以下儿童中男孩的平均身高,这就是统计的口径
指标
指标是口径的衡量值,也就是最后的结果。比如最近七天的订单量,一个促销活动的购买转化率等。 一个指标具体到计算实施,主要有以下几部分组成:
指标加工逻辑,比如 count ,sum, avg
维度,比如按部门、地域进行指标统计,对应 sql 中的 group by
业务限定/修饰词,比如以不同的支付渠道来算对应的指标,微信支付的订单退款率,支付宝支付的订单退款率 。对应 sql 中的 where。
除此之外,指标本身还可以衍生、派生出更多的指标,基于这些特点,可以将指标进行如下分类:
原子指标:基本业务事实,没有业务限定、没有维度。比如订单表中的订单量、订单总金额都算原子指标;
业务方更关心的指标,是有实际业务含义,可以直接取数据的指标。比如店铺近 1天订单支付金额就是一个派生指标,会被直接在产品上展示给商家看。但是这个指标却不能直接从数仓的统一中间层里取数据(因为没有现成的事实字段,数仓提供的一般都是大宽表)。需要有一个桥梁连接数仓中间层和业务方的指标需求,于是便有了派生指标
派生指标:维度+修饰词+原子指标。 店铺近 1 天订单支付金额中店铺是维度,近 1 天是一个时间类型的修饰词,支付金额是一个原子指标;
维度:观察各项指标的角度;
修饰词:维度的一个或某些值,比如维度性别下,男和女就是 2 种修饰词。
衍生指标:比如某一个促销活动的转化率就是衍生指标,因为需要促销投放人数指标和促销订单数指标进行计算得出。
标签
标签是人为设定的、根据业务场景需求,对目标对象运用一定的算法得到的高度 精炼的特征标识。可见标签是经过人为再加工后的结果,如网红、白富美、萝莉。 对于有歧义的标签,我们内部可进行标签区分,比如:苹果,我们可以定义苹果指的是水果,苹果手机才指的是手机。
自然键
由现实中已经存在的属性组成的键,它在业务概念中是唯一的,并具有一定的业 务含义,比如商品 ID,员工 ID,学号等。
以数仓角度看,来自于业务系统的标识符就是自然键,比如业务库中员工的编号。
持久建
保持永久性不会发生变化。有时也被叫做超自然持久键。比如身份证号属于持久键。
自然键和持久键区别:举个例子就明白了,比如说公司员工离职之后又重新入职,他的自然键也就是员工编号发生了变化,但是他的持久键身份证号是不变的。
代理键
就是不具有业务含义的键。代理键有许多其他的称呼:无意义键、整数键、非自然键、人工键、合成键等。
代理键就是简单的以按照顺序序列生产的整数表示。产品行的第 1 行代理键为 1, 则下一行的代理键为 2,如此进行。
代理键的作用仅仅是连接维度表和事实表。
退化纬度
退化维度,就是那些看起来像是事实表的一个维度关键字,但实际上并没有对应的维度表,就是维度属性存储到事实表中,这种存储到事实表中的维度列被称为退化维度。与其他存储在维表中的维度一样,退化维度也可以用来进行事实表的过滤查询、实现聚合操作等。
那么究竟怎么定义退化维度呢?
比如说订单 id,这种量级很大的维度,没必要用一张维度表来进行存储,而我们进行数据查询或者数据过滤的时候又非常需要,所以这种就冗余在事实表里面,这种就叫退化维度,citycode 这种我们也会冗余在事实表里面,但是它有对应的维度表,所以它不是退化维度。
下钻
这是在数据分析中常见的概念,下钻可以理解成增加维的层次,从而可以由粗粒度到细粒度来观察数据,比如对产品销售情况分析时,可以沿着时间维从年到月 到日更细粒度的观察数据。从年的维度可以下钻到月的维度、日的维度等
上卷
知道了下钻,上卷就容易理解了,它俩是相逆的操作,所以上卷可以理解为删掉维的某些层,由细粒度到粗粒度观察数据的操作或沿着维的层次向上聚合汇总数据
在 Kimball 维度建模中有维度与事实,在 Inmon 范式建模中有实体与关系,如果我们分开两种建模方式看这些概念比较容易理解。但是目前也出现了不少混合建模方式,两种建模方式结合起来看,这些概念是不是容易记忆混乱,尤其事实表和实体表,它们之间到底有怎样区别与联系,先看下它们各自概念:
维度表:维度表可以看成是用户用来分析一个事实的窗口,它里面的数据应该是对事实的各个方面描述,比如时间维度表,地域维度表,维度表是事实表的一个分析角度。
事实表:事实表其实就是通过各种维度和一些指标值的组合来确定一个事实的,比如通过时间维度,地域组织维度,指标值可以去确定在某时某地的一些指标值怎么样的事实。事实表的每一条数据都是几条维度表的数据和指标值交汇而得到的。
实体表:实体表就是一个实际对象的表,实体表放的数据一定是一条条客观存在的事物数据,比如说各种商品,它就是客观存在的,所以可以将其设计一个实体表。实时表只描述各个事物,并不存在具体的事实,所以也有人称实体表是无事实的事实表。
举个栗子:比如说手机商场中有苹果手机,华为手机等各品牌各型号的手机,这 些数据可以组成一个手机实体表,但是表中没有可度量的数据。某天苹果手机卖了 15 台,华为手机卖了 20 台,这些手机销售数据属于事实,组成一个事实表。
这样就可以使用日期维度表和地域维度表对这个事实表进行各种维度分析。
概念不同
指标是用来定义、评价和描述特定事物的一种标准或方式。比如:新增用户数、累计用户数、用户活跃率等是衡量用户发展情况的指标;
标签是人为设定的、根据业务场景需求,对目标对象运用一定的算法得到的高度精炼的特征标识。可见标签是经过人为再加工后的结果,如网红、白富美、萝莉。
构成不同
指标名称是对事物质与量两方面特点的命名;指标取值是指标在具体时间、地域、条件下的数量表现,如人的体重,指标名称是体重,指标的取值就是 120 斤;
标签名称通常都是形容词或形容词+名词的结构,标签一般是不可量化的,通常是孤立的,除了基础类标签,通过一定算法加工出来的标签一般都没有单位和量纲。如将超过 200 斤的称为大胖子。
分类不同
对指标的分类:
按照指标计算逻辑,可以将指标分为原子指标、派生指标、衍生指标三种类型;
按照对事件描述内容的不同,分为过程性指标和结果性指标;
对标签的分类:
按照标签的变化性分为静态标签和动态标签;
按照标签的指代和评估指标的不同,可分为定性标签和定量标签;
指标最擅长的应用是监测、分析、评价和建模。
标签最擅长的应用是标注、刻画、分类和特征提取。
特别需要指出的是,由于对结果的标注也是一种标签,所以在自然语言处理和机器学习相关的算法应用场景下,标签对于监督式学习有重要价值,只是单纯的指标难以做到的。而指标在任务分配、绩效管理等领域的作用,也是标签无法做到的。
维度就是数据的观察角度,即从哪个角度去分析问题,看待问题。指标就是从维度的基础上去衡算这个结果的值。
维度一般是一个离散的值,比如时间维度上每一个独立的日期或地域,因此统计时,可以把维度相同记录的聚合在一起,应用聚合函数做累加、均值、最大值,最小值等聚合计算。
指标就是被聚合的通计算,即聚合运算的结果,一般是一个连续的值。
数仓工具箱中说维度表的唯一主键应该是代理键而不应该是自然键。有时建模人员不愿意放弃使用自然键,因为他们希望与操作型代码查询事实表,而不希望与维度表做连接操作。然而,应该避免使用包含业务含义的多维键,因为不管我们做出任何假设最终都可能变得无效,因为我们控制不了业务库的变动。
所以数据仓库中维度表与事实表的每个连接应该基于无实际含义的整数代理键。避免使用自然键作为维度表的主键。
数据仓库建模的方法常用的有两种:范式建模法、维度建模法,实体建模法,三范式建模法主要是应用于传统的企业级数据仓库,这类数据仓库通常使用关系型数据库实现,是由Inmon提出的,应用于自顶向下的数据仓库架构; 维度数据模型就是基于维度分析来创建模型,是由Kimball提出,应用于自下向上的数据仓库架构。
范式建模法其实是我们在构建数据模型常用的一个方法,该方法的主要由 Inmon所提倡,主要解决关系型数据库的数据存储,利用的一种技术层面上的方法。目前,我们在关系型数据库中的建模方法,大部分采用的是三范式建模法。
范式是符合某一种级别的关系模式的集合。构造数据库必须遵循一定的规则, 而在关系型数据库中这种规则就是范式,这一过程也被称为规范化。目前关系数据库有六种范式:第一范式(1NF)、第二范式(2NF)、第三范式(3NF)、Boyce-Codd 范式(BCNF)、第四范式(4NF)和第五范式(5NF)。
在数据仓库的模型设计中,一般采用第三范式。一个符合第三范式的关系必须具有以下三个条件 :
每个属性值唯一,不具有多义性 ;
每个非主属性必须完全依赖于整个主键,而非主键的一部分 ;
每个非主属性不能依赖于其他关系中的属性,因为这样的话,这种属性应该归到其他关系中去。
根据 Inmon 的观点,数据仓库模型的建设方法和业务系统的企业数据模型类似。在业务系统中,企业数据模型决定了数据的来源,而企业数据模型也分为两个层次,即主题域模型和逻辑模型。同样,主题域模型可以看成是业务模型的概念模 型,而逻辑模型则是域模型在关系型数据库上的实例化。
维度模型是数据仓库领域另一位大师 Ralph Kimall 所倡导,他的《数据仓库工具箱》是数据仓库工程领域最流行的数仓建模经典。维度建模以分析决策的需求出发构建模型,构建的数据模型为分析需求服务,因此它重点解决用户如何更快速完成分析需求,同时还有较好的大规模复杂查询的响应性能。
典型的代表是我们比较熟知的星形模型(Star-schema),以及在一些特殊场景 下适用的雪花模型(Snow-schema)。
维度建模中比较重要的概念就是 事实表(Fact table)和维度表(Dimension table)。其最简单的描述就是,按照事实表、维度表来构建数据仓库、数据集市。
实体建模法并不是数据仓库建模中常见的一个方法,它来源于哲学的一个流派。从哲学的意义上说,客观世界应该是可以细分的,客观世界应该可以分成由一个个实体,以及实体与实体之间的关系组成。那么我们在数据仓库的建模过程中完全可以引入这个抽象的方法,将整个业务也可以划分成一个个的实体,而每个实体之间的关系,以及针对这些关系的说明就是我们数据建模需要做的工作。虽然实体法粗看起来好像有一些抽象,其实理解起来很容易。即我们可以将任何一个业务过程划分成 3 个部分,实体,事件,说明,如下图所示:
维度建模分为两种表:事实表和维度表:
事实表:必然存在的一些数据,像采集的日志文件,订单表,都可以作为事实表 。
特征:是一堆主键的集合,每个主键对应维度表中的一条记录,客观存在的,根据主题确定出需要使用的数据
维度表:维度就是所分析的数据的一个量,维度表就是以合适的角度来创建的表,分析问题的一个角度:时间、地域、终端、用户等角度。
事实表记录了特定事件的数字化信息,一般由数值型数字和指向维度表的外键组成。
事实表的设计依赖于业务系统,事实表的数据就是业务系统的指标数据。数据分析的实质就是基于事实表开展的计算操作。
事务事实表与周期快照事实表、累积快照事实表使用相同的维度,但是它们在描述业务事实方面是有着非常大的差异的。
事务事实表记录的事务层面的事实,保存的是最原子的数据,也称“原子事实表”或“交易事实表”。事务事实表中的数据在事务事件发生后产生,数据的粒度通常是每个事务一条记录。一旦事务被提交,事实表数据被插入,数据就不再进行更改,其更新方式为增量更新。
事务事实表的日期维度记录的是事务发生的日期,它记录的事实是事务活动的内容。用户可以通过事务事实表对事务行为进行特别详细的分析。
沟通中常说的事实表,大多指的是事务事实表。
周期快照事实表以具有规律性的、可预见的时间间隔来记录事实,时间间隔如每天、每月、每年等等。典型的例子如销售日快照表、库存日快照表等。
想象以下场景,需要统计一个季度的商品成交量要怎么去做呢?如果用一个季度内的事实事务表进行计算,虽然可以得出结果但是效率太低,在实际生产中并不可行,因此,需要定期对指定的度量进行整合,作为周期快照表用于下游应用。一般设计事实表时,事务事实表和周期快照表是成对设计的,大部分的周期表由事务表加工产生,还有部分特殊数据是直接应用系统产生(如订单评价)。
周期快照事实表的粒度是每个时间段一条记录,通常比事务事实表的粒度要粗,是在事务事实表之上建立的聚集表。比如说时间周期是1周,那么这个周期快照事实表的一条记录就是这一周的对于某个度量的统计值。周期快照事实表的维度个数比事务事实表要少。
周期快照事实表的日期维度通常是记录时间段的终止日,记录的事实是这个时间段内一些聚集事实值。事实表的数据一旦插入即不能更改,其更新方式为增量更新。
累积快照事实表和周期快照事实表有些相似之处,它们存储的都是事务数据的快照信息。但是它们之间也有着很大的不同,周期快照事实表记录的确定的周期的数据,而累积快照事实表记录的不确定的周期的数据。
累积快照事实表代表的是完全覆盖一个事务或产品的生命周期的时间跨度,它通常具有多个日期字段,用来记录整个生命周期中的关键时间点。例如订单累计快照事实表会有付款日期,发货日期,收货日期等时间点。
事务事实表中一个完整的交易记录会有一系列不同状态的数据来记录整个交易过程;而累积快照事实表只会有一条记录,数据会一直更新直到过程结束。
累积快照事实表代表的是完全覆盖一个事务或产品的生命周期的时间跨度,它通常具有多个日期字段,用来记录整个生命周期中的关键时间点。另外,它还会有一个用于指示最后更新日期的附加日期字段。
由于事实表中许多日期在首次加载时是不知道的,所以必须使用代理关键字来处理未定义的日期,而且这类事实表在数据加载完后,是可以对它进行更新的,来补充随后知道的日期信息。
举例来说:订货日期、预定交货日期、实际发货日期、实际交货日期、数量、金额、运费。
特点 | 事务事实 | 周期快照事实 | 累积快照事实 |
---|---|---|---|
时间/时期 | 时间 | 时期 | 时间跨度较短的多个时点 |
粒度 | 每行代表一个事务事件 | 每行代表一个时间周期 | 每行代表一个业务周期 |
事实表加载 | 新增 | 新增 | 新增和修改 |
事实表更新 | 不更新 | 不更新 | 新事件产生时更新 |
时间维 | 业务日期 | 时期末 | 多个业务过程的完成日期 |
事实 | 事务活动 | 时间周期内的绩效 | 限定的多个业务阶段内的绩效 |
维度是指观察数据的角度,一般是一个名词,比如对于销售金额这个事实,我们可以从销售时间、销售产品、销售店铺、购买顾客等多个维度来观察分析。
维度表的记录数比事实表少,但是每条记录可能会包含很多字段。
主要包含两大类数据:
高基数维度数据:一般是用户资料表、商品资料表类似的资料表。数据量可能是千万级或者上亿级别。
低基数维度数据:一般是配置表,比如枚举值对应的中文含义,或者日期维表、地理维表等。数据量可能是个位数或者几千条几万条。
基数指的是一个字段中不同值的个数,比如主键列具有唯一值,所以具有最高的基数,而性别枚举值(日期、地区等)这样的列的基数就很低。
时间维度表
描述事件发生的时间,数据仓库就是一个随时间变化的数据集合,因此可能需要一个时间维度表。年月日时分秒。
地理维度表
描述地理位置信息数据,国家、省市县镇村、邮编等。
产品维度表
描述产品属性。比如书的分类,有科技、教育、小说等分类属性。
人员维度表
描述人员相关信息,销售人员、市场人员、开发人员等。
星型模型是一种多维的数据关系。一个事实表为中心,多个维度表环绕周围。
一个星型模型中可以有一个或多个事实表,每个事实表可以引用任意数量的维度表。
星型模型将业务流程分为事实和维度。事实是对业务的度量,是定量的数据,比如价格、销售数量、距离、速度、质量等。维度是对事实数据属性的描述,比如日期、产品、客户、地理位置等。
当有一个或多个维表没有直接连接到事实表上,而是通过其他维表连接到事实表上时,就像多个雪花连接在一起,故称雪花模型。雪花模型是对星型模型的扩展,它对星型模型的维表进一步层次化,原有的各维表可能被扩展为小的事实表,形成一些局部的 "层次 " 区域,这些被分解的表都连接到主维度表而不是事实表。
如何将维度表进行层次化处理呢?
即把低基数(重复比较多、辨识度比较低、维度数据少,比如性别)的属性从维度表中移除并形成单独的表。
比如之前讲到的案例,购买量指标有课程维度,课程维度又可以将课程分类进行层次化扩展为新的维度表。
层次化的影响
层次化的过程是将维度表中重复度比较高的字段组成一个新表,所以层次化不可避免增加了表的数量,减少了数据的存储空间,提高了数据更新的效率。但是查询时就需要连接更多的表。
总结,雪花模型中,一个维度被规范化成多个关联的表,星型模型中,每个维度由一个单一的维度表所表示。
星座模式是星型模式延伸而来,星型模式是基于一张事实表的,而星座模式是基于多张事实表的,而且共享维度信息。 前面介绍的两种维度建模方法都是多维表对应单事实表,但在很多时候维度空间内的事实表不止一个,而一个维表也可能被多个事实表用到。在业务发展后期,绝大部分维度建模都采用的是星座模式
我们知道维度建模的表类型有事实表,维度表;模式有星形模型,雪花模型,星座模型这些概念了,但是实际业务中,给了我们一堆数据,我们怎么拿这些数据进行数仓建设呢,数仓工具箱作者根据自身60 多年的实际业务经验,给我们总结了如下四步,请务必记住!
数 仓 工 具 箱 中 的 维 度 建 模 四 步 走 :
请牢记以上四步,不管什么业务,就按照这个步骤来,顺序不要搞乱,因为这四步是环环相扣,步步相连。下面详细拆解下每个步骤怎么做
维度建模是紧贴业务的,所以必须以业务为根基进行建模,那么选择业务过程,顾名思义就是在整个业务流程中选取我们需要建模的业务,根据运营提供的需求及日后的易扩展性等进行选择业务。比如商城,整个商城流程分为商家端,用户端,平台端,运营需求是总订单量,订单人数,及用户的购买情况等,我们选择 业务过程就选择用户端的数据,商家及平台端暂不考虑。业务选择非常重要,因 为后面所有的步骤都是基于此业务数据展开的。
先举个例子:对于用户来说,一个用户有一个身份证号,一个户籍地址,多个手机号,多张银行卡,那么与用户粒度相同的粒度属性有身份证粒度,户籍地址粒度,比用户粒度更细的粒度有手机号粒度,银行卡粒度,存在一对一的关系就是相同粒度。为什么要提相同粒度呢,因为维度建模中要求我们,在同一事实表中, 必须具有相同的粒度,同一事实表中不要混用多种不同的粒度,不同的粒度数据建立不同的事实表。并且从给定的业务过程获取数据时,强烈建议从关注原子粒 度开始设计,也就是从最细粒度开始,因为原子粒度能够承受无法预期的用户查询。但是上卷汇总粒度对查询性能的提升很重要的,所以对于有明确需求的数据,我们建立针对需求的上卷汇总粒度,对需求不明朗的数据我们建立原子粒度。
维度表是作为业务分析的入口和描述性标识,所以也被称为数据仓库的“灵魂”。在一堆的数据中怎么确认哪些是维度属性呢,如果该列是对具体值的描述,是一个文本或常量,某一约束和行标识的参与者,此时该属性往往是维度属性,数仓工具箱中告诉我们牢牢掌握事实表的粒度,就能将所有可能存在的维度区分开,并 且要确保维度表中不能出现重复数据,应使维度主键唯一
事实表是用来度量的,基本上都以数量值表示,事实表中的每行对应一个度量, 每行中的数据是一个特定级别的细节数据,称为粒度。维度建模的核心原则之一是同一事实表中的所有度量必须具有相同的粒度。这样能确保不会出现重复计算度量的问题。有时候往往不能确定该列数据是事实属性还是维度属性。记住最实用的事实就是数值类型和可加类事实。所以可以通过分析该列是否是一种包含多个值并作为计算的参与者的度量,这种情况下该列往往是事实。
维度可以根据变化剧烈程度主要分为无变化维度和变化维度。例如一个人的相关信息,身份证号、姓名和性别等信息数据属于不变的部分;而婚姻状态、工作经历、工作单位和培训经历等属于可能会变化的字段。
大多数维度数据随时间的迁移是缓慢变化的。比如增加了新的产品,或者产品的ID号码修改了,或者产品增加了一个新的属性,此时,维度表就会被修改或者增加新的记录行。这样,在设计维度和使用维度的过程中,就要考虑到缓慢变化维度数据的处理。
缓慢渐变维,即维度中的属性可能会随着时间发生改变,比如包含用户住址Address的DimCustomer维度,用户的住址可能会发生改变,进而影响业务统计精度,DimCustomer维度就是缓慢渐变维(SCD)。
SCD有三种分类,我们这里以顾客表为例来进行说明:
假设在第一次从业务数据库中加载了一批数据到数据仓库中,当时业务数据库有这样的一条顾客的信息。
顾客 BIWORK ,居住在北京,目前是一名 BI 的开发工程师。假设 BIWORK 因为北京空气质量 PM2.5 等原因从北京搬到了三亚。那么这条信息在业务数据库中应该被更新了。
那么当下次从业务数据库中抽取这类信息的时候,数据仓库又应该如何处理呢?
我们假设在数据仓库中实现了与业务数据库之间的同步,数据仓库中也直接将词条数据修改更新。后来我们创建报表做一些简单的数据统计分析,这时在数据仓库中所有对顾客 BIWORK 的销售都指向了 BIWORK 新的所在地 - 城市三亚,但是实际上 BIWORK 在之前所有的购买都发生在 BIWORK 居住在北京的时候。
通过这个简单的例子,描述了因一些基本信息的更改可能会引起数据归纳和分析出现的问题。
通过更新维度记录直接覆盖已存在的值。不维护记录的历史。一般用于修改错误的数据,即历史数据就是错误数据,除此没有他用。
在数据仓库中,我们可以保持业务数据和数据仓库中的数据始终处于一致。可以在 Customer 维度中使用来自业务数据库中的 Business Key - CustomerID 来追踪业务数据的变化,一旦发生变化那么就将旧的业务数据覆盖重写。
DW 中的记录根据业务数据库中的 CustomerID 获取了最新的 City 信息,直接更新到 DW 中。
在源数据发生变化时,给维度记录建立一个新的“版本”记录,从而维护维度历史。SCD2不删除、不修改已存在的数据。SCD2也叫拉链表。
在数据仓库中有很多需求场景会对历史数据进行汇总和分析,因此会尽可能的维护来自业务系统中的历史数据,使系统能够真正捕获到这种历史数据的变化。
以上面的例子来说,可能需要分析的结果是 BIWORK 在 2012年的时候购买额度整体平稳,但是从2013年开始购买额度减少了。出现的原因可能与所在的城市有关系,在北京的门店可能比在三亚的门店相对要多一些。
像这种情况,就不能很简单在数据仓库中将 BIWORK 当前所在城市直接更新,否则此用户所有的购买额度都会归于三亚。
通过起始时间来标识,Valid To(封链时间)为 NULL 的标识当前数据,也可以用2999,3000,9999等等比较大的年份。数仓内部需要保持统一。每个版本都会产生一行新的数据。
实际上SCD1 and 2 可以满足大多数需求了,但是仍然有其它的解决方案,比如说 SCD3。 SCD3希望只维护更少的历史记录。
比如说把要维护的历史字段新增一列,然后每次只更新 Current Column 和 Previous Column。这样,只保存了最近两次的历史记录,历史数据都在同一行数据中。但是如果要维护的字段比较多,就比较麻烦,因为要更多的 Current 和 Previous 字段。所以 SCD3 用的还是没有 SCD1 和 SCD2 那么普遍。它只适用于数据的存储空间不足并且用户接受有限历史数据的情况。
作为一名数据的规划者,我们肯定希望自己的数据能够有秩序地流转,数据的整个生命周期能够清晰明确被设计者和使用者感知到。直观来讲就是如图这般层次清晰、依赖关系直观。
但是,大多数情况下,我们完成的数据体系却是依赖复杂、层级混乱的。如下的右图,在不知不觉的情况下,我们可能会做出一套表依赖结构混乱,甚至出现循环依赖的数据体系。
因此,我们需要一套行之有效的数据组织和管理方法来让我们的数据体系更有序,这就是谈到的数据分层。数据分层并不能解决所有的数据问题,但是,数据分层却可以给我们带来如下的好处:
清晰数据结构:每一个数据分层都有它的作用域和职责,在使用表的时候能更方便地定位和理解。
复杂问题简单化:将一个复杂的任务分解成多个步骤来完成,每一层解决特定的问题。
便于维护:当数据出现问题之后,可以不用修复所有的数据,只需要从有问题的步骤开始修复。
减少重复开发:规范数据分层,开发一些通用的中间层数据,能够减少重复开发的工作量。
高性能:数据仓库的构建将大大缩短获取信息的时间,数据仓库作为数据的集合,所有的信息都可以从数据仓库直接获取,尤其对于海量数据的关联查询和复杂查询,所以数据仓库分层有利于实现复杂的统计需求,提高数据统计的效率。
通常将数据模型分为三层:数据运营层( ODS )、数据仓库层(DW)和数据应用层(APP)。简单来讲,我们可以理解为:ODS层存放的是接入的原始数据,DW层是存放我们要重点设计的数据仓库中间层数据,APP是面向业务定制的应用数据。下面详细介绍这三层的设计。
此层数据无任何更改,直接沿用外围系统数据结构和数据,不对外开放;为临时存储层,是接口数据的临时存储区域,为后一步的数据处理做准备。
DW 层的数据应该是一致的、准确的、干净的数据,即对源系统数据进行了清洗(去除了杂质)后的数据。
此层可以细分为三层:
明细层DWD(Data Warehouse Detail):存储明细数据,此数据是最细粒度的事实数据。该层一般保持和ODS层一样的数据粒度,并且提供一定的数据质量保证。同时,为了提高数据明细层的易用性,该层会采用一些维度退化手法,将维度退化至事实表中,减少事实表和维表的关联。
中间层DWM(Data WareHouse Middle):存储中间数据,为数据统计需要创建的中间表数据,此数据一般是对多个维度的聚合数据,此层数据通常来源于DWD层的数据。
业务层DWS(Data WareHouse Service):存储宽表数据,此层数据是针对某个业务领域的聚合数据,应用层的数据通常来源与此层,为什么叫宽表,主要是为了应用层的需要在这一层将业务相关的所有数据统一汇集起来进行存储,方便业务层获取。此层数据通常来源与DWD和DWM层的数据。
在实际计算中,如果直接从DWD或者ODS计算出宽表的统计指标,会存在计算量太大并且维度太少的问题,因此一般的做法是,在DWM层先计算出多个小的中间表,然后再拼接成一张DWS的宽表。由于宽和窄的界限不易界定,也可以去掉DWM这一层,只留DWS层,将所有的数据在放在DWS亦可。
前端应用直接读取的数据源;根据报表、专题分析的需求而计算生成的数据。
最后补充一个维表层,维表层主要包含两部分数据:
高基数维度数据:一般是用户资料表、商品资料表类似的资料表。数据量可能是千万级或者上亿级别。
低基数维度数据:一般是配置表,比如枚举值对应的中文含义,或者日期维表。数据量可能是个位数或者几千几万。
这里我们以电商网站的数据仓库为例,针对用户访问日志这一部分数据进行举例说明。
在ODS层中,由于各端的开发团队不同或者各种其它问题,用户的访问日志被分成了好几张表上报到了我们的ODS层。
为了方便大家的使用,我们在DWD层做了一张用户访问行为天表,在这里,我们将PC网页、H5、小程序和原生APP访问日志汇聚到一张表里面,统一字段名,提升数据质量,这样就有了一张可供大家方便使用的明细表了。
在DWM层,我们会从DWD层中选取业务关注的核心维度来做聚合操作,比如只保留人、商品、设备和页面区域维度。类似的,我们这样做了很多个DWM的中间表。
然后在DWS层,我们将一个人在整个网站中的行为数据放到一张表中,这就是我们的宽表了,有了这张表,就可以快速满足大部分的通用型业务需求了。
最后,在APP应用层,根据需求从DWS层的一张或者多张表取出数据拼接成一张应用表即可。