数据仓库 (英语:Data Warehouse,简称数仓、DW)是一个为数据分析而设计的企业级数据管理系统。它旨在 支持企业决策过程中的数据分析和业务智能 。数据仓库的基本原理是将不同来源的数据整合到一个中心存储库中,以提供一致的数据视图和易于理解的分析结果。
具体来说,数据仓库提供以下服务:
通过提供这些服务,数据仓库可以帮助企业更好地理解业务、预测趋势、制定战略,并提升企业的决策水平和竞争力。
数据仓库的建设步骤:
数据仓库可以通过多种方式进行建模,其中最常用的是 星型模型和雪花模型 。星型模型将事实表(Fact Table)与多个维度表(Dimension Table)连接起来,每个维度表都描述了一个独立的主题,例如时间、地点、产品等。而雪花模型则是在星型模型的基础上,将一些维度表进一步细分为多个子表,以实现更细粒度的数据存储和查询。
数据仓库的优点包括:
数据仓库的建设存在的挑战和难点:
总之,数据仓库是企业决策过程中的重要组成部分,它可以提供一致的数据视图、支持复杂的查询和分析、改善决策过程、增强数据质量和支持增量更新。但是,数据仓库的建设也存在一些挑战和难点,需要专业的技术和经验支持。
数据库一般用于处理业务数据,数据仓库一般用于做数据分析,因此,虽然它们都涉及到数据的存储和管理,但是在很多方面存在着显著的差异。
使用领域
数据库用于联机事务处理(Online Transaction Processing,OLTP),主要用于管理日常的业务事务,例如交易记录和实时库存管理。
数据仓库用于联机分析处理(Online Analysis Processing,OLAP),主要用于快速分析大型多维数据集,例如多维分析、数据挖掘和预测等。
数据特点
数据库一般用来存储当前事务性数据,如交易数据;数据仓库一般存储的是历史数据。
数据库中数据是由日常的业务产生的,并且是频繁更新的;数据仓库中数据来源多样化,经过一定的规则转换得到的,用于分析和决策。
管理特点
数据库设计一般符合三范式,有最大的精确度和最小的冗余度,有利于数据的插入;数据仓库设计一般不符合三范式,有利于查询。
数据仓库 是指为企业决策支持服务的一种专用数据存储,它将来自各个数据源的数据进行提取、转换和加载(ETL),并存储到一个或多个数据仓库中。数据仓库通常是面向主题、集成的、稳定的、可伸缩的、可重复的和易于使用的。
数据仓库技术包括以下几个方面:
ETL(Extract-Transform-Load): 从各种数据源中提取数据,进行转换和清洗,最终将数据加载到数据仓库中。ETL 是数据仓库的基础,可以保证数据的质量和一致性。
数据建模: 数据建模是设计和构建数据仓库的过程。数据仓库通常采用维度建模(Dimensional Modeling)或实体关系建模(Entity-Relationship Modeling)。
数据存储: 数据仓库通常采用关系数据库或列式数据库来存储数据。
OLAP(Online Analytical Processing): OLAP 是一种面向多维数据分析的技术。数据仓库通常采用 OLAP 技术来支持数据分析和报表查询等功能。
数据可视化: 数据仓库通常需要通过数据可视化的方式来展示数据分析结果,例如使用数据报表、数据可视化工具等。
数仓技术已经成为企业决策支持的重要基础设施,广泛应用于金融、零售、物流、医疗等领域,帮助企业更好地理解业务、预测趋势、制定战略。
ETL 是指数据提取(Extraction)、数据转换(Transformation)和数据加载(Loading)三个步骤的缩写。ETL是数据仓库建设中非常重要的环节,它的主要目的是将分散、异构、杂乱的数据整合到一个数据仓库中,使得数据能够被更加方便地管理和使用。
具体来说,ETL的三个步骤分别是:
ETL的好处包括:
ETL的实现
ETL的实现可以使用多种技术和工具,例如ETL工具、编程语言、SQL语言等。具体的实现方式取决于数据仓库的需求、数据源的特点、技术团队的技能等因素。
几种常见的ETL实现方式:
ETL过程需要考虑多种因素,如数据源的类型、数据量的大小、数据质量的要求、数据仓库的数据模型等。因此,ETL的设计和实现需要非常注意,需要充分考虑数据仓库的需求和数据源的特点,保证数据的质量和准确性。
简单来说,在实现ETL时,需要注意以下几点:
总之,ETL的实现需要根据具体的需求和技术特点来选择合适的技术和工具,同时需要注意数据质量、性能优化和安全性等问题。
ETL举例:
假设MySQL数据库中有一个名为"orders"的表,包含以下字段:
order_id:订单号
user_id:用户id
amount:订单金额
create_time:创建时间
现在需要实现一个ETL过程,将"orders"表中的数据提取出来,并将创建时间按照"yyyy-MM-dd"的格式进行格式化,最终将处理后的数据保存到数据仓库中。
提示:
使用JDBC连接MySQL数据库,读取"orders"表中的数据。
使用Spark RDD或DataFrame API对数据进行转换和处理。
使用Spark SQL将数据保存到数据仓库中。
参考答案:
import java.sql.DriverManager
import java.time.format.DateTimeFormatter
import org.apache.spark.SparkConf
import org.apache.spark.sql.{DataFrame, SparkSession}
object OrdersETL {
def main(args: Array[String]): Unit = {
val spark = SparkSession.builder().appName("OrdersETL").getOrCreate()
// 1. 从MySQL中读取数据
val jdbcUrl = "jdbc:mysql://localhost:3306/test"
val username = "root"
val password = "123456"
val driver = "com.mysql.jdbc.Driver"
val table = "orders"
val jdbcDF: DataFrame = spark.read.format("jdbc")
.option("url", jdbcUrl)
.option("user", username)
.option("password", password)
.option("driver", driver)
.option("dbtable", table)
.load()
// 2. 对数据进行转换和处理
val formattedDF: DataFrame = jdbcDF.select("order_id", "user_id", "amount", "create_time")
.withColumn("create_date", date_format(col("create_time"), "yyyy-MM-dd"))
.drop("create_time")
// 3. 将数据保存到数据仓库中
formattedDF.createOrReplaceTempView("temp_orders")
spark.sql(
"""
|CREATE TABLE IF NOT EXISTS orders (
| order_id INT,
| user_id INT,
| amount DOUBLE,
| create_date STRING
|)
""".stripMargin)
spark.sql(
"""
|INSERT INTO orders
|SELECT order_id, user_id, amount, create_date FROM temp_orders
""".stripMargin)
spark.stop()
}
}
数仓建模需要按照一定的数据模型,对整个企业的数据进行采集,整理,提供跨部门、完全一致的报表数据。合适的数据模型,对于大数据处理来讲,可以获得得更好的性能、成本、效率和质量。良好的模型可以帮助我们快速查询数据,减少不必要的数据冗余,提高用户的使用效率。
数据仓库的建模方式主要有两种:维度建模和范式建模。
维度建模一般按照以下四个步骤:选择业务处理过程 > 定义粒度 > 选择维度 > 确定事实
选择业务过程
确定需要建模的业务过程,比如下单业务,支付业务,退款业务,物流业务,一条业务线对应一张事实表。
声明粒度
声明粒度意味着精确定义事实表中的一行数据表示什么,应该尽可能选择最小粒度,以此来应各种各样的需求。
典型的粒度声明如:订单事实表中一行数据表示的是一个订单中的一个商品项。支付事实表中一行数据表示的是一个支付记录。
确定维度
维度的主要作用是描述业务是事实,主要表示的是“谁,何处,何时”等信息。
确定维度的原则是:后续需求中是否要分析相关维度的指标。例如,需要统计,什么时间下的订单多,哪个地区下的订单多,哪个用户下的订单多。需要确定的维度就包括:时间维度、地区维度、用户维度。
确定事实
此处的“事实”一词,指的是业务中的度量值(次数、个数、件数、金额,可以进行累加),例如订单金额、下单次数等。
在DWD层,以业务过程为建模驱动,基于每个具体业务过程的特点,构建最细粒度的明细层事实表。事实表可做适当的宽表化处理。
事实表和维度表的关联比较灵活,但是为了应对更复杂的业务需求,可以将能关联上的表尽量关联上。
维度建模按数据组织类型划分可分为星型模型、雪花模型、星座模型。
星型模型主要是维表和事实表,以事实表为中心,所有维度直接关联在事实表上,呈星型分布。
雪花模型,在星型模型的基础上,维度表上又关联了其他维度表。这种模型维护成本高,性能方面也较差,所以一般不建议使用。尤其是基于hadoop体系构建数仓,减少join就是减少shuffle,性能差距会很大。
星型模型可以理解为,一个事实表关联多个维度表,雪花模型可以理解为一个事实表关联多个维度表,维度表再关联维度表。
星座模型,是对星型模型的扩展延伸,多张事实表共享维度表。
星座模型是很多数据仓库的常态,因为很多数据仓库都是多个事实表的。所以星座模型只反映是否有多个事实表,他们之间是否共享一些维度表。
即实体关系(ER)模型,数据仓库之父Immon提出的,从全企业的高度设计一个3NF模型,用实体加关系描述的数据模型描述企业业务架构,在范式理论上符合3NF。此建模方法,对建模人员的能力要求非常高。特点:设计思路自上而下,适合上游基础数据存储,同一份数据只存储一份,没有数据冗余,方便解耦,易维护,缺点是开发周期一般比较长,维护成本高。
维度建模是数仓中最常用的建模方式,其核心思想是将复杂的业务通过 事实 和 维度 两个概念进行呈现。事实通常对应业务过程,而维度通常对应业务过程发生时所处的环境。
维度建模过程: 选择业务过程→声明粒度→确认维度→确认事实
第一步选择业务过程可以确定有哪些事务型事实表,第二步可以确定每张事务型事实表的每行数据是什么,第三步可以确定每张事务型事实表的维度外键,第四步可以确定每张事务型事实表的度量值字段。
事实表作为数据仓库维度建模的核心,紧紧围绕着业务过程来设计。其中包含该业务过程有关的维度引用(维度表外键)以及业务过程的度量(通常是可累加的数字类型字段)。
事实表有三种类型:分别是事务型事实表、周期型快照事实表和累积型快照事实表,每种事实表都具有不同的特点和适用场景。
事务事实表用来记录各业务过程,它保存的是各业务过程的原子操作事件,即最细粒度的操作事件。粒度是指事实表中一行数据所表达的业务细节程度。
事务型事实表可以保存所有业务过程的最细粒度的操作事件,故理论上其可以支撑与各业务过程相关的各种统计粒度的需求。但对于某些特定类型的需求,其逻辑可能会比较复杂,或者效率会比较低下。如存量型指标,多事务关联统计。
周期快照事实表以具有规律性的、可预见的时间间隔来记录事实,主要用于分析一些存量型(例如商品库存,账户余额)或者状态型(空气温度,行驶速度)指标。
对于商品库存、账户余额这些存量型指标,业务系统中通常就会计算并保存最新结果,所以定期同步一份全量数据到数据仓库,构建周期型快照事实表,就能轻松应对此类统计需求,而无需再对事务型事实表中大量的历史记录进行聚合了。对于空气温度、行驶速度这些状态型指标,由于它们的值往往是连续的,我们无法捕获其变动的原子事务操作,所以无法使用事务型事实表统计此类需求。而只能定期对其进行采样,构建周期型快照事实表。
累计快照事实表是基于一个业务流程中的多个关键业务过程联合处理而构建的事实表,如交易流程中的下单、支付、发货、确认收货业务过程。累积型快照事实表通常具有多个日期字段,每个日期对应业务流程中的一个关键业务过程(里程碑)。
订单id | 用户id | 下单日期 | 支付日期 | 发货日期 | 确认收货日期 | 订单金额 | 支付金额 |
---|---|---|---|---|---|---|---|
1001 | 3200038 | 2023-06-14 | 2023-06-14 | 2023-06-15 | 2023-06-17 | 10000 | 10000 |
累积型快照事实表主要用于分析业务过程(里程碑)之间的时间间隔等需求。例如统计用户下单到支付的平均时间间隔,使用累积型快照事实表进行统计,就能避免两个事务事实表的关联操作,从而变得十分简单高效。
事实表紧紧围绕业务过程进行设计,而维度表则围绕业务过程所处的环境进行设计。维度表主要包含一个主键和各种维度字段,维度字段称为维度属性。
确认维度是 维度建模过程:选择业务过程→声明粒度→确认维度→确认事实 中的第三步。
1)确定维度(表)
在声明粒度时,已经确定了与每个事实表相关的维度,理论上每个相关维度均需对应一张维度表。需要注意到,可能存在多个事实表与同一个维度都相关的情况,这种情况需保证维度的唯一性,即只创建一张维度表。另外,如果某些维度表的维度属性很少,例如只有一个**名称,则可不创建该维度表,而把该表的维度属性直接增加到与之相关的事实表中,这个操作称为维度退化。
2)确定主维表和相关维表
此处的主维表和相关维表均指业务系统中与某维度相关的表。例如业务系统中与商品相关的表有 sku_info , spu_info , base_trademark , base_category3 , base_category2 ,base_category1 等,其中 sku_info 就称为商品维度的主维表,其余表称为商品维度的相关维表。维度表的粒度通常与主维表相同。在星型建模中会对主维表和相关维表进行合并,减少join操作。
3)确定维度属性
确定维度属性即确定维度表字段。维度属性主要来自于业务系统中与该维度对应的主维表和相关维表。维度属性可直接从主维表或相关维表中选择,也可通过进一步加工得到。
确定维度属性时,需要遵循以下要求:
规范化: 是指使用一系列范式设计数据库的过程,其目的是减少数据冗余,增强数据的
一致性。通常情况下,规范化之后,一张表的字段会拆分到多张表。
反规范化: 是指将多张表的数据冗余到一张表,其目的是减少 join 操作,提高查询性能。
在设计维度表时,如果对其进行规范化,得到的维度模型称为雪花模型,如果对其进行反规范化,得到的模型称为星型模型。
维度变化: 维度属性通常不是静态的,而是会随时间变化的,数据仓库的一个重要特点就是反映历史的变化,所以如何保存维度的历史状态是维度设计的重要工作之一。保存维度数据的历史状态最常用的做法就是全量快照表。离线数据仓库的计算周期通常为每天一次,所以可以每天从业务系统同步并保存一份全量的维度数据。优点是简单而有效,开发和维护成本低,且方便理解和使用。缺点是浪费存储空间,尤其是当数据的变化比例比较低时。
数据仓库分层是一种组织数据仓库结构的方法,它将数据仓库划分为多个层次,每个层次负责不同的数据处理任务和数据访问需求。
常见的数仓分层规划:
分层的好处
数据分层:
ODS层(Operational Data Store)
ODS层是最接近数据源中数据的一层,数据源中的数据,经过抽取、洗净、传输,也就说传说中的 ETL 之后,装入本层。本层的数据,总体上大多是按照源头业务系统的分类方式而分类的。
一般来讲,为了考虑后续可能需要追溯数据问题,因此对于这一层就不建议做过多的数据清洗工作,原封不动地接入原始数据即可,至于数据的去噪、去重、异常值处理等过程可以放在后面的DWD层来做。
DW层(Data Warehouse)
数据仓库层,从 ODS 层中获得的数据按照主题建立各种数据模型。DW层又细分为 DWD(Data Warehouse Detail)层、DWM(Data WareHouse Middle)层和DWS(Data WareHouse Servce)层。
DWD层
该层一般保持和ODS层一样的数据粒度,并且提供一定的数据质量保证。同时,为了提高数据明细层的易用性,该层会采用一些维度退化手法,将维度退化至事实表中,减少事实表和维表的关联。
另外,在该层也会做一部分的数据聚合,将相同主题的数据汇集到一张表中,提高数据的可用性。
DWM层(Data WareHouse Middle)
该层会在DWD层的数据基础上,对数据做轻度的聚合操作,生成一系列的中间表,提升公共指标的复用性,减少重复加工。
直观来讲,就是对通用的核心维度进行聚合操作,算出相应的统计指标。
DWS层(Data WareHouse Servce)
按照业务划分,如流量、订单、用户等,生成字段比较多的宽表,用于提供后续的业务查询,OLAP分析,数据分发等。
一般来讲,该层的数据表会相对比较少,一张表会涵盖比较多的业务内容,由于其字段较多,因此一般也会称该层的表为宽表。
在实际计算中,如果直接从DWD或者ODS计算出宽表的统计指标,会存在计算量太大并且维度太少的问题,因此一般的做法是,在DWM层先计算出多个小的中间表,然后再拼接成一张DWS的宽表。由于宽和窄的界限不易界定,也可以去掉DWM这一层,只留DWS层,将所有的数据在放在DWS亦可。
APP层(Application)
在这里,主要是提供给数据产品和数据分析使用的数据,一般会存放在 ES、PostgreSql、Redis等系统中供线上系统使用,也可能会存在 Hive 或者 Druid 中供数据分析和数据挖掘使用。比如我们经常说的报表数据,一般就放在这里。
DIM层(Dimension)
最后补充一个维表层,维表层主要包含两部分数据:
从业务角度描述数据仓库中的数据,提供介于使用者和实际系统之间的语义层,使不懂计算机技术的业务人员也能读懂数仓中的数据
存储关于数据仓库技术细节的数据,用于开发和管理数仓使用的数据
管理领域相关,包括管理流程、人员组织、角色职责等。
数据地图:以拓扑图的形式对数据系统的各类数据实体、数据处理过程元数据进行分层次的图形化展示,并通过不同层次的图形展现。
元数据分析:血缘分析、影响分析、实体关联分析、实体差异分析、指标一致性分析。
辅助应用优化:结合元数据分析功能,可以对数据系统的应用进行优化。
辅助安全管理:采用合理的安全管理机制来保障系统的数据安全;对数据系统的数据访问和功能使用进行有效监控。
基于元数据的开发管理:通过元数据管理系统规范日常开发的工作流程(包括任务调度系统)。