赞
踩
数据库(Database)是按照数据结构来组织、存储和管理数据的建立在计算机存储设备上的仓库。
数据库是长期储存在计算机内、有组织的、可共享的数据集合。数据库中的数据指的是以一定的数据模型组织、描述和储存在一起、具有尽可能小的冗余度、较高的数据独立性和易扩展性的特点并可在一定范围内为多个用户共享。
常用的数据库有 MySQL、ORACLE、SQL Server 等。
数据仓库是决策支持系统(dss)和联机分析应用数据源的结构化数据环境。数据仓库研究和解决从数据库中获取信息的问题。
数据仓库的特征在于面向主题、集成性、稳定性和时变性,用于支持管理决策。
数据仓库存在的意义在于对企业的所有数据进行汇总,为企业各个部门提供统一的, 规范的数据出口。
面向主题:数据仓库中的数据是按照一定的主题域进行组织的,每一个主题对应一个宏观的分析领域。数据仓库排除对于决策无用的数据,提供特定主题的简明视图。
集成的:企业内不同业务部门数据的完整集成。
对于企业内所有数据的集成要注意一致性(假设财务系统中对于性别使用 F/M,而 OA 系统对性别使用 A/B,这就是数据不一致,如果想搭建企业级的数据仓库,需要数据具有一致性)。
稳定的:数仓里不存在数据的更新和删除操作。
变化的:数仓里会完整的记录某个对象在一段时期内的变化情况。
维度 | 数据仓库 | 数据库 |
---|---|---|
应用场景 | OLAP | OLTP |
数据来源 | 多数据源 | 单数据源 |
数据标准化 | 非标准化Schema | 高度标准化的静态Schema |
数据读取优势 | 针对读操作进行优化 | 针对写操作进行优化 |
数据湖:一个集中存储各类结构化和非结构化数据的大型数据仓库,它可以存储来自多个数据源、多种数据类型的原始数据,数据无需经过结构化处理,就可以进行存取、处理、分析和传输。数据湖能帮助企业快速完成异构数据源的联邦分析、挖掘和探索数据价值。
数据湖 = 数据存储架构 + 数据处理工具
数据存储架构:要有足够的扩展性和可靠性,可以存储海量的任意类型的数据,包括结构化、半结构化和非结构化数据。
数据处理工具,则分为两大类:
1)聚焦如何把数据“搬到”湖里。包括定义数据源、制定数据同步策略、移动数据、编制数据目录等。
2)关注如何对湖中的数据进行分析、挖掘、利用。数据湖需要具备完善的数据管理能力、多样化的数据分析能力、全面的数据生命周期管理能力、安全的数据获取和数据发布能力。如果没有这些数据治理工具,元数据缺失,湖里的数据质量就没法保障,最终会由数据湖变质为数据沼泽。
数据仓库和数据湖的不同类比于仓库和湖泊:仓库存储着来自特定来源的货物;而湖泊的水来自河流、溪流和其他来源,并且是原始数据。
维度 | 数据湖 | 数据仓库 |
---|---|---|
应用场景 | 可以探索性分析所有类型的数据,包括机器学习、数据发现、特征分析、预测等 | 通过历史的结构化数据进行数据分析 |
使用成本 | 起步成本低,后期成本较高 | 起步成本高,后期成本较低 |
数据质量 | 包含大量原始数据,使用前需要清洗和标准化处理 | 质量高,可作为事实依据 |
适用对象 | 数据科学家、数据开发人员为主 | 业务分析师为主 |
分层原因
1)把复杂问题简单化
2)减少重复开发
3)隔离原始数据
数据仓库基础分层主要是分为四层
如上图所示,一个公司可能有多个业务系统,而数据仓库就是将所有的业务系统按照某种组织架构整合起来,形成一个仓储平台,也就是数仓。
1.四层分层
第一层:ODS——原始数据层:存放原始数据
ODS层即操作数据存储,是最接近数据源中数据的一层,数据源中的数据,经过抽取、洗净、传输,也就说传说中的ETL之后,装入本层;一般来说ODS层的数据和源系统的数据是同构的,主要目的是简化后续数据加工处理的工作。从数据粒度上来说ODS层的 数据粒度是 最细 的。ODS层的表通常包括两类,一个用于存储当前需要加载的数据,一个用于存储处理完后的历史数据。历史数据一般保存3-6个月后需要清除,以节省空间。但不同的项目要区别对待,如果源系统的数据量不大,可以保留更长的时间,甚至全量保存;数据在装入本层前需要做以下工作:去噪、去重、提脏、业务提取、单位统一、砍字段、业务判别。
第二层:DWD——数据明细层:对ODS层数据进行清洗、维度退化、脱敏等。
该层一般保持和ODS层一样的数据粒度,并且提供一定的数据质量保证,在ODS的基础上对数据进行加工处理,提供更干净的数据。同时,为了提高数据明细层的易用性,该层会采用一些维度退化手法,当一个维度没有数据仓库需要的任何数据时,就可以退化维度,将维度退化至事实表中,减少事实表和维表的关联。例如:订单id,这种量级很大的维度,没必要用一张维度表来进行存储,而我们一般在进行数据分析时订单id又非常重要,所以我们将订单id冗余在事实表中,这种维度就是退化维度。
第三层:DWS——数据汇总层: 对DWD层数据进行一个轻度的汇总。
DWS层为公共汇总层,会进行轻度汇总,粒度比明细数据稍粗,会针对度量值进行汇总,目的是避免重复计算。该层数据表会相对比较少,大多都是宽表(一张表会涵盖比较多的业务内容,表中的字段较多)。按照主题划分,如订单、用户等,生成字段比较多的宽表,用于提供后续的业务查询,OLAP分析,数据分发等。
第四层:DM——数据集市层:为各种统计报表提供数据。
存放的是轻度聚合的数据,也可以称为数据应用层,基于DWD、DWS上的基础数据,整合汇总成分析某一个主题域的报表数据。主要是提供给数据产品和数据分析使用的数据,通常根据业务需求,划分成流量、订单、用户等,生成字段比较多的宽表,用于提供后续的业务查询,OLAP分析,数据分发等。从数据粒度来说,这层的数据是汇总级的数据,也包括部分明细数据。从数据的时间跨度来说,通常是DW层的一部分,主要的目的是为了满足用户分析的需求,而从分析的角度来说,用户通常只需要分析近几年的即可。从数据的广度来说,仍然覆盖了所有业务数据。
2,三层分层
第一层:ODS——原始数据层:存放原始数据
第二层:DW——数据仓库层:数据清洗,初步汇总
本层将从 ODS 层中获得的数据按照主题建立各种数据模型,每一个主题对应一个宏观的分析领域,数据仓库层排除对决策无用的数据,提供特定主题的简明视图。在DW层会保存BI系统中所有的历史数据,例如保存10年的数据。
第三层:DM——数据集市层:为各种统计报表提供数据。
3,五层分层
第一层:ODS——原始数据层:存放原始数据
第二层:DWD——数据明细层:对ODS层数据进行清洗、维度退化、脱敏等。
第三层:DWS——数据汇总层: 对DWD层数据进行一个轻度的汇总。
第四层:ADS——数据应用层:为各种统计报表提供数据
该层是基于DW层的数据,整合汇总成主题域的服务数据,用于提供后续的业务查询等。
第五层:DIM——维表层:基于维度建模理念思想,建立整个企业的一致性维度。
维表层主要包含两部分数据:1)高基数维度数据:一般是用户资料表、商品资料表类似的资料表。数据量可能是千万级或者上亿级别。2)低基数维度数据:一般是配置表,比如枚举值对应的中文含义,或者日期维表。数据量可能是个位数或者几千几万。
操作型处理,叫联机事务处理 OLTP(On-Line Transaction Processing,),也可以称面向交易的处理系统,它是针对具体业务在数据库联机的日常操作,通常对少数记录进行查询、修改。用户较为关心操作的响应时间、数据的安全性、完整性和并发支持的用户数等问题。传统的数据库系统作为数据管理的主要手段,主要用于操作型处理。
分析型处理,叫联机分析处理 OLAP(On-Line Analytical Processing)一般针对某些主题的历史数据进行分析,支持管理决策。
OLTP 与 OLAP 的异同如表所示:
OLTP | OLAP | |
---|---|---|
用户 | 操作人员,低层管理人员 | 决策人员,高级管理人员 |
功能 | 日常操作处理 | 分析决策 |
DB设计 | 面向应用 | 面向主题 |
数据 | 当前的,最新的,细节的,二维的,分立的 | 历史的,聚集的,多维的,集成的,统一的 |
存取 | 读写数十条记录 | 读上百万条记录 |
工作单位 | 简单的事务 | 复杂的查询 |
用户数 | 上千个 | 上百万个 |
DB大小 | 100MB-GB | 100GB-TB |
时间要求 | 具有实时性 | 对时间的要求不严格 |
并发要求 | 高并发 | 低并发 |
技术实现方案 | 事务;索引;存储计算耦合 | 大量SCAN;列式存储;存算可以分离 |
数据模型/规约 | 关系模型,3NF范式 | 维度模型,关系模型,对范式要求低 |
主要应用 | 数据库 | 数据仓库 |
技术典范 | MySQL,Oracle | SQL-On-Hadoop |
六范式
一范式(1NF):域应该是原子性的,即数据库表的每一列都是不可分割的原子数据项。
域:域就是列的取值范围,比如性别的域就是(男,女)
不符合一范式的表格设计如下:
ID | 商品 | 商家 | 用户ID | 产地 |
001 | 5 台电脑 | XXX旗舰店 | 00001 | 河北省石家庄市裕华区 |
很明显上表所示的表格设计是不符合第一范式的,商品列中的数据不是原子数据项,是可以进行分割的,因此对表格进行修改,让表格符合第一范式的要求,修改结果如下表所示:
ID | 商品 | 数量 | 商家ID | 用户ID | 省 | 市 | 区 |
001 | 电脑 | 5 | 00254 | 00001 | 河北 | 石家庄 | 裕华区 |
实际上, 1NF 是所有关系型数据库的最基本要求, 你在关系型数据库管理系统
(RDBMS),例如 SQL Server,Oracle,MySQL 中创建数据表的时候,如果数据表的设计
不符合这个最基本的要求,那么操作一定是不能成功的。也就是说,只要在 RDBMS 中已经存在的数据表,一定是符合 1NF 的。
二范式
二范式(2NF):在 1NF 的基础上,实体的属性完全函数依赖于主关键字(混合主键), 不能存在部分函数依赖于主关键字(混合主键)。
如果存在某些属性只依赖混合主键中的部分属性,那么不符合二范式。
数据表中的所有列,必须依赖于唯一的一个主键。
学生 ID | 姓名 | 所属系 | 系主任 | 所修课程 | 分数 |
20170901176 | 王小强 | 计算机系 | 马小腾 | 000001 | 95 |
20170901176 | 王小强 | 计算机系 | 马小腾 | 000002 | 99 |
上述表格中是混合主键(学生 ID + 所修课程),但是所属系和系主任这两个属性只依赖于混合主键中的学生 ID 这一个属性,因此,不符合第二范式。
如果有一天学生的所属系要调整,那么所属系和系主任这两列都需要修改,如果这个学生修了多门课程,那么表中的多行数据都要修改,这是非常麻烦的,不符合第二范式。
为了消除这种部分依赖,只有一个办法,就是将大数据表拆分成两个或者更多个更小的数据表。
符合二范式的表格设计如下:
表 3-5 符合二范式的表格设计(1)
学生 ID | 所修课程 | 分数 |
20170901176 | 000001 | 95 |
20170901176 | 000002 | 99 |
系 ID | 所属系 | 系主任 |
000001 | 计算机系 | 马小腾 |
000002 | 计算机系 | 马小腾 |
学生 ID | 姓名 |
20170901176 | 王小强 |
20170901176 | 王小强 |
通过上述的修改,当一个学生的所属系需要调整时,不管学生修了多少门课程,都只需要改变表 3-5 中的一行数据即可。
通过上述的修改,当一个学生的所属系需要调整时,不管学生修了多少门课程,都只需要改变上表中的一行数据即可。
三范式
3NF 在 2NF 的基础之上,消除了非主属性对于主键(复合主键)的传递依赖。
表 3-6 不符合三范式的表格设计
订单ID | 商品ID | 商品颜色 | 商品尺寸 | 商家ID | 用户ID |
001 | 0001 | 深空灰 | 300*270*40 | XXX旗舰店 | 00001 |
很明显,表 3-7 中,商品颜色依赖于商品 ID,商品 ID 依赖于订单 ID,那么非主属性商品颜色就传递依赖于订单 ID,因此不符合三范式,解决方案是将大数据表拆分成两个或者更多个更小的数据表。
数据中只能有唯一的一个主键。外键不能传递依赖于主键。
表 3-7 符合三范式的表格设计(1)
订单ID | 商品ID | 商家ID | 用户ID |
001 | 0001 | XXX旗舰店 | 00001 |
商品ID | 商品颜色 | 商品尺寸 |
0001 | 深空灰 | 300*270*40 |
BC范式(BGFN):关系模式R<U,F>中,若每一个决定因素都包含码,则R<U,F>属于BCFN。
理解:根据定义我们可以得到结论,一个满足BC范式的关系模式有:所有非主属性对每一个码都是完全函数依赖;所有主属性对每一个不包含它的码也是完全函数依赖;没有任何属性完全函数依赖于非码的任何一组属性。
例如有关系模式C(Cno, Cname, Pcno),Cno,Cname,Pcno依次表示课程号、课程名、先修课。可知关系C只有一个码Cno,且没有任何属性对Cno部分函数依赖或传递函数依赖,所以关系C属于第三范式,同时Cno是C中的唯一决定因素,所以C也属于BC范式。
第四范式(4NF): 限制关系模式的属性之间不允许有非平凡且非函数依赖的多值依赖。
理解: 显然一个关系模式是4NF,则必为BCNF。也就是说,当一个表中的非主属性互相独立时(3NF),这些非主属性不应该有多值,若有多值就违反了4NF。
第五范式(5NF): 越往下,冗余度越低。必须满足第四范式;表必须可以分解为较小的表,除非那些表在逻辑上拥有与原始表相同的主键。
第五范式是在第四范式的基础上做的进一步规范化。第四范式处理的是相互独立的多值情况,而第五范式则处理相互依赖的多值情况。
反范式:反范式化设计数据库,是为了提高查询效率,采用空间换时间的实现思路。
应用场景:当冗余的信息有价值或者能大幅度提高查询效率的时候,我们才会采取反范式的优化。
一些情况下,比如存在频繁查询时,可以容忍适当的冗余设计,目的是减少多表关联查询,提高效率。
缺点:存储空间变大了;一个表中字段做了修改,另一个表中冗余字段也需要做同步修改,否则数据不一致;若采用存储过程来支持数据的更新、删除等额外操作,如果更新频繁会非常消耗系统资源。
范式化设计与反范式设计的优缺点
范式化设计(时间换空间)
优点:范式化的表减少了数据冗余,数据表更新操作快、占用存储空间小。
缺点:查询时需要对多个表进行关联,查询性能降低;索引优化会更难进行。
反范式化设计(空间换时间):通过增加数据表中的冗余字段来提高数据库的读(查询)性能,但冗余数据会牺牲数据一致性。
优点:可以减少表关联;可能更好的进行索引优化。
缺点:存在大量冗余数据;数据维护成本更高(删除异常,插入异常,更新异常)。
数据仓库建模的目标是通过建模的方法更好的组织、存储数据,以便在性能、成本、效率和数据质量之间找到最佳平衡点。
访问性能:能够快速查询所需的数据,减少数据 I/O;DM集市(hbase ES)mysql
数据成本:减少不必要的数据冗余,实现计算结果数据复用,降低大数据系统中的数据成本和计算成本;
使用效率:改善用户应用体验,提高使用数据的效率;
数据质量:整合所有数据源的数据,改善数据统计口径的不一致性,减少数据计算错误的可能性,提供高质量的、一致的数据访问平台。
上述的四点之间是存在冲突的,为了提高访问性能,可能会提高数据冗余(减少 Join), 这样会降低计算成本,但是会导致数据存储成本很高,并且由于数据的冗余,会提高数据统计口径不一致的风险,我们的目的是通过合理的设计在性能、成本、效率和数据质量之间找到平衡点。
ER 模型是数据库设计的理论基础,当前几乎所有的 OLTP 系统设计都采用 ER 模型建模的方式。
在信息系统中,将事物抽象为“实体”、“属性”、“关系”来表示数据关联和事物描述;其中,实体:Entity,关系:Relationship,这种对数据的抽象建模通常被称为 ER 实体关系模型。
实体:通常为参与到过程中的主体,客观存在的,比如商品、仓库、货位、汽车,此实体非数据库的实体表;
属性:对主体的描述、修饰即为属性,比如商品的属性有商品名称、颜色、尺寸、重量、产地等;
关系:现实的物理事件是依附于实体的,比如商品入库事件,依附实体商品、货位, 就会有“库存”的属性产生;用户购买商品,依附实体用户、商品,就会有“购买数量”、
“金额”的属性产品。
实体之间建立关系时,存在对照关系:
1:1,即 1 对 1 的关系,比如实体人、身份证,一个人有且仅有一个身份证号;(A->B: 相互完全依赖,知道 A 一定确定 B,知道 B 一定确定 A)。
(动静分离:在数据库设计时,会将动态属性(年龄、地址、偏好、...)和静态属性(姓名、性别、身份证号、...)进行分离,剥离为两张表,一张父表,一张子表,从而提高性能)。
1:n,即 1 对多的关系,比如实体学生、班级,对于某 1 个学生,仅属于 1 个班级,而在 1 个班级中,可以有多个学生;(一张学生表,一张班级表,通过班级 ID 这个外键进行关联)。
n:m,即多对多的关系,比如实体学生、课程,每个学生可以选修多门课程,同样每个课程也可以被多门学生选修;(一张学生表,一张课程表,一张选课表)。
在日常建模过程中:
“实体”:使用矩形表示;
“关系”:使用菱形表示;
“属性”:使用椭圆形表示;
所以 ER 实体关系模型也称作 E-R 关系图。
学生选课系统,该系统主要用来管理学生和选修课程,其中包括课程选修、学生管理功能,现需要完成数据库逻辑模型设计。
图 3-4 ER 关系图
使用 ER 模型构建数据仓库的成功率是比较低的,因为涉及到“抽象出实体”这个过程, 这就涉及到将企业所有业务系统中的所有实体都抽象出来,这需要先梳理出所有的业务系 统实体,再梳理实体之间的关系,这是一个非常复杂的过程,可能你把公司所有的实体梳 理清楚了,可能业务又要调整了。
维度建模的理论由 Ralph Kimball 提出,他提出将数据仓库中的表划分为事实表和维度表两种类型。
维度建模源自数据集市,主要面向分析场景。
“事实表”,用来存储事实的度量(measure)及指向各个维的外键值。“维度表”, 用来保存该维的元数据,即维的描述信息,包括维的层次及成员类别等。
简单的说,维度表就是你观察该事物的角度(维度),事实表就是你要关注的内容。例如用户使用滴滴打车,那么打车这件事就可以转化为一个事实表,即打车订单事实表,然后用户对应一张用户维度表,司机对应一张司机维度表。
在现实世界中,每一个操作型事件,基本都是发生在实体之间的,伴随着这种操作事件的发生,会产生可度量的值,而这个过程就产生了一个事实表,存储了每一个可度量的事件。
发生在现实世界中的操作性事件所产生的可度量数值,存储在事实表中。从最低的粒
度级别来看,事实表行对应一个度量事件,反之亦然。因此,事实表的设计完全依赖于物理活动,不受可能产生的最终报表的影响。除数字度量外,事实表总是包含外键,用于关联与之相关的维度,也包含可选的退化维度键和日期/时间戳。查询请求的主要目标是基于事
实表展开计算和聚集操作。
事实表往往包含三个重要元素:
例如在电商场景中的一次购买事件,涉及主体包括客户、商品、商家,产生的可度量值包括商品数量、金额、件数等。
图 3-6 订单事实表
每个维度表都包含单一的主键列。维度表的主键可以作为与之关联的任何事实表的外键,当然,维度表行的描述环境应与事实表行完全对应。维度表通常比较宽,是扁平型非
规范表,包含大量的低粒度的文本属性。
比如商品,单一主键为商品 ID,属性包括产地、颜色、材质、尺寸、单价等,但并非属性一定是文本,比如单价、尺寸,均为数值型描述性的,日常主要的维度抽象包括:时间维度表、地理区域维度表等。
图 3-7 商品维度表
综上所述,如果针对用户的下单行为(单一商品)进行维度建模,我们可以得到如下模型:
图 3-8 维度建模实例
某电商平台,经常需要对订单进行分析,以某宝的购物订单为例,以维度建模的方式设计该模型。
事实表为订单表、子订单表,维度包括商品维度、用户维度、商家维度、区域维度、时间维度。
订单中包含的度量:商品件数、总金额、总减免金额; 描述性属性:下单时间、付款时间、订单状态等;
子订单包含度量:商品 ID、单价、减免金额;
描述性属性:加入购物车时间、下单时间、付款时间、状态;
商品维度:商品 ID、商品名称、商品品类、单价、颜色、尺寸、生产商等; 用户维度:用户 ID、姓名、性别、生日、职业、信用值、收货地址等;
时间维度:日期 ID、日期、周几、是否周末、是否假期等;
区域维度:区域 ID,县/区、县/区 ID、市、市 ID、省、省 ID;
图 3-9 维度建模实例
订单表和子订单表是两张事实表,我们往往会避免事实表之间产生关系,因此会考虑 让子订单表中有一定的数据冗余,比如订单表和订单明细表都各自记录着用户 ID,区域 ID, 时间 ID 等,这样在查询子订单信息时,就不用通过关联订单表来获取上述数据了,但是子订单表中仍会保存订单 ID 字段。
ER 模型以及维度模型是当前主流的建模方法。
ER 模型常用于 OLTP 数据库建模,应用到构建数仓时更偏重数据整合,站在企业整体考虑,将各个系统的数据按相似性、一致性合并处理,为数据分析、决策服务,但并不便于直接用来支持分析。
ER 模型的特点如下:
维度建模是面向分析场景而生,针对分析场景构建数仓模型;重点关注快速、灵活的解决分析需求,同时能够提供大规模数据的快速响应性能。针对性强,主要应用于数据仓库构建和 OLAP 引擎低层数据模型。
某电商平台,经常需要对订单进行分析,以某宝的购物订单为例,以维度建模的方式设计该模型。
事实表为订单表、子订单表,维度包括商品维度、用户维度、商家维度、区域维度、时间维度。
订单中包含的度量:商品件数、总金额、总减免金额; 描述性属性:下单时间、付款时间、订单状态等;
子订单包含度量:商品 ID、单价、减免金额;
描述性属性:加入购物车时间、下单时间、付款时间、状态;
商品维度:商品 ID、商品名称、商品品类、单价、颜色、尺寸、生产商等; 用户维度:用户 ID、姓名、性别、生日、职业、信用值、收货地址等;
时间维度:日期 ID、日期、周几、是否周末、是否假期等; 区域维度:区域 ID,县/区、县/区 ID、市、市 ID、省、省 ID;
图 3-9 维度建模实例
订单表和子订单表是两张事实表,我们往往会避免事实表之间产生关系,因此会考虑 让子订单表中有一定的数据冗余,比如订单表和订单明细表都各自记录着用户 ID,区域 ID, 时间 ID 等,这样在查询子订单信息时,就不用通过关联订单表来获取上述数据了,但是子订单表中仍会保存订单 ID 字段。
ER 模型以及维度模型是当前主流的建模方法。
ER 模型常用于 OLTP 数据库建模,应用到构建数仓时更偏重数据整合,站在企业整体考虑,将各个系统的数据按相似性、一致性合并处理,为数据分析、决策服务,但并不便于直接用来支持分析。
ER 模型的特点如下:
维度建模是面向分析场景而生,针对分析场景构建数仓模型;重点关注快速、灵活的解决分析需求,同时能够提供大规模数据的快速响应性能。针对性强,主要应用于数据仓库构建和 OLAP 引擎低层数据模型。
图 3-1 星型模型
星型模式是维度模型中最简单的形式,也是数据仓库以及数据集市开发中使用最广泛的
形式。星型模式由事实表和维度表组成,一个星型模式中可以有一个或多个事实表,每个
事实表引用任意数量的维度表。星型模式的物理模型像一颗星星的形状,中心是一个事实表, 围绕在事实表周围的维度表表示星星的放射状分支,这就是星型模式这个名字的由来。
星型模式将业务流程分为事实和维度。事实包含业务的度量,是定量的数据,如销售价格、销售数量、距离、速度、重量等是事实。维度是对事实数据属性的描述,如日期、产品、客户、地理位置等是维度。一个含有很多维度表的星型模式有时被称为蜈蚣模式,显然这个名字也是因其形状而得来的。蜈蚣模式的维度往往只有很少的几个属性,这样可以简化对维度表的维护,但查询数据时会有更多的表连接,严重时会使模型难于使用,因此在设计中应该尽量避免蜈蚣模式。
图 3-2 雪花模型
雪花模式是一种多维模型中表的逻辑布局,其实体关系图有类似于雪花的形状,因此得名。
与星型模式相同,雪花模式也是由事实表和维度表所组成。所谓的“雪花化”就是将行星模型中的维度表进行规范化处理。当所有的维度表完成规范化后,就形成了以事实表为
中心的雪花型结构,即雪花模式。将维度表进行规范化的具体做法是,把低基数的属性从维度表中移除并形成单独的表。基数指的是一个字段中不同值的个数,如主键列具有唯一值, 所以有最高的基数,而像性别这样的列基数就很低。
在雪花模式中,一个维度被规范化成多个关联的表,而在星型模式中,每个维度由一个单一的维度表所表示。一个规范化的维度对应一组具有层次关系的维度表,而事实表作为雪花模式里的字表,存在具有层次关系的多个父表。
图 3-3 星座模式
数据仓库由多个主题构成,包含多个事实表,而维表是公共的,可以共享,这种模式可以看做星型模式的汇集,因而称作星系模式或者事实星座模式。
在数据仓库建模时,会涉及到模式的选择,我们要根据不同模式的特点选择适合具体业务的模式:
冗余:雪花模型符合业务逻辑设计,采用 3NF 设计,有效降低数据冗余;星型模型的维度表设计不符合 3NF(如果是雪花模型改造成了星型模型,那么肯定不符合 3NF,因为一定发生了表的整合,即降维,一定有传递依赖,但是,并不是所有的星型模型都不符合
3NF,很多星型模型的表是符合 3NF 的),反规范化,维度表之间不会直接相关,牺牲部分存储空间。(雪花模型的维度之间是有关联的)
性能:雪花模型由于存在维度间的关联,采用 3NF 降低冗余,通常在使用过程中,需要连接更多的维度表,导致性能偏低;星型模型反三范式,采用降维的操作将维度整合,以存储空间为代价有效降低维度表连接数,性能较雪花模型高。( 星型表的数据冗余大,是用存储空间换取效率 )( BI 的一些工具对于星型模型的支持更规范化 )
ETL:雪花模型符合业务 ER 模型设计原则,在 ETL 过程中相对简单,但是由于附属模型的限制,ETL 任务并行化较低(由于雪花模型中有很多的维度依赖,在 ETL 的时候, 需要在保持 3NF 的前提下对数据进行清洗,即对数据一致性/规范化的处理,例如数据来自于多个业务系统,各个系统对于用户的定义不一致,此时要对每个业务定义的用户数据进行
规范化处理,在 3NF 的限制下必然会降低并行度);星型模型在设计维度表时反范式设计,
所以在 ETL 过程中整合业务数据到维度表有一定难度,但由于避免附属维度,可并行化处理(不用关注太多的关联关系,避免了维度表之间的关联关系,并行度较高,注意,一般场景下星型模型的并行化程度更高,并不是所有场景)。
Hive 的分析通过 MapReduce 实现,每多一个 Join 就会多出一个 MapReduce 过程,对于雪花模型,由于存在着很多维度表之间的关联,这就会导致一次分析对应多个 MapReduce 任务,而星型模型由于不存在维度表的关联,因此一个 MapReduce 就可以实现分析任务。
MapReduce 本身是一个支持高吞吐量的任务,它的每个任务都要申请资源、分配容器、节点通信等待,需要 YARN 的调度,由于相互关联的维度表本身会很小,join 操作用时很少,
YARN 调度的时长可能都大于实际运算的时长,因此我们要尽可能减少任务个数,对于 Hive 来说就是尽可能减少不必要的表的关联。还有一点,雪花模型中拆分出的维度表,每个表对应至少一个文件,这就涉及到 I/O 方面的性能损耗。
因此,我们要采用适当的数据冗余,避免不必要的表之间的关联。
在实际项目中,不会刻意地去考虑雪花模型,而是刻意地去考虑星型模型,特别是大数据领域的建模,倾斜于使用数据冗余来提高查询效率,倾向于星型模型;雪花模型只会应用在一些我们要求模型的灵活性,要求保证模型本身稳定性的场景下,但是雪花模型并不是首选。
维度表中必须有一个能够唯一标识一行记录的列(最好是原子性的列,不要是组合键), 通过该列维护维度表与事实表之间的关系,一般在维度表中业务主键符合条件可以当作维度主键。
但是,数据仓库是整个公司数据的整合,这会涉及到多个数据源有相同维度,那么就会出现以下两个问题:
表 5.1 财务部门维度表
ID | name | note |
1 | Chen | Finc |
2 | Zhang | Finc |
表 5.2 研发部门维度表
ID | name | note |
1 | Li | R&D |
2 | Zhou | R&D |
如上图所示,业务键重复,我们可以引入代理键,如下表所示:
表 5.3 引入代理键
GID | ID | name | note |
1 | 1 | Chen | Finc |
2 | 2 | Zhang | Finc |
3 | 1 | Li | Risk |
4 | 2 | Zhou | Risk |
把多个系统的数据复合在一起,同时再维护一个代理键,而且代理键在这个维度表里是唯一标识一条记录的,类似于业务系统的业务键。
代理键是由数据仓库处理过程中产生的、与业务本身无关的、唯一标识维度表中一条记录并充当维度表主键的列,也是描述维度表与事实表关系的纽带。
在设计有代理键的维度表中,事实表中的关联键是代理键而不是原有的业务主键,即
业务关系是靠代理键维护,这样有效避免源系统变化对数仓数据对影响。
在实际业务中,代理键通常是数值型、自增的值。
部分维度表的维度是在维度表产生后,属性是稳定的、无变化的。比如时间维度、区 域维度等,针对这种维度,设计维度表的时候,仅需要完整的数据,不需要天的快照数据, 因为当前数据状态就是历史数据状态。
图 5-1 稳定维度
维度数据会随着时间发生变化,变化速度比较缓慢,这种维度数据通常称作缓慢渐变维,例如电商平台的用户维度表,用户可能会随着时间推移改变收件地址,因此用户维度表
中的收件地址就是一个缓慢变化维。由于数据仓库需要追溯历史变化,尤其是一些重要的数据,所以历史状态也需要采取一定的措施进行保存,保存历史状态的方式有以下三种:
(根据公司具体的配置而定)的维度,使用简单的方式保存历史状态。
将数据的变更当做流水记录下来 ,旧的设为失效,新的设为生效,如果粒度为天,那么就可以得到一天的最终状态作为最终状态。
表 5-4 拉链表
ID | name | addr | start_date | end_date |
1 | Zhou | dept2 | 2018-05-01 | 2018-06-09 |
1 | Zhou | dept3 | 2018-06-10 | 2018-06-14 |
1 | Zhou | dept1 | 2018-06-15 | 9999-12-31 |
表 5-4 中每条记录都有一个 End_date,当有新的数据产生时,在旧数据的 End_date 字段中插入日期,然后新插入一条数据,新数据的 End_date 字段中是一个永久有效的值,如果再发生更新,上一次更新数据的 End_date 字段设置为当前日期,然后再次插入新数据, 新数据的 End_date 字段中设置一个永久有效的值。
如果想知道某个员工在 5 月 22 号时在哪个部门,那么可以通过如下 SQL:
Select * from user where start_date<= 2018-05-22 and end_date>= 2018-05-22
根据拉链表的结构,如果对维度表做拉链,那么一个维度实体必然存在多条记录,也就是一个主键 ID 对应多条数据,此时维度表的原子性主键也就没有意义了。
维度表做拉链后会失去原子性主键,那么拉链维度表如何和事实表进行关联呢? 此时就要用到代理键,也就是在事实表和维度表中同时添加代理键,如下图所示:
表 5-5 用户详情拉链表
UID | ID | name | addr | start_date | end_date |
1 | 1 | Zhou | dept2 | 2018-05-01 | 2018-06-09 |
2 | 1 | Zhou | dept3 | 2018-06-10 | 2018-06-14 |
3 | 1 | Zhou | dept1 | 2018-06-15 | 9999-12-31 |
表 5-6 订单表
OID | ID -> UID | Tim_ID | amount |
1 | 1 | 5 | 998 |
2 | 1 | 9 | 1000 |
3 | 2 | 10 | 1499 |
完成代理键的添加后,在之后的统计中,按照代理键进行聚合即可。
事实表来源于业务事务表,代理键和业务本身没有关系,那么怎么在新增数据时在事实表中装载代理键?
当事实表中有新增数据时,新增数据中记录了维度表中原有的原子性主键,可以根据原有的主键匹配维度表中的数据,然后根据新增数据的时间范围找到匹配的代理键,然后在事实表的新增数据中加入代理键。
代理键是维度建模中极力推荐的方式,它的应用能有效的隔离源端变化带来的数仓结构
不稳定问题,同时也能够提高数据检索性能。
但是代理键维护代价非常高,尤其是数据装载过程中,对事实表带来了较大的影响, 在基于 hive 的数据仓库建设影响更加严重,比如代理键的生成、事实表中关联键的装载、
不支持非等值关联等问题,带来 ETL 过程更加复杂。
因此,在大数据体系下,谨慎使用代理键,同时对于缓慢渐变维场景,可以考虑用空间换取时间,每天保留维表全量快照,但这样会带来存储成本,根据实际情况衡量。
表 6-1 命名规范示例
语义 | 翻译 | 缩写 |
订单 | order | ord |
增量 | increment | inc |
历史 | history | his |
累积 | total | total |
天 | day | d |
周 | week | w |
月 | month | m |
年 | year | y |
用户 | user | user |
账单/还款计划 | bill | bill |
金额 | amount | amt |
数量 | count | cnt |
手机 | mobile | mob |
年龄 | age | age |
数据仓库中表格的命名规范如下表所示:
表 6-2 表命名规范
数据域 | 数仓层次 | 周期/数据范围 | |||
订单 | ord | 共用维度 | dim | 日快照 | d |
用户 | user | 集市 | dm | 增量 | i |
财务 | finc | ODS | o | 周 | w |
账单 | bill | DWD | d | 拉链表 | l |
库存 | sto | DWS | s | 非分区全量表 | a |
在表格的命名中,我们要求能够合理的区分出表所描述的数据域、数据周期等。命名格式:层次_数据域_修饰/描述_范围/周期
根据表的命名规范,我们对以下的数据表进行命名:
DWD 层:d_ord_info_d
DWS 层:s_ord_st_d
维度表:
用户维度:dim_user_d
商品缓慢渐变维表:dim_product_l
ODS 层表:
(对于 ODS 层表,最好能够区分数据来源,包括来自什么系统、数据源名称) 业务系统编码:buss
业务系统订单表:loan_order
Ods 层表命名:o_buss_loan_order_d
设计模型的时候,按照业务含义、业务术语规范命名字段汉字名称。
根据字段命名对字段进行命名,如下表所示:
表 6-3 字段命名规范
名称 | 字段名称 |
用户 ID | user_id |
应还金额 | rep_amt |
实还金额 | act_amt |
逾期利息 | overdue_int |
下单计数 | ord_cnt |
月下单计数 | m_ord_cnt |
累积下单用户计数 | total_ord_user_cnt |
数据仓库中会使用到很多自动化脚本,脚本的命名规则如下:
根据脚本命名规范,我们对如下的脚本进行命名:
采集数据到 ODS 层的表 o_buss_loan_order_d,我们按照输出表 d_ord_ino_d 对脚本和任务进行命名:
数据采集脚本命名:imp_o_buss_loan_order_d.sh、imp_o_buss_loan_order_d.py
从 ODS 层的表 o_buss_loan_order_d 整理数据并且装载到 DWD 层表 d_ord_ino_d 中, 我们按照输出表 d_ord_ino_d 对脚本和任务进行命名:
ETL 脚本命名: d_ord_info_d.sh、d_ord_info_d.py、d_ord_info_d.hql、d_ord_info_d.jar
ETL 任务命名:d_ord_info_d
ETL 脚本命名:dim_product_mfrs_d.sh、dim_product_mfrs_d.py、dim_product_mfrs_d.hql、
dim_product_mfrs_d.jar
ETL 任务名称:dim_product_mfrs_d
图 6-1 ETL 脚本格式
数据的采集过程,
数仓的分层:ETL过程:python脚本。 hive脚本,sqoop迁移,oozie,azkaban,任务调度系统。
数据仓库是企业管理、维护和分析数据的关键体系,通过数据仓库的建立实现了企业内部数据的整合,并为不同的业务部门提供了同一的数据出口。
本项目深入探讨了数据仓库的基本理论、数据仓库建模基础、数据仓库数据采集与同步、数据仓库维度建模以及数据仓库规范,对数据仓库中的理论知识进行了详细梳理,对数据仓库中涉及到的各类概念进行了详细解析,并通过穿插于概念之间的实例展示了各个概念具体的实现方式。
希望通过对于本课程的学习,让学生掌握数据仓库的基本概念与搭建技巧,能够根据企业实际的业务需求对数据仓库进行维护或者创建新的数据仓库体系。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。