大家好,又见面了,我是你们的朋友全栈君。
目录
数据仓库最早的概念可以追溯到20世纪70年代MIT的一项研究,该研究致力于开发一种优化的技术架构并提出这些架构的指导性意见。
第一次,MIT的研究员将业务系统和分析系统分开,将业务处理和分析处理分成不同的层次,并采用单独的数据存储和完全不同的设计准则。同时,MIT的研究成果与80年代提出的信息中心(InformationCenter)相吻合:即把那些新出现的、不可以预测的、但是大量存在的分析型的负载从业务处理系统中剥离出来。
但是限于当时的信息处理和数据存储能力,该研究只是确立了一个论点:这两种信息处理的方式差别如此之大,以至于它们只能采用完全不同的架构和设计方法。
在80年代中后期,作为当时技术最先进的公司,DEC已经开始采用分布式网络架构来支持其业务应用,并且DEC公司首先将业务系统移植到其自身的RDBMS产品:RdB。并且,DEC公司从工程部、销售部、财务部以及信息技术部抽调了不同的人员组建了新的小组,不仅研究新的分析系统架构,并要求将其应用到其全球的财务系统中。该小组结合MIT的研究结论,建立了TA2(TechnicalArchitecture2)规范,该规范定义了分析系统的四个组成部分:
其中的数据获取和数据访问目前大家都很清楚,而目录服务是用于帮助用户在网络中找到他们想要的信息,类似于业务元数据管理;用户服务用以支持对数据的直接交互,包含了其他服务的所有人机交互界面,这是系统架构的一个非常大的转变,第一次将交互界面作为单独的组件提出来。
全企业集成(EnterpriseIntergration,1988)同时,IBM也在处理信息管理不同方面的问题,其最烦人的问题是不断增加的信息孤岛,IBM的很多客户要面对很多分立系统的数据集成问题,而这些系统有不同的编码方式和数据格式。
1988年,为解决全企业集成问题,IBM爱尔兰公司的BarryDevlin和PaulMurphy第一次提出了“信息仓库(InformationWarehouse)”的概念,将其定义为:“一个结构化的环境,能支持最终用户管理其全部的业务,并支持信息技术部门保证数据质量”,并在1991年在DECTA2的基础上把信息仓库的概念包含进去,并称之为VITAL规范,将PC、图形化界面、面向对象的组件以及局域网都包含在VITAL里,并定义了85种信息仓库的组件,包括数据抽取、转换、有效性验证、加载、Cube开发和图形化查询工具等。但是IBM只是将这种领先的概念用于市场宣传,而没有付诸实际的架构设计。这是IBM有一个领域上创新后停止不前导致丧失其领先地位。因此,在90年代初期,数据仓库的基本原理、框架架构,以及分析系统的主要原则都已经确定,主要的技术,包括关系型数据存取、网络、C/S架构和图形化界面均已具备,只欠东风了。
同时,在1988年-1991年,一些前沿的公司已经开始建立数据仓库。
企业级数据仓库(EDW,1991)1991年,BillInmon出版了其有关数据仓库的第一本书,这本书不仅仅说明为什么要建数据仓库、数据仓库能给你带来什么,更重要的是,Inmon第一次提供了如何建设数据仓库的指导性意见,该书定义了数据仓库非常具体的原则,包括:数据仓库是面向主题的(Subject-Oriented)、集成的(Integrated)、包含历史的(Time-variant)、相对稳定的(Nonvolatile)、面向决策支持的(DecisionSupport)面向全企业的(EnterpriseScope)最明细的数据存(AtomicDetail)数据快照式的数据获取(SnapShotCapture)这些原则到现在仍然是指导数据仓库建设的最基本原则,虽然中间的一些原则引发一些争论,并导致一些分歧和数据仓库变体的产生。
BillInmon凭借其这本书奠定了其在数据仓库建设的位置,被称之为“数据仓库之父”。
数据仓库发展的第一明显分歧是数据集市概念的产生。由于企业级数据仓库的设计、实施很困难,使得最早吃数据仓库螃蟹的公司遭到大面积的失败,因此数据仓库的建设者和分析师开始考虑只建设企业级数据仓库的一部分,然后再逐步添加,但是这有背于BillInmon的原则:各个实施部分的数据抽取、清洗、转换和加载是独立,导致了数据的混乱与不一致性。而且部分实施的项目也有很多失败,除了常见的业务需求定义不清、项目执行不力之外,很重要的原因是因为其数据模型设计,在企业级数据仓库中,Inmon推荐采用3范式进行数据建模,但是不排除其他的方法,但是Inmon的追随者固守OLTP系统的3范式设计,从而无法支持DSS系统的性能和数据易访问性的要求。
这时,Ralph Kimball出现了,他的第一本书“TheDataWarehouseToolkit”掀起了数据集市的狂潮,这本书提供了如何为分析进行数据模型优化详细指导意见,从DimensionalModeling大行其道,也为传统的关系型数据模型和多维OLAP之间建立了很好的桥梁。从此,数据集市在很多地方冒了出来,并获得很大成功,而企业级数据仓库已逐渐被人所淡忘。
企业级数据仓库还是部门级数据集市?关系型还是多维?BillInmon和RalphKimball一开始就争论不休,其各自的追随者也唇舌相向,形成相对立的两派:Inmon派和Kimball派(有点象少林和武当,呵呵)。
在初期,数据集市的快速实施和较高的成功率让Kimball派占了上风,但是很快,他们也发现自己陷入了某种困境:企业中存在6-7个不同的数据集市,分别有不同的ETL,相互之间的数据也不完全一致。同时,各个项目实施中也任意侵犯了Inmon开始定下的准则:把数据集市当成众多OLTP系统之后的有一个系统,而不是一个基础性的集成性的东西,为保证数据的准确性和实时性,有的甚至可以由OLTP系统直接修改数据集市里面的数据,为了保证系统的性能,有的数据集市删除了历史数据。等等,不一而足。
当然,这导致了一些新的应用的出现,例如ODS,但是人们对DataWarehouse、DataMart、ODS的概念非常的模糊,经常混为一谈。有人说OLAP就是数据仓库,也有人说我要ODS和DataMart,不要Datawarehouse,也有人说,我DataMart建多了,自然就有DataWarehouse了。但是BillInmon一直很旗帜鲜明:“你可以打到几万吨的小鱼小虾,但是这些小鱼小虾加起来不是大鲸鱼”。
经过多翻争吵,证明one-size-fits-all是不可能的,你需要不同的BI架构来满足不同的业务需求。BillInmon也推出了新的BI架构CIF(Corporationinformationfactory),把Kimball的数据集市也包容进来了,第一次,Kimball承认了Inmon,但是仍然还有很多人在争论是自顶向下,还是自底向上。
未来几个方向:时效性方向的实时数仓;数据质量方向的数据治理;数据中台、数据湖(欢迎留言讨论!)
大数据时代,维度建模已成为各大厂的主流方式。
维度建模从分析决策的需求出发构建模型,为分析需求服务。重点关注用户如何快速的完成数据分析,可以直观的反应业务模型中的业务问题,需要大量的数据预处理、数据冗余,有较好的大规模复杂查询的响应性能。
维度建模按数据组织类型划分可分为星型模型、雪花模型、星座模型。Kimball老爷爷维度建模四部曲:
选择业务处理过程 > 定义粒度 > 选择维度 > 确定事实
2.1.1 星型模型
星型模型主要是维表和事实表,以事实表为中心,所有维度直接关联在事实表上,呈星型分布。
2.1.2 雪花模型
雪花模型,在星型模型的基础上,维度表上又关联了其他维度表。这种模型维护成本高,性能方面也较差,所以一般不建议使用。尤其是基于hadoop体系构建数仓,减少join就是减少shuffle,性能差距会很大。
星型模型可以理解为,一个事实表关联多个维度表,雪花模型可以理解为一个事实表关联多个维度表,维度表再关联维度表。
2.1.3 星座模型
星座模型,是对星型模型的扩展延伸,多张事实表共享维度表。
星座模型是很多数据仓库的常态,因为很多数据仓库都是多个事实表的。所以星座模型只反映是否有多个事实表,他们之间是否共享一些维度表。
即实体关系(ER)模型,数据仓库之父Immon提出的,从全企业的高度设计一个3NF模型,用实体加关系描述的数据模型描述企业业务架构,在范式理论上符合3NF。此建模方法,对建模人员的能力要求非常高。
特点:设计思路自上而下,适合上游基础数据存储,同一份数据只存储一份,没有数据冗余,方便解耦,易维护,缺点是开发周期一般比较长,维护成本高。
详见后文:三范式与反范式
DataVault由Hub(关键核心业务实体)、Link(关系)、Satellite(实体属性) 三部分组成 ,是Dan Linstedt发起创建的一种模型方法论,它是在ER关系模型上的衍生,同时设计的出发点也是为了实现数据的整合,并非为数据决策分析直接使用。
高度可扩展的模型,所有的扩展只是添加而不是修改,因此它将模型规范到6NF,基本变成了K-V结构模型。企业很少使用。
信息技术智库关注领取技术资料、面试真题、简历模板和PPT模板;一起交流工作难题、面试套路、职场经验、内推直通车公众号
数据模型建设的怎么样,极度依赖规范设计,如果代码风格是“千人千面”,那么恐怕半年下来,业务系统就没法看了。没有什么比“数据系统”更看重“法制”了,规范体系不仅能保障数据建设的一致性,也能够应对业务交接的情况,更能够为自动化奠定基础。
小编有话
事实表作为数据仓库维度建模的核心,紧紧围绕着业务过程来设 计,通过获取描述业务过程的度量来表达业务过程,包含了引用的维度 和与业务过程有关的度量。
事实表有三种类型 : 事务事实表、周期快照事实表和累积快照事实表。
也称原子事实表,描述业务过程,跟踪控件或时间上某点的度量事件,保存的是最原子的数据;
个人理解:类似于mysql binlog日志,每一次相关的 change 都记录下来,生成一行新的数据
以一个周期为时间间隔,来记录事实,一般周期可以是每天、每周、每月、每年等;
个人理解:只看某个业务过程,比如订单收货,数据按订单收货时间来切分,周期可以为每天、每月等。
用来描述过程开始和结束之间的关键步骤事件,覆盖过程的整个生命周期,通常具有多个日期字段来记录关键时间点;当过程随着生命周期不断变化时,记录也会随着过程的变化而被修改;
个人理解:要看整个生命周期的多个业务过程,比如:创建订单 → 买家付款 → 卖家发货 → 买家确认收货。粒度是一个订单一行数据,创建订单时间,付款时间,发货时间,收货时间,分别作为一个字段,便于计算不同业务过程的时间间隔。
事务事实表 | 周期快照事实表 | 累积快照事实表 | |
---|---|---|---|
时期/时间 | 离散事务时间点 | 以有规律的、可预测的 | 用于时间跨度不确定的不断变化的工作流 |
日期维度 | 事务日期 | 快照日期 | 相关业务过程涉及的多个日期 |
粒度 | 每行代表实体的一个事务 | 每行代表某时间周期的一个实体 | 每行代表一个实体的生命周期 |
事实 | 事务事实 | 累积事实 | 相关业务过程事实和时间间隔事实 |
事实表加载 | 插入 | 插入 | 插入与更新 |
事实表更新 | 不更新 | 不更新 | 业务过程变更时更新 |
Kimball 的维度模型设计 4 步法:选择业务过程、声明粒度、确定维度、确定事实;
当前的互联网大数据环境,维度模型的设计,是基于 Kimball 的四步维度建模方法进行了更进一步的改进:
在Kimball的维度建模的数据仓库中,关于多维体系结构(MD)有三个关键性概念:总线架构(Bus Architecture),一致性维度(Conformed Dimension)和一致性事实(Conformed Fact)。
多维体系结构(总线架构) 数据仓库领域里,有一种构建数据仓库的架构,叫Multidimensional Architecture(MD),中文一般翻译为“多维体系结构”,也称为“总线架构”(Bus Architecture)。
多维体系结构的创始人是数据仓库领域中最有实践经验的Kimball博士。多维体系结构主要包括后台(Back Room)和前台(Front Room)两部分。后台也称为数据准备区(Staging Area),是MD架构的最为核心的部件。在后台,是一致性维度的产生、保存和分发的场所。同时,代理键也在后台产生。前台是MD架构对外的接口,包括两种主要的数据集市,一种是原子数据集市,另一种是聚集数据集市。
原子数据集市保存着最低粒度的细节数据,数据以星型结构来进行数据存储。聚集数据集市的粒度通常比原子数据集市要高,和原子数据集市一样,聚集数据集市也是以星型结构来进行数据存储。前台还包括像查询管理、活动监控等为了提供数据仓库的性能和质量的服务。在多维体系结构中,所有的这些基于星型机构来建立的数据集市可以在物理上存在于一个数据库实例中,也可以分散在不同的机器上,而所有这些数据集市的集合组成的分布式的数据仓库。
在多维体系结构中,没有物理上的数据仓库,由物理上的数据集市组合成逻辑上的数据仓库。而且数据集市的建立是可以逐步完成的,最终组合在一起,成为一个数据仓库。如果分步建立数据集市的过程出现了问题,数据集市就会变成孤立的集市,不能组合成数据仓库,而一致性维度的提出正式为了解决这个问题。
一致性维度的范围是总线架构中的维度,即可能会在多个数据集市中都存在的维度,这个范围的选取需要架构师来决定。一致性维度的内容和普通维度并没有本质上区别,都是经过数据清洗和整合后的结果。 一致性维度建立的地点是多维体系结构的后台(Back Room),即数据准备区。
在多维体系结构的数据仓库项目组内需要有专门的维度设计师,他的职责就是建立维度和维护维度的一致性。在后台建立好的维度同步复制到各个数据集市。这样所有数据集市的这部分维度都是完全相同的。建立新的数据集市时,需要在后台进行一致性维度处理,根据情况来决定是否新增和修改一致性维度,然后同步复制到各个数据集市。这是不同数据集市维度保持一致的要点。
在同一个集市内,一致性维度的意思是两个维度如果有关系,要么就是完全一样的,要么就是一个维度在数学意义上是另一个维度的子集。
例如,如果建立月维度话,月维度的各种描述必须与日期维度中的完全一致,最常用的做法就是在日期维度上建立视图生成月维度。这样月维度就可以是日期维度的子集,在后续钻取等操作时可以保持一致。如果维度表中的数据量较大,出于效率的考虑,应该建立物化视图或者实际的物理表。这样,维度保持一致后,事实就可以保存在各个数据集市中。虽然在物理上是独立的,但在逻辑上由一致性维度使所有的数据集市是联系在一起,随时可以进行交叉探察等操作,也就组成了数据仓库。
在建立多个数据集市时,完成一致性维度的工作就已经完成了一致性的80%-90%的工作量。余下的工作就是建立一致性事实。一致性事实和一致性维度有些不同,一致性维度是由专人维护在后台(Back Room),发生修改时同步复制到每个数据集市,而事实表一般不会在多个数据集市间复制。需要查询多个数据集市中的事实时,一般通过交叉探查(drill across)来实现。
为了能在多个数据集市间进行交叉探查,一致性事实主要需要保证两点:第一个是KPI的定义及计算方法要一致,第二个是事实的单位要一致性。如果业务要求或事实上就不能保持一致的话,建议不同单位的事实分开建立字段保存。
这样,一致性维度将多个数据集市结合在一起,一致性事实保证不同数据集市间的事实数据可以交叉探查,一个分布式的数据仓库就建成了。
小遍有话
追求一致性必然会增加开发工作量,但长期来说,使用方便、运维简单;一致性和性能之间,需要平衡。
无规矩、不方圆。规范设计是在具体开发工作之前制定的,过程中不断进行完善。目的在于约束 N 个人对齐认知,按照一个标准或流程进行开发,以保证数据一致性,流程清晰且稳定。
一个良好的规范设计,应当起到以下作用:提高开发效率,提升质量,降低沟通对齐成本,降低运维成本等。
下面西红柿🍅将带领大家盘一盘数据仓库有哪些规范,从中挑选几个重点细说:
逻辑架构、技术架构、分层设计、主题划分、方法论
各层级命名、任务命名、表命名、字段命名、指标命名等
建模方法、建模工具、血缘关系、维度退化、一致性维度、元数据管理
脚本注释、字段别名、编码规范、脚本格式、数据类型、缩写规范
需求流程、工程流程、上线流程、调度流、调度和表生命周期管理
为了提高指标管理的效率,你需要按照业务线、主题域和业务过程三级目录方式管理指标。
原子指标 + 原子指标 = 派生指标
需要遵循两个原则:易懂与统一
对于原子指标,标名称适合用“动作 + 度量”的命名方式(比如注册用户数、购买用户数)
对于派生指标,应该严格遵循“时间周期 + 统计粒度 + 修饰词 + 原子指标”的命名方式。(比如30天内黑卡会员购买用户数)
指标确实是多,如果一视同仁去管理其实很难,所以可以按照下面的原则进行等级划分:
常规表是我们需要固化的表,是正式使用的表,是目前一段时间内需要去维护去完善的表。
规范:分层前缀[dwd|dws|ads|bi]_业务域_主题域_XXX_更新频率|全量/增量。
业务域、主题域我们都可以用词根的方式枚举清楚,不断完善,粒度也是同样的,主要的是时间粒度、日、月、年、周等,使用词根定义好简称。
建议格式: dwd_xxx_xxx_da
中间表一般出现在Job中,是Job中临时存储的中间数据的表,中间表的作用域只限于当前Job执行过程中,Job一旦执行完成,该中间表的使命就完成了,是可以删除的(按照自己公司的场景自由选择,以前公司会保留几天的中间表数据,用来排查问题)。
建议格式:mid_table_name_[0~9]
table_name是我们任务中目标表的名字,通常来说一个任务只有一个目标表。这里加上表名,是为了防止自由发挥的时候表名冲突,而末尾大家可以选择自由发挥,起一些有意义的名字,或者简单粗暴,使用数字代替,各有优劣吧,谨慎选择。
临时表是临时测试的表,是临时使用一次的表,就是暂时保存下数据看看,后续一般不再使用的表,是可以随时删除的表。
建议格式:tmp_xxx
只要加上tmp开头即可,其他名字随意,注意tmp开头的表不要用来实际使用,只是测试验证而已。
维度表是基于底层数据,抽象出来的描述类的表。维度表可以自动从底层表抽象出来,也可以手工来维护。
建议格式:dim_xxx
维度表,统一以dim开头,后面加上,对该指标的描述,可以自由发挥。
1 | 表和列的注释释是否有缺失,复杂计算逻辑是否有注释释 |
---|---|
2 | 任务是否支持多次重跑而输出不变,不能有insert into语句 |
3 | 分区表是否使用分区键过滤并且有有效裁剪 |
4 | 外连接的过逑条件是否使用正确,例如在左连接的where语句存在右表的过滤条件 |
5 | 关联小表,是否使用/*+ map join * / hint |
6 | 不允许引用别的计算任务临时表 |
7 | 原则上不允许存在一个任务更新多个目标表 |
8 | 是否存在笞、迪卡尔积 |
9 | 禁止在代码里面使用drop 111ble、creat它111ble、renaiue 111ble、chan零column等ddl语句 |
10 | 使用动态分区时,有没有检查分区键值为NULL的情况 |
11 | DQC质量监控规则是否配置,严禁棵奔 |
12 | 代码中有没有进行适当的规避数据倾斜语句 |
13 | Where条件中is null语句有没有进行空字符串处理 |
根据阿里流程规范,本文将数据仓库研发流程抽象为如下几点:
管理领域相关,包括管理流程、人员组织、角色职责等。
在日常工作中,元数据的管理主要体现在元数据的采集、存储、查询、应用几个方面。原则上应从规范化,到脚本化,到工具化的方向进行建设。
维度是维度建模的基础和灵魂。在维度建模中,将度量称为“事实” , 将环境描述为“维度”。
维度表包含了事实表中指定属性的相关详细信息,最常用的维度表有日期维度、城市维度等。
日期维表:
num | 字段名 | 字段中文名 | 描述 | 数据类型 |
---|---|---|---|---|
1 | date | 日期 | 日期 yyyMMdd格式 | bigint |
2 | week | 星期,数字型 | 星期,数字型 0-6 | bigint |
3 | week_cn | 星期中文名 | 星期中文名 星期一…… | string |
4 | year_weeks | 一年中的第几周 | 一年中的第几周 1 2 3…… | bigint |
5 | mon_dt | 本周周一日期 | 本周周一日期 | bigint |
6 | sun_dt | 本周周日日期 | 本周周日日期 | bigint |
7 | month | 年月 | 年月,yyyyMM格式 | bigint |
8 | month_short | 月份简写 | 月份简写,MM格式1~12 | bigint |
9 | month_cn | 月份中文名 | 月份中文名 一月…… | string |
10 | quarter | 季度 | 季度,yyyyQ1\2\3\4 | string |
11 | quarter_short | 季度 数字型 | 季度 数字型 1-4 | bigint |
12 | quarter_cn | 季度中文名 | 季度中文名 第一季度…… | string |
13 | year | 年份 | 年份,yyyy格式 | bigint |
维度的作用一般是查询约束、分类汇总以及排序等,我们在进行维度表设计时,应当提前考虑:
(1)维度属性尽量丰富,为数据使用打下基础
比如淘宝商品维度有近百个维度属性,为下游的数据统计、分析、探查提供了良好的基础。
(2)给出详实的、富有意义的文字描述
属性不应该是编码,而应该是真正的文字。在间里巴巴维度建模中, 一般是编码和文字同时存在,比如商品维度中的商品 ID 和商品标题、 类目 ID 和 类目名称等。ID 一 般用于不同表之间的关联,而名称一般用 于报表标签
(3)区分数值型属性和事实
数值型宇段是作为事实还是维度属性,可以参考字段的一般用途。如果通常用于查询约束条件或分组统计,则是作为维度属性;如果通常 用于参与度量的计算, 则是作为事实。比如商品价格,可以用于查询约 束条件或统计价格区间 的商品数量,此时是作为维度属性使用的;也可 以用于统计某类目 下商品的平均价格,此时是作为事实使用的。另外, 如果数值型字段是离散值,则作为维度属性存在的可能性较大;如果数 值型宇段是连续值 ,则作为度量存在的可能性较大,但并不绝对,需要 同时参考宇段的具体用途。
(4)沉淀出通用的维度属性,为建立一致性维度做好铺垫
有些维度属性获取需要进行比较复杂的逻辑处理,有些需要通过多表关联得到,或者通过单表 的不同宇段混合处理得到,或者通过对单表 的某个字段进行解析得到。此时,需要将尽可能多的通用的维度属性进 行沉淀。一方 面,可以提高下游使用的方便性,减少复杂度;另一方面,可以避免下游使用解析时由于各自逻辑不同而导致口径不 一致。
(5)退化维度(Degenerate Dimension)
在维度类型中,有一种重要的维度称作为退化维度。这种维度指的是直接把一些简单的维度放在事实表中。退化维度是维度建模领域中的一个非常重要的概念,它对理解维度建模有着非常重要的作用,退化维度一般在分析中可以用来做分组使用。
(6)缓慢变化维(Slowly Changing Dimensions)
维度的属性并不是始终不变的,它会随着时间的流逝发生缓慢的变化,这种随时间发生变化的维度我们一般称之为缓慢变化维(SCD),缓慢变化维一般使用代理健作为维度表的主健。
推荐阅读:缓慢变化维度的10种处理方式
① TYPE1 直接覆盖原值
适用于:不看历史数据,简单粗暴
② TYPE2 拉链表
需要在维度行再增加三列:有效日期、截止日期、行标识(可选)。
在旧的一行数据增加关链时间(end_date),新的一行数据增加开链时间和关链时间,多条数据加起来是一个完整的时间周期。
③ TYPE3 增加属性列
范式是符合某一种级别的关系模式的集合。构造数据库必须遵循一定的规则。在关系数据库中,这种规则就是范式。
关系数据库中的关系必须满足一定的要求,即满足不同的范式。大数据生态中,各类强大的查询引擎层出不穷,相对廉价的磁盘和分布式技术,也让数据冗余变得可接受甚至更加方便。
在创建一个数据库的过程中,范化是将其转化为一些表的过程,这种方法可以使从数据库得到的结果更加明确。这样可能使数据库产生重复数据,从而导致创建多余的表。范化是在识别数据库中的数据元素、关系以及定义所需的表和各表中的项目等这些初始工作之后的一个细化的过程。
1NF要求属性具有原子性,即列不可再分解;
表:字段1、 字段2(字段2.1、字段2.2)、字段3 ……
如学生(学号,姓名,性别,出生年月日)
有些钢筋可能要问西红柿了,姓名可以拆成姓、名两列, “出生年月日” 也可以拆成年、月、日三个字段。所以就不满足第一范式了!!!这里再强调一下原子性,原子性是根据使用方便来自定义的最小单位。中国人一般姓名一起用,美国就习惯姓名分别存两字段。
2NF要求记录有惟一标识,即不存在部分依赖;
简单来说就是拆表,以人为粒度做一张明细表,以课程号为粒度做一张维度表,两表关联使用,消除了数据冗余
表:学号、课程号、姓名、学分;
这个表明显说明了两个事务:学生信息, 课程信息;由于非主键字段必须依赖主键,这里学分依赖课程号,姓名依赖与学号,所以不符合二范式。
可能会存在问题:
正确做法: 学生:Student(学号, 姓名); 课程:Course(课程号, 学分); 选课关系:StudentCourse(学号, 课程号, 成绩)。
3NF是对字段的冗余性,要求任何字段不能由其他字段派生出来,它要求字段没有冗余,即不存在传递依赖;
表: 学号, 姓名, 年龄, 学院名称, 学院电话
因为存在依赖传递: (学号) → (学生)→(所在学院) → (学院电话) 。
可能会存在问题:
正确做法:
学生:(学号, 姓名, 年龄, 所在学院);
学院:(学院, 电话)。
一般说来,数据库只需满足第三范式(3NF)就行了。
没有冗余的数据库设计可以做到。但是,没有冗余的数据库未必是最好的数据库,有时为了提高运行效率,就必须降低范式标准,适当保留冗余数据。具体做法是:在概念数据模型设计时遵守第三范式,降低范式标准的工作放到物理数据模型设计时考虑。降低范式就是增加字段,允许冗余,达到以空间换时间的目的。
〖例〗:有一张存放商品的基本表,如表1所示。“金额”这个字段的存在,表明该表的设计不满足第三范式,因为“金额”可以由“单价”乘以“数量”得到,说明“金额”是冗余字段。但是,增加“金额”这个冗余字段,可以提高查询统计的速度,这就是以空间换时间的作法。
在Rose 2002中,规定列有两种类型:数据列和计算列。“金额”这样的列被称为“计算列”,而“单价”和“数量”这样的列被称为“数据列”。
优点:
缺点:
反范式的过程就是通过冗余数据来提高查询性能,但冗余数据会牺牲数据一致性
优点:
缺点:
OLAP 一般冗余比较多,以查询分析为主,这种一般都是采用反范式设计,以提高查询效率。更新一般是定时大批量数据插入。
OLTP 则是尽可能消除冗余,以提高变更的效率。因为这种应用无时无刻不在频繁变化。
随着数据量的暴增和数据实时性要求越来越高,以及大数据技术的发展驱动企业不断升级迭代,数据仓库架构方面也在不断演进,分别经历了以下过程:早期经典数仓架构 > 离线大数据架构 > Lambda > Kappa > 混合架构。
架构 | 组成 | 特点 |
---|---|---|
经典数仓架构 | 关系型数据库(mysql、oracle)为主 | 数据量小,实时性要求低 |
离线大数据架构 | hive,spark为主 | 数据量大,实时性要求低 |
Lambda | hive,spark负责存量,strom/Flink负责实时计算 | 数据量大,实时性要求高 |
Kappa | kafka、strom、Flink | 多业务,多数据源,事件型数据源 |
混合架构 |
ps.西红柿的举例若有不当,欢迎指正
Lambda架构的核心思想是把大数据系统拆分成三层:Batch Layer,Speed Layer和Serving Layer。其中,Batch Layer负责数据集存储以及全量数据集的预查询。
Speed Layer主要负责对增量数据进行计算,生成Realtime Views。Serving Layer用于响应用户的查询请求,它将Batch Views和Realtime Views的结果进行合并,得到最后的结果,返回给用户,如下图:
Lambda架构解决了大数据量下实时计算的问题,但架构本身也存在一定缺点。
Kappa架构的核心思想包括以下三点:
项目 | Lambda | Kappa |
---|---|---|
数据处理能力 | 可以处理超大规模的历史数据 | 历史数据处理的能力有限 |
机器开销 | 批处理和实时计算需一直运行,机器开销大 | 必要时进行全量计算,机器开销相对较小 |
存储开销 | 只需要保存一份查询结果,存储开销较小 | 需要存储新老实例结果,存储开销相对较大 |
开发、测试难度 | 实现两套代码,开发、测试难度较大 | 只需面对一个框架,开发、测试难度相对较小 |
运维成本 | 维护两套系统,运维成本大 | 只需维护一个框架,运维成本小 |
目前很多准实时增量批处理方案也能满足实时性需求,从稳定性和运维成本上也表现更佳。
比如kudu(存储)+impala(计算)准实时方案,可以实现千万级数据的增量更新和olap查询,性能优异。
数据治理(Data Governance)是组织中涉及数据使用的一整套管理行为。由企业数据治理部门发起并推行,关于如何制定和实施针对整个企业内部数据的商业应用和技术管理的一系列政策和流程。
数据的质量直接影响着数据的价值,并且直接影响着数据分析的结果以及我们以此做出的决策的质量。
我们常说,用数据说话,用数据支撑决策管理,但低质量的数据、甚至存在错误的数据,必然会”说假话”!!!数据治理即提高数据的质量,发挥数据资产价值。
从技术实施角度看,数据治理包含“理”“采”“存”“管”“用”这五个步骤,即业务和数据资源梳理、数据采集清洗、数据库设计和存储、数据管理、数据使用。
数据资源梳理:数据治理的第一个步骤是从业务的视角厘清组织的数据资源环境和数据资源清单,包含组织机构、业务事项、信息系统,以及以数据库、网页、文件和 API 接口形式存在的数据项资源,本步骤的输出物为分门别类的数据资源清单。
数据采集清洗:通过可视化的 ETL 工具(例如阿里的 DataX,Pentaho Data Integration)将数据从来源端经过抽取 (extract)、转换 (transform)、加载 (load) 至目的端的过程,目的是将散落和零乱的数据集中存储起来。
基础库主题库建设:一般情况下,可以将数据分为基础数据、业务主题数据和分析数据。基础数据一般指的是核心实体数据,或称主数据,例如智慧城市中的人口、法人、地理信息、信用、电子证照等数据。主题数据一般指的是某个业务主题数据,例如市场监督管理局的食品监管、质量监督检查、企业综合监管等数据。而分析数据指的是基于业务主题数据综合分析而得的分析结果数据,例如市场监督管理局的企业综合评价、产业区域分布、高危企业分布等。那么基础库和主题库的建设就是在对业务理解的基础上,基于易存储、易管理、易使用的原则抽像数据存储结构,说白了,就是基于一定的原则设计数据库表结构,然后再根据数据资源清单设计数据采集清洗流程,将整洁干净的数据存储到数据库或数据仓库中。
元数据管理:元数据管理是对基础库和主题库中的数据项属性的管理,同时,将数据项的业务含义与数据项进行了关联,便于业务人员也能够理解数据库中的数据字段含义,并且,元数据是后面提到的自动化数据共享、数据交换和商业智能(BI)的基础。需要注意的是,元数据管理一般是对基础库和主题库中(即核心数据资产)的数据项属性的管理,而数据资源清单是对各类数据来源的数据项的管理。
血缘追踪:数据被业务场景使用时,发现数据错误,数据治理团队需要快速定位数据来源,修复数据错误。那么数据治理团队需要知道业务团队的数据来自于哪个核心库,核心库的数据又来自于哪个数据源头。我们的实践是在元数据和数据资源清单之间建立关联关系,且业务团队使用的数据项由元数据组合配置而来,这样,就建立了数据使用场景与数据源头之间的血缘关系。数据资源目录:数据资源目录一般应用于数据共享的场景,例如政府部门之间的数据共享,数据资源目录是基于业务场景和行业规范而创建,同时依托于元数据和基础库主题而实现自动化的数据申请和使用。
质量管理:数据价值的成功发掘必须依托于高质量的数据,唯有准确、完整、一致的数据才有使用价值。因此,需要从多维度来分析数据的质量,例如:偏移量、非空检查、值域检查、规范性检查、重复性检查、关联关系检查、离群值检查、波动检查等等。需要注意的是,优秀的数据质量模型的设计必须依赖于对业务的深刻理解,在技术上也推荐使用大数据相关技术来保障检测性能和降低对业务系统的性能影响,例如 Hadoop,MapReduce,HBase 等。
商业智能(BI):数据治理的目的是使用,对于一个大型的数据仓库来说,数据使用的场景和需求是多变的,那么可以使用 BI 类的产品快速获取需要的数据,并分析形成报表,比较知名的产品有 Microsoft Power BI,QlikView,Tableau,帆软等。
数据共享交换:数据共享包括组织内部和组织之间的数据共享,共享方式也分为库表、文件和 API 接口三种共享方式,库表共享比较直接粗暴,文件共享方式通过 ETL 工具做一个反向的数据交换也就可以实现。我们比较推荐的是 API 接口共享方式,在这种方式下,能够让中心数据仓库保留数据所有权,把数据使用权通过 API 接口的形式进行了转移。API 接口共享可以使用 API 网关实现,常见的功能是自动化的接口生成、申请审核、限流、限并发、多用户隔离、调用统计、调用审计、黑白名单、调用监控、质量监控等等。
数据采集值或者观测值和真实值之间的接近程度,也叫做误差值,误差越大,准确度越低。
指对同一对象的观测数据在重复测量时所得到不同数据间的接近程度。
数据能否在需要的时候得到保证,比如月初的财务对账,能不能在月初就完成
指数据采集时间节点和数据传输的时间节点,一个数据在数据源头采集后立即存储,并立即加工呈现,就是即时数据,而经过一段时间之后再传输到信息系统中,则数据即时性就稍差。
应采集和实际采集到数据之间的比例。
完整性衡量的是应采集和实际采集的差异。而全面性指的是数据采集点的遗漏情况。
指各个数据集之间的关联关系。比如员工工资数据和员工绩效考核数据是通过员工这个资源关联在一起来的。
信息技术智库关注领取技术资料、面试真题、简历模板和PPT模板;一起交流工作难题、面试套路、职场经验、内推直通车公众号
基本流程:发现数据质量问题 > 定义数据质量规则 > 质量控制 > 质量评估 > 质量优化
ETL,是英文Extract-Transform-Load的缩写,用来描述将数据从来源端经过抽取(extract)、转换(transform)、加载(load)至目的端的过程,是数据仓库的生命线。
抽取(Extract)主要是针对各个业务系统及不同服务器的分散数据,充分理解数据定义后,规划需要的数据源及数据定义,制定可操作的数据源,制定增量抽取和缓慢渐变的规则。
转换(transform)主要是针对数据仓库建立的模型,通过一系列的转换来实现将数据从业务模型到分析模型,通过ETL工具可视化拖拽操作可以直接使用标准的内置代码片段功能、自定义脚本、函数、存储过程以及其他的扩展方式,实现了各种复杂的转换,并且支持自动分析日志,清楚的监控数据转换的状态并优化分析模型。
装载(Load)主要是将经过转换的数据装载到数据仓库里面,可以通过直连数据库的方式来进行数据装载,可以充分体现高效性。在应用的时候可以随时调整数据抽取工作的运行方式,可以灵活的集成到其他管理系统中。
伴随着数据仓库的发展(传送门:数据仓库的八个发展阶段),数据量从小到大,数据实时性从T+1到准实时、实时,ETL也在不断演进。
即:Extract-Transform-Load >> Extract-Load-Transform
通常我们所说的ETL,已经泛指数据同步、数据清洗全过程,而不仅限于数据的抽取-转换-加载。
下面小编将介绍几类ETL工具(sqoop,DataX,Kettle,canal,StreamSets)。
只有新增(full join。能拿更新表就拿更新表)
每天一个全量表,也可一个hive天分区一个全量。
使用kafka,消费mysql binlog日志到目标库,源表和目标库是1:1的镜像。
无论是全量还是增量的方式,都会浪费多余的存储或通过计算去重,得到最新的全量数据。为解决这一问题,西红柿墙裂建议kafka的数据同步方案,源表变化一条,目标表消费一条,目标表数据始终是一份最新全量数据,且为实时同步的。
ps.极端情况下可能会丢数,需要写几个监控脚本(详见上文数据质量部分)和补数脚本即可~
OLTP | OLAP | |
---|---|---|
对象 | 业务开发人员 | 分析决策人员 |
功能 | 日常事务处理 | 面向分析决策 |
模型 | 关系模型 | 多维模型 |
数据量 | 几条或几十条记录 | >百万于万条记录 |
操作类型 | 增、删、查、改(CRUD) | 查询为主 |
总体概括 | 联机事务处理 | 在线分析处理 |
1.1 hadoop中的数据倾斜表现
1.2 hive中数据倾斜
一般都发生在Sql中group by和join on上,而且和数据逻辑绑定比较深。
1.3 Spark中的数据倾斜
Spark中的数据倾斜,包括Spark Streaming和Spark Sql,表现主要有下面几种:
我们以Spark和Hive的使用场景为例。
在做数据运算的时候会涉及到,count distinct、group by、join on等操作,这些都会触发Shuffle动作。一旦触发Shuffle,所有相同key的值就会被拉到一个或几个Reducer节点上,容易发生单点计算问题,导致数据倾斜。
一般来说,数据倾斜原因有以下几方面:
1)key分布不均匀;
2)建表时考虑不周
举一个例子,就说数据默认值的设计吧,假设我们有两张表:
user(用户信息表):userid,register_ip
ip(IP表):ip,register_user_cnt
这可能是两个不同的人开发的数据表。如果我们的数据规范不太完善的话,会出现一种情况:
user表中的register_ip字段,如果获取不到这个信息,我们默认为null;
但是在ip表中,我们在统计这个值的时候,为了方便,我们把获取不到ip的用户,统一认为他们的ip为0。
两边其实都没有错的,但是一旦我们做关联了,这个任务会在做关联的阶段,也就是sql的on的阶段卡死。
3)业务数据激增
比如订单场景,我们在某一天在北京和上海两个城市多了强力的推广,结果可能是这两个城市的订单量增长了10000%,其余城市的数据量不变。
然后我们要统计不同城市的订单情况,这样,一做group操作,可能直接就数据倾斜了。
很多数据倾斜的问题,都可以用和平台无关的方式解决,比如更好的数据预处理,异常值的过滤等。因此,解决数据倾斜的重点在于对数据设计和业务的理解,这两个搞清楚了,数据倾斜就解决了大部分了。
1)业务逻辑
我们从业务逻辑的层面上来优化数据倾斜,比如上面的两个城市做推广活动导致那两个城市数据量激增的例子,我们可以单独对这两个城市来做count,单独做时可用两次MR,第一次打散计算,第二次再最终聚合计算。完成后和其它城市做整合。
2)程序层面
比如说在Hive中,经常遇到count(distinct)操作,这样会导致最终只有一个Reduce任务。
我们可以先group by,再在外面包一层count,就可以了。比如计算按用户名去重后的总用户量:
(1)优化前
只有一个reduce,先去重再count负担比较大:
select name,count(distinct name)from user;
(2)优化后
// 设置该任务的每个job的reducer个数为3个。Hive默认-1,自动推断。
set mapred.reduce.tasks=3;
// 启动两个job,一个负责子查询(可以有多个reduce),另一个负责count(1):
select count(1) from (select name from user group by name) tmp;
3)调参方面
Hadoop和Spark都自带了很多的参数和机制来调节数据倾斜,合理利用它们就能解决大部分问题。
4)从业务和数据上解决数据倾斜
很多数据倾斜都是在数据的使用上造成的。我们举几个场景,并分别给出它们的解决方案。
一个原则:尽早过滤每个阶段的数据量。
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/135350.html原文链接:https://javaforall.cn