当前位置: 首页 > news >正文

数仓建模理论

一、基础概念

重点掌握:

  1. 数据仓库的特点
  2. 数据仓库与数据库的练习与区别
  3. 为什么要使用数据仓库 / 使用数据仓库的目的是什么

1. 数据仓库的起源

1.1 数据仓库的概念

数据仓库之父比尔·恩门(Bill Inmon)在 1991 年出版的“Building the Data
Warehouse”一书中所提出的定义被广泛接受:数据仓库(Data Warehouse)
是一个面向主题的(Subject Oriented)、集成的(Integrated)、相对稳定的
(Non-Volatile)、反映历史变化(Time Variant)的数据集合,数据仓库的目
标是用于支持分析和决策(Decision Making Support)。

它是一个过程 ,一个解决方案,一套方法论,不是一个具体产品。

1.2 数据仓库的特点(☆☆☆重点掌握)

  1. 面向主题性
    数据仓库主要面向分析主题,因此按照主题来组织,而不是按照应用程序或者业务流程组织数据,主题是用户关心的一类业务或问题。例如:销售、客户、产品等。

    举例说明:数据仓库被设计成辅助人们分析数据。例如,一个公司要分析销售数据,就可以建立一个专注于销售的数据仓库,使用这个数据仓库,就可以回答类似于“去年谁是我们这款产品的最佳用户”这样的问题。这个场景下的销售,就是一个数据主题,而这种通过划分主题定义数据仓库的能力,就使得数据仓库是面向主题的。主题域是对某个主题进行分析后确定的主题的边界,客户、销售、产品都是主题域的例子。

  2. 集成性
    数据仓库集成来自不同系统和数据源的数据,将其统一的存储和管理,消除数据冗余和不一致性。

    举例说明:集成的概念与面向主题是密切相关的。还用销售的例子,假设公司有多条产品线和多种产品销售渠道,而每个产品线都有自己独立的销售数据库,此时要从公司层面整体分析销售数据,必须将多个分散的数据源进行抽取并统一成一致的,无歧义的数据格式后,再放置到数据仓库中。因此数据仓库必须能够解决诸如产品命名冲突、码值统一、计量单位不一致等问题。当完成了这些数据整合工作后,该数据仓库就可称为是集成的。

  3. 相对稳定性
    数据仓库的数据是稳定的、可靠的,不会频繁变化,以保证决策分析的准确性和一致性。

    举例说明:OLTP 型数据库中的数据通常实时更新,数据根据需要及时发生变化。数据仓库的数据主要供企业决策分析之用,所涉及的数据操作主要是数据查询,一旦某个数据进入数据仓库以后,一般情况下将被长期保留,也就是数据仓库中一般有大量的查询操作,但修改和删除操作很少,通常只需要定期的加载、刷新

  4. 反映历史变化
    数据仓库是反映历史变化的,OLTP 型数据库主要关心当前某一个时间段内的数据,而数据仓库中的数据通常包含历史信息,系统记录了企业从过去某一时点(如开始应用数据仓库的时点)到目前的各个阶段的信息,通过这些信息,可以对企业的发展历程和未来趋势做出定量分析和预测。
    当然,任何一个存储结构都不可能无限扩展。当数据超过数据仓库的存储期限,或对分析无用时,从数据仓库中删除这些数据。

除了以上四个特性外,数据仓库还有一个非常重要的概念就是粒度。粒度问题遍布于数据仓库体系结构的各个部分。粒度是指数据的细节或汇总程度,细节程度越高,粒度级别越细。这里举个例子:
(1)例如,销售库里的销售额, 可以是一天一个值, 也可以是一个月一个值,甚至一年一个值, 这就是相对于时间维度表的粒度。

粒度也不是越细越好, 也要综合分析。数据粒度一直是数据仓库设计需要重点考虑的问题。

粒度之所以是数据仓库环境的关键设计问题,是因为它极大地影的的数据仓库的数据量和可以进行的查询类型,粒度级别越低,数据量越大,查询的细节程度越高。查询范围越广泛,反之亦然。

1.3 为什么要有数据仓库

通常数据仓库的数据来自各个业务应用系统。业务系统中的数据形式各种各样,可能是 oracle、mysql 等关系数据库的结构化数据,可能是文本、CSV 等文件或Word、Excel 文档中的非结构化数据,还可能是 HTML、XML 等自描述的半结构化数据。这些业务数据经过一系列的数据抽取、转换、清洗,最终以一种统一的格式装载进数据仓库

从存储的角度看,数据仓库里的数据实际上已经存在于业务应用系统中,那么为什么不能直接操作业务系统中的数据用于分析,而要使用数据仓库呢?

实际上在数据仓库技术出现前,有很多数据分析的先驱者已经发现,简单的“直接访问”方式很难良好工作,这样做的失败案例数不胜数。下面列举一些直接访问业务系统无法工作的原因:

  • 某些业务数据由于安全或其他因素不能直接访问。
  • 业务系统的版本变更很频繁,每次变更都需要重写分析系统并重新测试。
  • 很难建立和维护汇总数据来源于多个业务系统版本的报表。
  • 业务系统的列名通常是硬编码,有时仅仅是无意义的字符串,这让编写分析系统更加困难。
  • 业务系统的数据格式,如日期、数字的格式不统一。
  • 业务系统的表结构为事务处理性能而优化,有时并不适合查询与分析,没有适当的方式将有价值的数据合并进特定应用的数据库。
  • 没有适当的位置存储元数据。
  • 用户需要看到的显示数据字段,有时在数据库中并不存在。
  • 通常事务处理的优先级比分析系统高,所以如果分析系统和事务处理运行在同一硬件之上,分析系统往往性能很差。
  • 极有可能影响业务系统的性能。

数据仓库(开源的 Hadoop 体系和阿里的 MaxCompute/ODPS 等)本质上也
是数据库,只不过它主要用于:

  1. 从外部数据源引入和存储历史数据;
  2. 分析数据。

因此相比事务性数据,数据仓库对数据集成和数据分析能力要求较高,相对应的功能更丰富和更强大。比如对复杂的 JSON 文本处理和分析, 可以通过集成 Java / Python/Shell 等语言自定义 UDF 函数来实现更加灵活的处理。

下面简单总结一下什么时候需要开始使用数据仓库:

  • 需要分析的数据量较大(单批 GiB),此时事务性数据库分析性能堪忧,需要通过建立索引而且会分析查询会影响在线事务。而数仓一般采用列式存储,自带索引性能加成。
  • 分析查询不想影响在线事务
  • 需要记录历史数据
  • 需要对来自不同数据库、数据源的数据进行整合、关联分析和交叉探查。比如将存储在 SLS 的用户日志和 MySQL 的用户信息进行关联分析,通过用户的行为日志建立用户画像。
  • 批处理分析,需要定期批量查询分析数据并生成结果,比如各种 BI 报表。

1.4 数据仓库 VS 数据库(☆☆理解记住)

(1)数据库
数据库是面向业务的处理系统,它是针对具体业务在数据库联机的日常操作,通常对记录进行查询、修改。用户较为关心操作的响应时间、数据的安全性、完整性和并发支持的用户数等问题。传统的数据库系统作为数据管理的主要手段,主要用于操作型处理,也被称为联机事务处理 OLTP(On-Line Transaction Processing)。

(2)数据仓库
数据仓库是面向主题的处理系统,一般针对某些主题的历史数据进行分析,支持管理决策,又被称为联机分析处理 OLAP(On-Line Analytical Processing)。

(3) 两者区别
首先要明白,数据仓库的出现,并不是要取代数据库。数据仓库中的数据面向主题、数据集成、不易更新、反映历史变化的特点,这些特点是数据库系统没有的,两者区别主要包括:面向需求不同、系统设计目标不同、设计方法不同等详情见下表。


在这里插入图片描述


举个例子:
以银行业务为例。数据库是事务系统的数据平台,客户在银行做的每笔交易都会写入数据库,被记录下来,这里,可以简单地理解为用数据库记账。

数据仓库是分析系统的数据平台,它从业务系统获取数据,并做汇总、加工,为决策者提供决策的依据。比如,某银行某分行一个月发生多少交易,该分行当前存款余额是多少。如果存款又多,消费交易又多,那么该地区就有必要设立ATM 了。

显然,银行的交易量是巨大的,通常以百万甚至千万次来计算。业务系统是实时的,这就要求时效性,客户存一笔钱需要几十秒是无法忍受的,这就要求数据库只能存储很短一段时间的数据。而分析系统是事后的,它要提供关注时间段内所有的有效据。这些数据是海量的,汇总计算起来也要慢一些,但是只要能够提供有效的分析数据就达到目的了。

数据仓库,是在数据库已经大量存在的情况下,为了进一步挖掘数据资源、为了决策需要而产生的,它决不是所谓的“大型数据库”。

1.5 数据仓库 VS 数据湖

随着大数据时代的发展,环境发生了变化,使得数据仓库这种先处理后使用的方式成本激增。

首先,数据量发生了显著的增加,对数据仓库的存储是一个巨大的挑战;
其次,数据结构也非常多元化,不再都是结构化数据,而是出现了半结构化数据,甚至语音视频等非结构数据。但是人们同时意识到数据包含巨大的潜在价值,对于很多数据,即使暂时没有明确的需求,也想先留一份。

所以,妥协的办法出现了,从先处理后用,变成了先存储,以后用的时候再考虑怎么处理。这就是数据湖的处理方式。这样做有两个好处,一个是保留了原始数据的原汁原味,这样可以避免任何前期的数据加工造成的数据变形。另外一个好处就是节约了前期数据接入时的成本。

数据湖是一个以原始格式(通常是对象块或文件)存储数据的系统或存储库。数据湖通常是所有企业数据的单一存储。用于报告、可视化、高级分析和机器学习等任务。数据湖可以包括来自关系数据库的结构化数据(行和列)、半结构化数据(CSV、日志、XML、JSON)、非结构化数据(电子邮件、文档、pdf)和二进制数据(图像、音频、视频)。


在这里插入图片描述


最初构思数据湖时,人们认为只需要提取数据并将其放入数据湖即可。一旦进入数据湖,终端用户就可以一头扎进去,找到数据并进行分析。然而,企业很快发现,使用数据湖中的数据与仅仅将数据放入湖中完全是两码事。

当前,业界出现了一种称为 data lakehouse(湖仓一体) 的新型数据架构,它通过一种新的开放和标准化的系统设计来实现:其实现与数据仓库中类似的数据结构和数据管理功能,并将数据存放在数据湖使用的低成本存储系统中。

目前作为前沿的大数据架构,数据湖和数据仓库一体正蓬勃发展,有望成为新一代的大数据应用架构。

2. 数据模型

2.1 什么是数据模型

数据模型就是数据组织和存储方法,是数据特征的抽象,通过抽象的实体及实体之间联系的形式,来表示现实世界中事物的相互关系的一种映射,也是对数据背后业务的抽象表达,可以用一个公式表示其结构:

数据模型 = 「数据组件 + 组件间关系 + 规约」

  • 数据组件指各类业务对象或实体,对应到数据模型的图形化表达上,一般是
    「点」,常见的数据组件有业务对象(如:用户、商家)、表(如:Hive 物
    理表)、指标等;
  • 组件间的关系就是多个数据组件之间的各种关系,对应到数据模型的图形化
    表达上,一般是「边」,常见的组件间的关系有关联关系(如用户与商品之
    间,商品与商家之间)、泛化关系(如:用户与支付宝用户,商家与小程序
    商家);
  • 规约指各类组件及关系的约束条件,如数据组件的命名约束、关联关系的方
    向约束、主外键约束等等。

数据模型表现和抽象的是实体和实体之间的关系,通过对实体和实体之间关系的定义和描述,来表达实际的业务中具体的业务关系。

数据仓库模型是数据模型中针对特定的数据仓库应用系统的一种特定的数据模型,从层级上看,依次分为:概念模型、逻辑模型、物理模型:


在这里插入图片描述

  • 概念模型:是一种面向用户、面向客观世界的模型,用抽象的概念名词来抽象表达业务,按数据模型的结构,概念模型对应的数据组件一般是各类数据实体,如:业务对象(用户、商家、商品…),业务活动(交易、投保、配送…)。
  • 逻辑模型:逻辑模型既面向用户,又面向物理系统,它是在概念模型的基础上,扩展概念的属性实现的,如用户这个概念模型数据组件,扩展性别、年龄、住址等等属性,形成一个表格,逻辑模型的载体可以是一个文档,也可以是一张虚拟表。
  • 物理模型:主要是根据逻辑模型,基于物理系统的特性进行针对性的适配,如:分区、存储结构、索引策略、冗余等等,载体一般是物理表。

2.2 为什么需要数据模型

大数据系统需要数据模型方法来帮助更好地组织和存储数据,以便在性能、成本、效率和质量之间取得最佳平衡。

  1. 性能:良好的数据模型能帮助我们快速查询所需要的数据,减少数据的 I/O 吞吐。
  2. 成本:良好的数据模型能极大地减少不必要的数据冗余,也能实现计算结果复用,极大地降低大数据系统中的存储和计算成本。
  3. 效率:良好的数据模型能极大地改善用户使用数据的体验,提高使用数据的效率。
  4. 质量:良好的数据模型能改善数据统计口径的不一致性,减少数据计算错误的可能性。

2.3 如何建设数据模型

建设数据模型既然是整个数据仓库建设中一个非常重要的关键部分,那么,怎么建设我们的数据仓库模型就是我们需要解决的一个问题。

这里我们将要以供应链业务介绍如何创建适合自己的数据模型。概念模型、逻辑模型、物理模型之间的关系如下图所示:

在这里插入图片描述


数据仓库的数据建模大致分为三个阶段:

  1. 概念建模,这部分的建模工作侧重业务分析,主要包含以下几个部分:
    • 理清业务活动并抽象化;
    • 分析确认业务活动中参与业务实体;
    • 分析确认业务实体之间的关系;
      在这里插入图片描述
  2. 逻辑建模,这部分的建模工作侧重实体关系设计,主要包含以下几个部分:
    • 业务实体化的属性和值域;
    • 梳理实体的属性和实体之间的联系;
      在这里插入图片描述
  3. 物理建模,这部分的建模工作维度模型设计,主要包含以下几个部分:
    • 综合考虑存储和查询性能,进行数据仓库模型设计,维度表和事实表的设计
      (不展开);

最终梳理出核心的业务流程图:

在这里插入图片描述
首先识别业务过程。识别业务过程之前要先找出业务中的实体。对于供应链体系来说主要的实体就是:供应商、商品、经销商、用户、仓库、资金等。把上边的业务流图稍作简化,从头走一遍。经销商先向供应商采购。供应商发货给仓库入库。仓库理货,上架商品进行售卖。用户购买商品,然后仓库发货出库。物流快递派送商品到用户。用户确认收货。经销商和供应商进行财务结算。整个流程走完,基本重要业务过程节点都清晰了。把这些关键节点的业务过程再进行细化和完善。比如采购之前,需要签合同,入库之前需要预约等。

业务过程梳理清晰后,还要根据实际的业务判断,哪些数据是获取不到的,哪些是业务部关注的。对业务过程进行精简,精简后就可以对核心的数据进行物理建模了。

  • 实体通常以 DIM 维表形式构建。比如:供应商维表、货品维表、货品商品关系维表等。
  • 业务过程以 DWD 事实表形式构建。比如:采购单流水表、入库流水表、出库流水表等。

从我们上面对数据仓库的数据建模阶段的各个阶段的划分,我们能够了解到整个数据仓库建模的主要工作和工作量,能够对我们在实际的项目建设能够有所帮助。


二、数据仓库的架构

重点掌握:

  1. 请讲一下常见的数据仓库架构有哪些?设计思路是什么样的?
  2. 请讲一下 Inmon、Kimball 两种数仓架构的特点。
  3. 请讲一下你们公司当前数据建设的情况、所处的阶段、存在什么样的问题。

1. 基本架构

“架构”是什么? 架构的定义,一般指的是整体结构和结构组件之间的关系。数据仓库的架构,说的就是常见的数据仓库的结构以及内部结构之间的关系。数据仓库系统一般采取下图架构来满足上述使用场景的:

在这里插入图片描述

  1. 数据从不同的数据源引入到统一的存储
  2. 在统一存储里进行分析计算
  3. 计算得到分析结果给外部消费
  4. 串 联 上 述 数 据 引 入 、 处 理 和 分 析 过 程 的 程 序 就 是 ETL(Extract-Transform-Load,抽取-转换-加载)任务

2. 主要数据仓库架构(☆☆理解记住)

2.1 离线架构

2.1.1 数据分层架构

搞过数据仓库的,都知道所谓的三层架构,那么数据为何要做分层呢?

  1. 清晰数据结构:每一个数据分层都有它的作用,这样我们在使用表的时候能更方便地定位和理解。
  2. 减少重复开发:规范数据分层,开发一些通用的中间层数据,能够减少极大的重复计算。
  3. 复杂问题简单化:将一个复杂的任务分解成多个步骤来完成,每一层只处理单一的步骤,比较简单和容易理解。而且便于维护数据的准确性,当数据出现问题之后,可以不用修复所有的数据,只需要从有问题的步骤开始修复。
  4. 屏蔽原始数据的异常:屏蔽业务的影响,不必改一次业务就需要重新接入数据。

一般数据仓库的三层架构,典型如阿里的 ONEDATA 体系,就是按照三层架构来落地。

在这里插入图片描述

当然在各个层次之下还可以有细化层次或者是减少层次,比如:

  • 针对新创建业务场景,其看数思路和指标体系并不固定的情况下,多数情况下公共层只会构建 DWD 等明细层,弱化 DWS;
  • 在应用层内部,可能因为结构清晰和数据加工计算方便等考量,会在细化抽象层次,比如之前很多人提到的公共应用层或者是所谓接口服务层等概念。

架构这个东西,存在即是合理,只要合理的考虑层次的用途,基于各自的业务和数据现状,可以针对性的细化分层架构。

2.1.2 Inmon 数据仓库架构(了解)

范式建模,并且很重视数据清洗。

Inmon 企业信息工厂架构如下图所示,我们来看一下图中组件是如何协同工作的。

在这里插入图片描述

  • 应用系统,这些应用是组织中的操作型系统,用来支撑业务。它们收集业务处理过程中产生的销售、市场、材料、物流等数据,并将数据以各种形式进行存储。操作型系统也叫源系统,为数据仓库提供数据。
  • ETL 过程,ETL 过程从操作型系统抽取据,然后将数据转换成一种标准形式,最终将转换后的数据装载到企业级数据仓库中。ETL 是周期性运行的批处理过程。
  • 企业级数据仓库,是该架构中的核心组件。正如 Inmon 数据仓库所定义的,企业级数据仓库是一个细节数据的集成资源库。其中的数据以最低粒度级别被捕获,存储在满足三范式设计的关系数据库中。
  • 部门级数据集市,是面向主题数据的部门级视图。数据从企业级数据仓库取。数据在进入部门数据集市时可能进行聚合。数据集市使用多维模型设计,用于数据分析。重要的一点是,所有的报表工具、BI 工具或其他数据分析应用都从数据集市查询数据,而不是直接查询企业级数据仓库。

2.1.3 Kimball 数据仓库架构(目前主流的架构)

Kimball 数据仓库架构如图所示:
在这里插入图片描述
对比上一张图可以看到,Kimball 与 lnmon 两种架构的主要区别在于核心数据仓库的设计和建立。Kimball 的数据仓库包含高粒度的企业数据,使用多维模型设计,这也意味着数据仓库由星型模式的维度表和事实表构成。分析系统或报表工具可以直接访问多维数据仓库里的数据。在此架构中的数据集市也与 lnmon中的不同。这里的数据集市是一个逻辑概念,只是多维数据仓库中的主题域划分,并没有自己的物理存储,也可以说是虚拟的数据集市。

2.1.4 混合型数据仓库架构

混合型数据仓库架构如图所示:
在这里插入图片描述
所谓的混合型结构,指的是在一个数据仓库环境中,联合使用 Inmon 和Kimball 两种架构。从架构图可以看到,这种架构将 Inmon 方法中的数据集市部分替换成了一个多维数据仓库,而数据集市则是多维数据仓库上的逻辑视图。使用这种架构的好处是,既可以利用规范化设计消除数据冗余,保证数据的粒度足够细;又可以利用多维结构更灵活地在企业级实现报表和分析。

2.2 实时架构

2.2.1 Lambda 架构

随着大数据应用的发展,人们逐渐对系统的实时性提出了要求,为了计算一些实时指标,就在原来离线数仓的基础上增加了一个实时计算的链路,并对数据源做流式改造(即把数据发送到消息队列),实时计算去订阅消息队列,直接完成指标增量的计算,推送到下游的数据服务中去,由数据服务层完成离线 & 实时结果的合并,以此实现对离线产生的数据和实时产生的数据进行查询。

在这里插入图片描述

2.2.2 Kappa 架构

Kappa 架构可以认为是 Lambda 架构的简化版(移除 lambda 架构中的批处理部分)。

在 Kappa 架构中,正常情况下 kafka 都是吐出实时数据,经过实时处理系统,进入服务数据库,当需要数据订正或历史数据重新处理时都通过上游重放消息完成。

在这里插入图片描述
Kappa 架构最大的问题是流式重新处理历史数据的吞吐能力会低于批处理,但这个可以通过增加计算资源来弥补。

Kappa 架构问题:

  1. 消息中间件缓存的数据量和回溯数据有性能瓶颈。通常算法需要过去 180 天的数据,如果都存在消息中间件,无疑有非常大的压力。同时,一次性回溯订正180 天级别的数据,对实时计算的资源消耗也非常大。
  2. 在实时数据处理时,遇到大量不同的实时流进行关联时,非常依赖实时计算系统的能力,很可能因为数据流先后顺序问题,导致数据关联不上而被误抛弃。

2.2.3 HSAP 架构

如下图所示是阿里巴巴在 2011~2024 年间沉淀下来的一套实时数仓架构,其本质上也是 Lambda 架构,通过一系列存储和计算引擎(HBase、Druid、Hive、Drill、Redis 等)的复杂配合才能满足业务的需求,并且多个存储之间需要通过数据同步任务来保持大致的同步。这种业务架构极其复杂,整个业务的开发耗费了大量的时间。然而随着业务量的增长,随着数据的增长,关系复杂度越来越大,成本急剧增加,因此,我们迫切的需要一种更优雅的方案去解决类似的问题。

在这里插入图片描述

基于上述背景,提出了 HSAP 理念,HSAP 是指 Hybrid serving and analytical processing(混合型服务分析一体化),理念是既能支持很高 QPS 场景的实时写入,又能将复杂的分析场景在一套体系里面完成。HSAP 相当于数仓 + 在线(OLAP + OLTP)服务,是两者的超集。

那么 HSAP 理念落地的其核心是什么呢?

  • 首先,要有一套非常强大的存储,能够同时存储实时数据和离线数据,统一数据存储;
  • 同时还要有一种高效的查询服务,在同一个接口下(比如 SQL),能够支持高 QPS 的查询,支持复杂的分析以及联邦查询和分析;
  • 系统能够直接对接前端应用,例如报表和在线服务等,不需要再额外的导入导出就能即席分析,统一数据服务,减少数据移动。

HSAP 理念的产品,阿里云 Hologres。用户、商品、商家属性数据和海量的用户行为数据经过实时和离线的数据清洗统一进入 HSAP 系统,由 HSAP 系统向上承接了实时大屏、实时报表、效果跟踪、实时数据应用等查询和分析服务。

在这里插入图片描述

3.数仓建模方法(☆☆理解记住)

如程序语言设计大师 Niklaus Wirth 所说,程序=算法+数据结构。数据仓库这一大程序中关注最重要的 2 件事情就是:

  • 数据仓库的数据结构:如何设计数据的存储格式和数据之间的关联关系?也就是数据建模。
  • 数据仓库的算法:如何编写和调度数据处理任务,完成数据的引入、处理分析算法。也就是 ETL 任务。

3.1 Inmon 模式(范式建模)

3.1.1 概念

Inmon 模式从流程上看是自上向下的,即从上游业务系统的数据着手, 进而构建出整个企业共享的数据仓库, 在这个数据仓库下延伸出不同主题的数据集市(数据集市就是关于某一个主题的小数据仓库),比如账单数据作为一个账单数据集市。(先有数据仓库再有数据集市)一种瀑布流开发方法。

3.1.2 流程

通常,Inmon 都是以数据源头为导向。首先,需要探索性地去获取尽量符合预期的数据,尝试将数据按照预期划分为不同的表需求。其次,明确数据的清洗规则后将各个任务通过 ETL 由 Stage 层转化到 DW 层,将数据抽象为实体-关系模型。接着,在完成 DW 的数据治理之后,可以将数据输出到数据集市中做基本的数据组合。最后,将数据集市中的数据输出到 BI 系统中去辅助具体业务。

3.1.3 特点

在这种场景下,数据无法从 stage 层直接输出到 dm 层,必须先通过 ETL 将数据的格式清洗后放入 dw 层,再从 dw 层选择需要的数据组合输出到 dm 层。在 Inmon 模式中,并不强调事实表和维度表的概念,因为数据源变化的可能性较大,需要更加强调数据的清洗工作,从中抽取实体-关系。


3.2 Kimball 模式(维度建模)

3.2.1 概念

Kimball 模式从流程上看是自下向上的,是指从最下游的业务数据分析需求开始,先想清楚要解决什么问题,解决这些问题需要知道哪些业务流程、索要分析的数据的维度和指标度量需求,再去上游数据源捞取需要的数据。根据分析的领域不同,逐渐积累出一堆数据集市。这堆逐渐构建出来的数据集市就是逻辑上的数据仓库。即从数据集市->数据仓库->数据源(先有数据集市再有数据仓库)的一种敏捷开发方法。

3.2.2 流程

通常,Kimball 都是以最终任务为导向。首先,在得到数据后需要先做数据的探索,尝试将数据按照目标先拆分出不同的表需求。其次,在明确数据依赖后将各个任务再通过 ETL 由 Stage 层转化到 DM 层。这里 DM 层数据则由若干个事实表和维度表组成。接着,在完成 DM 层的事实表维度表拆分后,数据集市一方面可以直接向 BI 环节输出数据了,另一方面可以先 DW 层输出数据,方便后续的多维分析。

3.2.3 特点

Kimball 支持数据仓库总线结构,提倡维度建模,以星型模型或是雪花模型等方式构建维度数据仓库。架构体系中,数据集市与维度数据仓库是紧密结合的,数据集市是数据仓库中一个逻辑上的主题域。各种前端工具将可以直接访问使用维度数据仓库。

Kimball 往往意味着快速交付、敏捷迭代,不会对数据仓库架构做过多复杂的设计,在变幻莫测的互联网行业,这种架构方式逐渐成为一种主流范式。


3.3 Inmon VS Kimball 建模方式对比

3.3.1 架构设计

Inmon 架构的思想在于自上而下的构建数据模型。以数据源头开始,数据以瀑布流式的向下流动,更加注重数据清洗。其核心思想在于数仓分层。(换言之就是,尽量将某一主题域的所有数据都考虑到数据建模中。这样设计的数据模型的覆盖面会更广,但是数据模型的设计会困难)。

在这里插入图片描述

Kimball 架构的思想在于自下而上的构建数据模型。以具体业务诉求为出发点,设计数据模型,其核心思想在于维度建模。(即根据业务需求找到关注的数据指标,基于关注的数据指标设计数据模型,这样设计的数据模型会更加的独立,但可能会导致数据模型过多发展)。

在这里插入图片描述

目前企业的数据仓库设计一般都是综合了两者的实现,整体上采用分层架构,具体的模型设计上采用维度建模。


3.3.2 实现特点

由于两派构建数据仓库的根本理念上就存在着差异,所以他们的数据建模方法也不同。

Inmon 偏向于构建一个企业级别中央大一统的数据仓库,所以 Inmon 推崇使用== ER 模型建立关系模型并坚持使用3NF 规范==化进行数据模型的建设,这样的好处又很多:数据一致性好,一处改动多处一致、减少数据冗余等等。这种方式对业务稳定的企业来说是可行的,但这样设计和开发效率较低,不够敏捷,不适合业务发展迅猛的企业,尤其是互联网行业;

Kimball 建议不要一上来就想搞大工程,要以需要分析的问题和业务为导向,小步快跑地集成数据来解决一个个具体的业务问题,并逐渐积累为数据仓库,这种小步快跑的迭代方法更敏捷,更受互联网公司青睐。它以分析问题为导向,因此重点关注业务问题分析中需要什么「维度属性」以及「事实度量值」,比如分析销售额时会重点关注区域、城市、日期、商品类别等维度,以及销售额、成本、利润等事实度量值。因此 KimBall 提出的「维度建模」方法以构建「维度表」和「事实表」为核心,并且为了让分析师更高效使用数据表,减少表之间的 Join 关联操作,因而放弃 3NF 规划化,提倡反规范化,构建大量宽表。当然缺点就是数据大量冗余、数据不一致,而且容易重复建设。

说了那么多,其实核心观点就是:不同的企业业务类型就应该用不同的数据建模方法。

在互联网行业中,需求变化飞快,追求敏捷更符合实际场景,阿里 MaxCompute 也推荐使用维度建模,数据建模工具的域名就是:https://kimball.alibaba-inc.com。除此以外,微软的 Power BI、Tableau 等业界 BI数据工具都可以采用维度建模。

我们可以拿几个例子来解释说明一下。

  • 营销:这是一个专业领域,我们不需要为了分析的目的考虑营销的每个方面。因此,我们不需要企业仓库——几个数据集市就足够了——也就是 Kimball方法。
  • 广告:这是一个小的分支,并且业务场景较为简单,无需进行企业级数仓建设,只需要数据集市就够了。因此,Kimball 的方法比较适合。
  • 保险:为了根据未来的预测管理风险,我们需要对所有投保人形成一个广泛的图景,由一系列数据组成,如盈利能力、历史、人口统计等。所有这些方面都是相互关联的,因此 Inmon 方法比较合适。
  • 银行:银行类的业务对于银行产品和客户信息都是非常关注,尤其是两者的交叉分析,哪些人买了啥银行产品。这些数据会有相关的限制,例如:产品和客户的信息不可给市场和财务部门公开,部门与部门之间的数据会有限制,这种情况下只能采用 Kimball 的方法;如果银行中的整个流程和部门相互关联,这种情况下使用 Inmon 会更好一些。
  • 制造&电信:会涉及到多个组织单元,且预算比较充裕。这种情况没有系统依赖,因而需要企业模型,这时还是 Inmon 的方法比较理想。

4. 阿里数仓架构升级之路

大型公司的数据建设也不是一蹴而就的,其实也是一步步地迭代建设的。在数仓架构层面,它通过多轮的迭代建设使其变得更加科学。

4.1 数仓架构升级方向

随着数据应用场景的扩大,如数据化运营、算法策略、产品优化等场景的出现,在多场景协同落地中出现了问题。在近 10 年的实践迭代中,整体数据架构发现了以下问题:

在这里插入图片描述

  1. 架构的定位与边界不清晰,导致 ADS 烟囱化开发:此前 OneData 定义了 CDM和 ODS 的范围,但缺少对 ADS 的范围定义,存在 ADS 与 DWS、ODS 的边界不清晰,导致 ADS 自建轻度汇总和 ODS 明细、竖立小烟囱等问题。如数据团队存在
    生意参谋、数据银行等多个数据应用团队及数据公共层团队,彼此协作边界不清晰,经常发生应用层开发有复用需求,提交至公共层下沉,公共层团队却因人力资源、全局通用性、二次加工等问题未承接,导致数据应用团队在 ADS 内部自建复用性模型以满足业务诉求。
  2. ADS 集市缺少统一规划,混乱低效:OneData 体系定义了公共层的数据域划分的标准和方法,但缺乏对 ADS 数据集市域的划分标准和方法。实操中集市大小体量差异悬殊,部分集市过度臃肿影响效率,而部分集市很小,且重复开发浪费资源。
  3. ADS 集市指标口径亟需统一:OneData 给出了指标定义较清晰的规范定义方法,但指标实操中均需拆解到业务过程,原子指标、修饰词、统计周期的设计成本高且口径各不一致,并随着业务发展指标口径越繁复,将严重影响 ADS 集市的开发效率。
  4. 缺少高质量的设计标准指导,模型千人千样,事后问题频发:OneData 体系包含架构分层、规范定义、使用维度建模理论,但如何设计出高质量的数据模型,当前主要依赖专家经验。虽然 OneData 给出了模型设计过程六大原则,而六大原则如何落地并没有案例和建议支撑。如高内聚低耦合从模型粒度指标相似性、消费频率情况给了建议,但在公共层设计的过程有哪些考虑因素,应用层没有外部消费又该如何操作?不合理的模型设计是核心应用产出不符合要求、模型变更频繁、架构稳定性差等问题的根源。
  5. 规范缺少配套的产品化工具落地保障:虽有 OneData 规范标准,但并未与开发工具 dataworks 集成形成规范管控力,出现了规范裸奔的现象。

4.2 数仓架构升级方案

核心解法思路在于从业务对数据的诉求出发,明确各模型分层的定位与作用,构建各模型层次的协作机制,形成高效的业务数据体系建设规范,并基于规范体系与开发平台共建模型设计和模型管控的产品化能力。

在这里插入图片描述

  • 数据架构升级,明确各层次定位:数据体系的价值在于解决业务问题,业务对数据的诉求核心在交付效率、产出时效、质量可靠、成本可控;同时服务业务的不只是应用层,而应由贴源层、公共层、应用层共同服务。需要对各层次明确定位,形成合力而避免内耗:

    • 应用层专注支撑业务,提升服务业务的效率,确保口径一致性,核心内容的稳定性;
    • 公共层通过抽象复用提升应用层的效率,同时共性逻辑下沉确保全局一致性;因为考虑复用性,服务多个集市下游,也需要关注模型设计的易用性和稳定性;
    • 贴源层在数据合规的背景下,需要关注数据接入的合规性;同时贴源层不做太多的逻辑转化,通过工具来提升接入效率。
  • 升级完善 OneData 规范:补全集市域的划分标准与方法,通过对集市进行划
    分降低应用层的复杂性,提升研发效率;并基于维度建模理论,结合业务设
    计最佳实践,总结应用层、公共层的设计原则,提升模型设计的质量;同时
    建立公共层的共建机制,形成公共层和应用层的联动。

  • 产品能力升级,确保模型规范有效执行:基于 OneData 方法论,在 dataworks
    上构建智能建模产品能力,将模型设计过程产品化;同时基于设计原则,抽
    象沉淀核心检测规则,形成事前管控能力,降低模型问题。


4.3 数仓架构升级建议

数据架构升级建议主要包含数据分层建议、公共层数据域建议、应用层集市域建议。

4.3.1 数据分层建议

升级分层架构建议(ODS/DWD/DIM/DWS/MDS/ADS),新增 MDS 层以解决应用层和公共层定位不清晰的问题;同时结合业务诉求的变化,完善各层次的内容范围。

  • ODS(操作数据层):把操作系统数据几乎无处理的存放在数据仓库系统中,采用增量或全量同步,根据业务需要保存历史数据、清洗数据。

    • 关注数据安全合规:随着国家数安法、个保法的出台,跨域数据的获取需要遵循安全合规要求。
    • 关注业务系统的稳定性:ODS 大部分来源于业务系统,需要采用正确的同步方式,同时避免重复同步,以保障业务系统的稳定性。
    • 关注数据存储成本:ODS 层跟 DWD 层的粒度几乎一致,需要关注重复存储带来的成本压力。
  • 公共层:公共层通过抽象集市复用逻辑,按业务过程重新定义数据,提升应用层的开发效率。因其具有通用性,需关注数据的易用性、稳定性,且易用性为主,稳定性为辅。

    • DWD(明细层): 使用维度建模方法,采用维度退化手法将维度退化至事实表,以降低应用层频繁关联的成本,提升模型易用性;通过对业务过程进行重新建模,保障数据粒度与源系统保持一致,提升模型规范性便于上层数据的加工和计算;
    • DIM(统一维度层):用于存放维度建模方法中核心构建总线矩阵的维度,同时 OLAP 场景常用分析的统计分析维表;确保跨集市统计分析维度的统一;
    • DWS(汇总层):对 ADS 层的数据诉求进行通用化抽象,按业务过程和维度组织数据,沉淀共用指标,减少重复计算应用层研发效率,确保跨集市指标口径统一。
  • 集市层:数据集市是满足特定的部门或者用户需求,按照业务角度组织数据,快速满足业务的数据层。数据集市需关注研发效率、口径一致性,以及核心应用的稳定性。

    • ADS:面向具体应用场景构建,场景间松耦合,一般为专表专用,快速满足业务需求;
    • MDS:用于承接单集市内多场景的数据共性问题,沉淀集市中间层,确保集市内维度、口径一致性与研发效率;因其承载集市内复用性能力,需要适当进行垂直切分解耦,以确保核心数据的产出稳定。

在这里插入图片描述

4.3.2 公共层数据域建议

对公共层进行数据域划分,使公共基础数据组织分类清晰呈现,便于提升数据消费者理解度,并优化数据管理。

具体数据域划分规范可参照:《模型命名规范-数据域划分规范》

请重点注意:

a. 数据域的抽象原则,根据高内聚低耦合的基础原则,以数据消费的内聚性、数据来源的内聚性、数据加工的内聚性进行抽象定义数据域标准;

b. 数据域的划分需统一标准,尽量符合 MECE 原则。
*MECE,是 Mutually Exclusive Collectively Exhaustive,中文意思是“相互独立,完全穷尽”。也就是对于一个重大的议题,能够做到不重叠、不遗漏的分类,而且能够借此有效把握问题的核心,并解决问题的方法。

4.3.3 应用层集市域建议

对应用层进行集市主题域划分,通过对相似数据业务场景内聚抽象进行分类,以降低 ADS 层的重复建设和数据管理复杂度,使应用研发更聚焦更高效。

请重点注意:

a.集市的划分原则,以业务场景或者服务对象作为划分原则,对相似数据业务场景内聚抽象进行分类;

b.集市域的划分需统一标准,尽量符合 MECE 原则。

在这里插入图片描述


三、数据仓库设计基础

重点掌握

  1. 请介绍你知道几种数据模型以及其特点。
  2. 请介绍一下第一、二、三范式。
  3. 列举一下你使用过的逆范式化设计,并说明这样做的目的?(逆 1nf-hive 里面的 map 结构;逆 2nf-log 日志表,做 PV、UV;逆 3nf-宽表设计)
  4. 请说明一下维度建模的过程。
  5. 请举例说明一下星型模型、雪花模型、星座模型,并说明它们各自的优缺点。

1. 关系数据模型

关系数据模型也叫做 E-R 模型,诞生于 20 世纪 70 年代,设计支持是针对关系型数据库的建模,比较适合构建三范式的模型,在数仓领域,Inmon 比较推崇此建模方式。


1.1 关系数据模型结构

  • 从模型结构上看:

    在这里插入图片描述
    我们使用一个分公司-员工关系的例子。假设一个大型公司在全国都有分公司,每个员工属于一个分公司,一个分公司有一个经理,分公司经理也是公司员工。分公司-员工关系如图所示:
    在这里插入图片描述

  • 从构建流程上看:
    在这里插入图片描述

1.1.1 关系

由行和列构成的二维结构,对应关系数据库中的表。如示例中的分公司表和员工表。。注意,这种认识只是我们从逻辑上看待关系模型的方式,并不应用于表在磁盘上的物理结构。

1.1.2 属性

由属性名称和类型名称构成的顺序对,对应关系数据库中表的列,如地址(Variable Characters)是公司表的一个属性。属性值是属性的一个特定的有效值,可以是简单的标量值,也可以是复合数据类型值。

在关系数据模型中,我们把关系描述为表,表中的行对应不同的记录,表中的列对应不同的属性。属性可以以任何顺序出现,而关系保持不变,也就是说,在关系理论中,表中的列是没有顺序的。

1.1.3 属性域

属性的取值范围。每一个属性都有一个预定义的值的范围。属性域是关系模型的一个重要特征,关系中的每个属性都与一个域相关。各个属性的域可能不同,也可能相同。域描述了属性所有可能的值。

1.1.4 元组

关系中的一条记录,对应关系数据库中的一个表行。元组可以以任何顺序出现,而关系保持不变,也就是说,在关系理论中,表中的行是没有顺序的。

1.1.5 关系数据库

一系列规范化的表的集合。这里的规范化可以理解为表结构的正确性

1.1.6 关系表的属性

关系表有如下属性:

  • 每个表都有唯一的名称;
  • 一个表中每个列有不同的名字;
  • 一个列的值来自于相同的属性域;
  • 列是无序的;行是无序的。
1.1.7 关系数据模型中的键

键是用于标识表(关系)中每一行(元组)的属性和属性集合.

  1. 超键
    超键是指一个属性集,其值能够唯一标识表中的每一个元组,我们通常只对仅包含能够唯一标识记录的最小数量的列感兴趣。

    例如:在学生表中,学号和姓名可能共同构成一个超键

  2. 候选键
    候选键是从超键中进一步提炼出来的,它是最小的属性集,仍然可以确保唯一性,每个候选键都可以作为主键使用,但通常在一个关系中只选择一个作为实际的主键。表的候选键有三个属性:

    • 唯一性:在每条记录中,候选键的值唯一标识该记录。
    • 最小性:具有唯一性属性的超键的最小子集。
    • 非空性:候选键的值不允许为空。

    例如:在学生表中,如果学号本身能唯一确定一个学生,则学号就是一个候选键。

  3. 主键
    主键是在候选键中被指定为表的主要标识符的一个或多个属性。它必须具有唯一性和非空性。即主键的值在表中不能重复,并且每个元组都必须有主键值。

    例子:在学生表中,如果选定学号为主键,则学号字段上会施加唯一约束.

    主键的选择在关系数据模型中非常重要,很多性能问题都是由于主键选择不当引起的。

  4. 外键
    外键是一个关系(表)中的某个属性,它的值引用来另一个关系(表)的主键。这种结构建立了两个表之间的关联或链接.

    例子:在课程成绩表中,可能有一个“学号”字段,它是“学生表”的主键的副本,在这里学号就是外键。主键所在的表被称为父表,外键所在的表被称为子表。

例子说明:
学生成绩信息表中有(学号、姓名、性别、年龄、系别、专业等),我们假设学生的姓名唯一,没有重名的现象。

超键:
学生表中含有学号或者身份证号的任意组合都为此表的超键。如:
(学号)、(学号,姓名)、(学号,性别),这些都唯一,是超键。
(姓名,性别)唯一,是一个超键。
(姓名,年龄)唯一,是一个超键。
(姓名,性别,年龄)唯一,是一个超键。

候选键:
学号唯一,没有多余属性,是一个候选键。
姓名唯一,没有多余属性,是一个候选键。
(姓名,性别)唯一,但是单独姓名一个属性就能确定这个人是谁,所以性别这个属性就是多余属性,(姓名,性别)不是候选键,同样(姓名,年龄),(姓名,性别,年龄),也不是候选键。

主键:主键就是候选键里面的一个,是人为规定的,例如学生表中,我们通常会让“学号”做主键,学号能唯一标识这一个元组。

外键:外键就很简单了,假如我们还有一个老师表,每个老师都有自己的编号,假设老师编号在老师这个层次中是主键,在学生表中它就是外键。

1.2 关系数据模型中的完整性

1.2.1 空值

表示一个列的值目前还不知道或者对于当前记录来说不可用。空值可以意味着未知,也可以意味着某个记录没有值,或者只是意味着该值还没有提供。空值是处理不完整数据或异常数据的一种方式。空值与数字零或者空字符串不同,零和空字符串是值,但空值代表没有值。因此,空值应该与其他值区别对待。空值具有特殊性,当它参与逻辑运算时,结果取决于真值表。每种数据库系统对空值参与运算的规则定义也不尽相同。

1.2.2 关系完整性规则

关系数据模型中的完整性是指数据库中数据的正确性一致性有效性,以确保存储的数据满足特定业务规则和语义约束。关系数据库通过实施完整性约束来维护数据完整性,这些约束可以分为三大类:

  1. 实体完整性(Entity Integrity)

    • 实体完整性要求关系(表)中的主键列(Primary Key)具有唯一且非空的值。
    • 每一行都必须有一个唯一的标识符,这意味着在主键列上不允许出现重复值,并且主键列不能包含 NULL 值。
  2. 参照完整性(Referential Integrity)

    参照完整性是针对两个相关表之间引用关系的规定。
    当一个表中的外键(Foreign Key)引用了另一个表的主键时,参照完整性保证:外键的值要么与被引用表的主键值相匹配(存在性),要么为 NULL(如果允许的话);

    如果删除或更新被引用表中主键对应的记录,则需要根据相应的级联规则(如:CASCADE, SET NULL, RESTRICT 等)来决定是否允许操作以及如何影响关联的外键记录。

    例如:在学生选课表和课程表中,学生选课表中的课程 CourseID 必须是课程表中存在的 CourseID 或者允许为 NULL。

  3. 用户定义的完整性(User-defined Integrity)

    用户定义完整性是指由数据库应用程序开发人员根据具体应用领域的需求制定的一组额外的完整性约束条件。

    这些约束可以是对任何属性或属性集合的限制,例如规定某个数值范围、检查字符串长度、日期的有效性或者禁止某些组合等。

1.2.3 业务规则

定义或约束组织的某些方面的规则。业务规则的例子包括属性域和关系完整性规则。属性域用于约束特定列能够取的值。有些数据库系统,如 Oracle,支持叫做 check 的约束,也用于定义列中可以接受的值,但这种约束是定义在属性域之上的,比属性域的约束性更强。例如,员工表的性别列就可以加上 check 约束,使它只能取有限的个值。

1.2.4 关系数据库语言

关系数据库的主要语言是 SQL 语言,SQL 是 Structured Query Language 的缩写,意为结构化查询语言。

(1)DDL 是 Data Definition Language 的缩写,意为数据定义语言,用于定义数据库结构和模式。典型的 DDL 有 create、alter、drop、truncate、comment、rename等。

(2)数据查询语言 (DQL - Data Query Language),DQL 主要用于从数据库中检索信息而不进行任何修改。SELECT 语句是最主要的 DQL 操作,用于查询特定的数据,并可以结合 WHERE、GROUP BY、HAVING 和 ORDER BY 等子句来筛选、分组、过滤和排序数据。

(3)DML 是 Data Manipulation Language 的缩写,意为数据操纵语言,用于检索、管理和维护数据库对象。典型的 DML 有 select、insert、update、delete、merge、call、explain、lock 等。

(4)DCL 是 Data Control Language 的缩写,意为数据控制语言,用于授予和回收数据库对象上的权限。典型的 DCL 有 grant 和 revoke。

(5)TCL 是 Transaction Control Language 的缩写,意为事务控制语言,用于管理DML 对数据的改变。它允许一组 DML 语句联合成一个逻辑事务。典型的 TCL 有commit、rollback、savepoint 等。


1.3 关系数据模型中的规范化(☆☆☆重点记忆)

关系数据模型的规范化是一种数据组织的技术。规范化方法对表进行分解,以消除数据冗余,避免异常更新,提高数据完整性。

如果没有规范化,数据的更新处理将变得困难,异常的插入、修改、删除数据的操作会频繁发生。为了便于理解,来看下面的例子。

假设有一个 employee 的员工表,它有九个属性:id(员工编号)、name(员工姓名),mobile(电话)、zip(邮编)、province(省份)、city(城市)、district(区县)、deptNo(所属部门编号)、deptName(所属部门名称),表中的数据如表所示。

在这里插入图片描述


由于此员工表是非规范化的,我们将面对如下的问题。

  • 修改异常:上表中张三有两条记录,因为他隶属两个部门。如果我们要修改张三的地址,必须修改两行记录。假如一个部门得到了张三的新地址并进行了更新,而另一个部门没有,那么此时张三在表中会存在两个不同的地址,导致了数据不一致。
  • 新增异常:假如一个新员工加入公司,他正处于入职培训阶段,还没有被正式分配到某个部门,如果 deptNo 字段不允许为空,我们就无法向该表中新增该员工的数据。
  • 删除异常:假设公司撤销了 D3 这个部门,那么在删除 deptNo 为 D3 的行时,会将李四的信息也一并删除。因为他只隶属于 D3 这一个部门。

为了克服这些异常更新,我们需要对表进行规范化设计。规范化是通过应用范式规则实现的。

什么是范式?简言之就是,数据库设计对数据的存储性能,还有开发人员对数据的操作都有莫大的关系。所以建立科学的、规范的数据库是需要满足一些规范的来优化数据存储方式,在关系型数据库中这些规范就可以称为范式

常用的范式有第一范式(1NF)、第二范式(2NF)、第三范式(3NF)。

1.3.1 第一范式

每个属性(字段)的值必须是原子的(不可再分)。

上例中张三有两个手机号存储在 mobile 列中,违反了 1NF 规则。为了使表满足 1NF,数据应该修改为如下表所示。

在这里插入图片描述

1.3.2 第二范式

第二范式要同时满足下面两个条件: 1.满足第一范式,2.非主属性必须完全依赖于整个候选键,不能存在部分依赖

例如,员工表的一个候选键是{id,moblie,deptNo},而 deptName 依赖于(deptNo),同样 name 仅依赖于{id},因此不是 2NF 的。为了满足第二范式的条件,需要将这个表拆分成 employee、dept、employee_dept、employee_mobile 四个表,如表所示。
在这里插入图片描述

1.3.3 第三范式

第三范式要同时满足下面两个条件:== 1.满足第二范式;2.没有传递依赖==。

例如,员工表的 province、city、district 依赖于 zip,而 zip 依赖于(id),换句话说,province、city、district 传递依赖于(id),违反了 3NF 规则。为了满足第三范式的条件,可以将这个表拆分成 enployee 和 zip 两个表,如下所示。

在这里插入图片描述


这里再解释一下传递依赖:
数据不能存在传递关系,即每个属性都跟主键有直接关系而不是间接关系。像:a–>b–>c 属性之间含有这样的关系,是不符合第三范式的。

举个例子,比如 Student 表(学号,姓名,年龄,性别,所在院校,院校地址,院校电话),这样一个表结构,就存在上述关系:
学号–> 所在院校 --> (院校地址,院校电话)
这样的表结构,我们应该拆开来,如下:
(学号,姓名,年龄,性别,所在院校)–(所在院校,院校地址,院校电话)


2. 维度数据模型

维度模型诞生于 20 世纪 90 年代,由 Kimball 引入到数仓领域并形成数仓维度建模的理论体系,比较适合分析领域。

事实维度是两个维度模型中的核心概念。事实表示对业务数据的度量,而维度是观察数据的角度。事实通常是数字类型的,可以进行聚合和计算,而维度通常是一组层次关系或描述信息,用来定义事实

例如,销售金额是一个事实,而销售时间、销售的产品、购买的顾客、商店等都是销售事实的维度。

事实表记录了特定事件的数字化的考量,一般由数字值和指向维度表的外键组成。通常会把事实表的粒度级别设计得比较低,使得事实表可以记录很原始的操作型事件,但这样做的负面影响是累加大量记录可能会更耗时。事实表有以下三种类型:

  1. 事务事实表。统计某个时间点事件发生情况。每发生一次事件,表中就会插入一条记录,且发生的事件不会被修改,只能新增,如下单记录、支付记录、券领取记录。
  2. 周期快照事实表。统计某个时间区间内业务过程的当前状况或历史状况平均,如月底账户余额、每天、周、月商品销量。
  3. 累积快照事实表。统计流程节点运转效率。一般此类表有多个关键日期字段,且事务事件跨度不会太长,比如订单状态:下单、支付、发货、确认收货。

维度表的记录数通常比事实表少,但每条记录包含有大量用于描述事实数据的属性字段。维度表可以定义各种各样的特性,以下是几种最常用的维度表。

  1. 时间维度表。描述星型模式中记录的事件所发生的时间,具有所需的最低级别的时间粒度。数据仓库是随时间变化的数据集合,需要记录数据的历史,因此每个数据仓库都需要一个时间维度表。
  2. 地理维度表。描述位置信息的数据,如国家、省份、城市、区县、邮编等。
  3. 产品维度表。描述产品及其属性。
  4. 人员维度表。描述人员相关的信息,如销售人员、市场人员、开发人员等。。
  5. 范围维度表。描述分段数据的信息,如高级、中级、低级等。

2.1 维度数据模型建模过程(☆☆☆重点记忆)

  • 从模型结构上看:

    在这里插入图片描述

  • 从构建流程上看:
    在这里插入图片描述
    维度模型设计期间主要涉及 4 个主要的过程:
    (1)选择业务过程
    (2)声明粒度
    (3)确认维度
    (4)确认事实
    在建模期间,需要考虑业务需求以及协作建模阶段涉及的底层数据源。从上述维度建模步骤来看,重点在解决数据粒度、维度设计和事实表设计问题。
    在这里插入图片描述
    声明粒度,为业务最小活动单元或不同维度组合。以共同粒度从多个组织业务过程合并度量的事实表称为合并事实表,需要注意的是,来自多个业务过程的事实合并到合并事实表时,它们必须具有同样等级的粒度。

由于在维度建模过程中,涉及到很多概念。下面通过一个场景来,来一一说明。
例如:常见的电商下单环节,每个用户提交一笔订单(仅限一个物品),就对应于一条订单记录。
【业务过程】:下订单
【粒度】:每笔订单(拆分为单个物品)
【维度】:用户、商品、卖家、地域、渠道类型等(可供分析的角度
【事实/度量】:订单金额等(可用于分析的数据

2.1.1 需求收集

收集业务需求,在开始维度建模工作之前,需要理解业务需求,以及作为底层源数据的实际情况。通过与业务方沟通交流、查看现有报表等来发现需求,用于理解他们的基于关键性能指标、决策制定过程、支持分析需求的目标。同时,数据实际情况可通过与后端系统开发同事交流,了解访问数据可行性等。

2.1.2 业务过程

选择业务过程,业务过程是组织完成的操作型活动。理清业务过程,就是需要建立或获取性能度量,并转换为事实表中的事实。多数事实表关注某一业务过程的结果。过程的选择非常重要的,因为过程定义了特定的设计目标以及对粒度、维度、事实的定义。

2.1.3 声明粒度

声明粒度,声明粒度是维度设计的重要步骤。粒度用于确定某一事实表中的行表示什么。在选择维度或事实前必须声明粒度,因为每个候选维度或事实必须与定义的粒度保持一致。在从给定的业务过程获取数据时,原子粒度是最低级别的粒度。强烈建议从关注原子级别粒度数据开始设计,因为原子粒度数据能够承受无法预期的用户查询。

2.1.4 确认维度

确认维度(描述环境),维度提供围绕某一业务过程事件所涉及的“谁、什么、何处、何时、为什么、如何”等背景。维度表包含分析应用所需要的用于过滤及分类事实的描述性属性。牢牢掌握事实表的粒度,就能够将所有可能存在的维度区分开来。

2.1.5 确认事实

确认事实(用于度量),涉及来自业务过程事件的度量,基本上都是以数据值表示。一个事实表行与按照事实表粒度描述的度量事件之间存在一对一关系,因此事实表对应一个物理可观察的事件。在事实表内,所有事实只允许与声明的粒度保持一致。

例如:权益核销环节,每个用户下一笔订单(为方便退单,商品粒度为 sku),就对应于多条权益核销记录。
【业务过程】:券核销业务过程
【粒度】:子订单 + 券 id(拆分为单个 sku)
【维度】:权益、领取场景、发放渠道等(分析视角)
【事实/度量】:核销金额,引导 GMV 等(原子指标)


2.2 维度规范化

与关系模型类似,维度也可以进行规范化。对维度的规范化(又叫雪花化),目的是减少数据冗余,提高数据一致性以及优化查询性能。减少冗余属性,是对非规范化维度做的规范化处理,在下面介绍雪花模型时,会看到维度规范化的例子。一个非规范化维度对应一个维度表,规范化后,一个维度会对应多个维度表,维度被严格地以子维度的形式连接在一起。实际上,在很多情况下,维度规范化后的结构等同于一个低范式级别的关系型结构。

设计维度数据模型时,会因为如下原因而不对维度做规范化处理:

  1. 规范化会增加表的数量,使结构更复杂。
  2. 不可避免的多表连接,使查询更复杂。
  3. 查询性能原因。分析查询需要聚合计算或检索很多维度值,此时第三范式的数据会遭遇性能问题。如果需要的仅仅是操作型报表,可以使用第三范式,因为作型系统的用户需要看到更细节的数据。

正如在前面关系模型中提到的,对于是否应该规范化的问题存在一些争论。

总体来说,当多个维度共用其些通用的属性时,做规范化会是有益的。例如,客户和供应商都有省、市、区县、街道等地理位置的属性,此时分离出一个地区属性就比较合适。


2.3 建模特点

2.3.1 易理解

相对于规范化的关系模型,维度模型容易理解且更直观。在维度模型中,信息按业务种类或维度进行分组,这会提高信息的可读性,也方便了对于数据含义的解释。简化的模型也让系统以更为高效的方式访问数据库。关系模型中,数据被分布到多个离散的实体中,对于一个简单的业务流程,可能需要很多表联合在一起才能表示。

2.3.2 高性能

维度模型更倾向于非规范化,因为这样可以优化查询的性能。介绍关系模型时多次提到,规范化的实质是减少数据冗余,以优化事务处理或数据更新的性能。

这里用一个具体的例子进一步说明性能问题。
如图所示,左边是一个销售订单的典型的规范化表示。
在这里插入图片描述
订单(Order)实体描述有关订单整体的信息,订单明细(Order Line)实体描述有关订单项的信息,两个实体都包含描述其订单状态的信息。

右边是一个订单状态维(Order Status Dimension),该维表描述订单和订单明细中对应的状态编码值的唯一组合。它包括在规范化设计的订单和订单明细实体中都出现的属性。当销售订单事实行被装载时,参照在订单状态维中的适合的状态编码的组合设置它的外键。

维度设计的整体观点是要简化和加速查询。假设有 100 万订单,每个订单有10 条明细,订单状态和订单明细状态各有 10 种。

如果用户要查询某种状态特性的订单,按 3NF 模型,逻辑上需要关联 100 万记录与 1000 万记录的两个大表,然后过滤两个表的状态值得到所要的结果。另一方面,销售订单事实表(图中并没有画出)按最细数据粒度有 1000 万记录,3NF里的订单表属性在事实表里是冗余数据,状态维度有 100 条数据,只需要关联1000 万记录与 100 条记录的两个表,再进行状态过滤即可。

2.3.3 可扩展

维度模型是可扩展的。由于维度模型允许数据冗余,因此当向一个维度表或事实表中添加字段时,不会像关系模型那样产生巨大的影响,带来的结果就是更容易容纳不可预料的新增数据。这种新增可以是单纯地向表中增加新的数据行而不改变表结构,也可以是在现有表上增加新的属性。基于数据仓库的查询和应用不需要过多改变就能适应表结构的变化。历史的查询和应用会维续工作而不会产生错误的结果。但是对于规范化的关系模模型,由于表之间存在复杂的依赖关系,改变表结构前一定要仔细考虑。

2.4 星型模型(☆☆☆重点记忆)

2.4.1 什么是星型模型

星型模式是维度模型最简单的形式,也是数据仓库以及数据集市开发中使用最广的形式。星型模式由事实表和维度表组成,一个星型模式中可以有一个或多个事实表,每个事实表引用任意数量的维表

在这里插入图片描述
Sales Fact 是唯一的事实表,Dim_time、Dim_branch、Dim_location 和 Dim_item是四个维度表。每个维度表的 xxx_key 字段是它们的主键。

星型模式的物理模型像一颗星星的形状,中心是一个事实表,围绕在事实表周围的维度表表示星星的放射状分支,这就是星型模式这个名字的由来。

举个例子:星型模式将业务流程分为事实和维度。事实包含业务的度量,是定量的数据,如销售价格、销售数量、距离、速度、重量等。维度是对事实数据属性的描述。如日期、产品、客户、地理位置等是维度。

星型模型的特点:

  • 星型模式中的每个维都由唯一的一维表表示;
  • 维度表应包含属性集;
  • 使用外键将维度表连接到事实表;
  • 维度表未相互连接;
  • 事实表将包含键和度量;
  • 维度表并未规范化 normalized;
2.4.2 优点

星型模式是非规范化的,在星型模式的设计开发过程中,不受应用于事务型关系数据库的范式规则的约束。星型模式的优点如下:

  1. 简化查询。查询数据时,星型模式的连接逻辑比较简单,而从高度规范化的事实表查询数据时,往往需要更多的表连接。
  2. 简化业务报表逻辑。与高度规范化的模式相比,由于查询更简单,因此星型模式简化了普通的业务报表(如每月报表)逻辑。
  3. 获得查询性能。星型模式可以提升只读报表类应用的性能。
  4. 快速聚合。基于星型模式的简单查询能够提高聚合操作的性能。
  5. 各类 BI 工具广泛支持该架构,便于向立方体提供数据。星型模式被广泛用于高效地建立OLAP 立方体,几乎所有的 OLAP 系统都提供 ROLAP 模型(关系型 OLAP),它可以直接将星型模式中的数据当作数据源,而不用单独建立立方体结构。
2.4.3 缺点

星型模式的主要缺点是不能保证数据完整性。一次性地插入或更新操作可能会造成数据异常,而这种情况在规范化模型中是可以避免的。

  1. 插入异常
    假设销售主题域的数据仓库,其中事实表“SalesFact”和维度表“Customer”,“Product”,“Time”。在星型模型中,“SalesFact”直接连接到各个维度表。如果在一次批量加载过程中,新客户记录没有同时添加到“Customer”维度表,而此时有该客户的销售记录已经插入到了“SalesFact”表中,则会造成参照完整性问题。因为“SalesFact”中的外键(如 CustomerID)将指向一个不存在于“Customer”表中的记录。
  2. 更新异常
    在同样的场景下,假设某个产品信息发生了变化(例如产品名称或分类),由于星型模型通常不支持对历史数据的更新,若直接修改“Product”维度表,可能会导致之前存储的与该产品相关的所有销售记录(即“SalesFact”表中的记录)在分析时关联到新的产品信息,从而破坏了历史数据分析的一致性与准确性。
  3. 事务一致性
    星型模型主要用于读取密集型场景,而非事务处理场景。因此,在实时插入或更新操作中,难以保证 ACID(原子性、一致性、隔离性和持久性)事务原则。
    例如,当多个业务操作同时发生时,如果没有适当的并发控制机制,可能会造成数据的临时不一致状态。

星型模式的数据装载,一般都是以高度受控的方式,用批处理或准实时过程执行的,以此来抵消上面提到的不足。

星型模式的另一个缺点是对于分析需求来说不够灵活。它更偏重于为特定目的建造数据视图,因此实际上很难进行全面的数据分析。星型模式不能自然地支持业务实体的多对多关系,需要在维度表和事实表之间建立额外的桥接表。

2.5 雪花模型(☆☆☆重点记忆)

2.5.1 什么是雪花模型

雪花模式是星型模式的扩展,在雪花模式中,每个维度都经过规范化并连接到更多维度表,其实体关系图有类似于雪花的形状,因此得名。

与星型模式相同,雪花模式也是由事实表和维度表所组成。所谓的“雪花化”就是将星型模式中的维度表进行规范化处理。当所有的维度表完成规范化后,就形成了以事实表为中心的雪花型结构,即雪花模式

将维度表进行规范化的具体做法是,把低基数的属性从维度表中移除并形成单独的表。基数指的是一个字段中不同值的个数,如主键列具有唯一值,所以有最高的基数,而像性别这样的列基数就很低。

在这里插入图片描述

2.5.2 数据规范化与存储

规范化的过程就是将维度表中重复的组分离成一个新表,以减少数据冗余的过程。正因为如此,规范化不可避免地增加了表的数量。在执行查询的时候,不得不连接更多的表。但是规范化减少了存储数据的空间需求,而且提高了数据更新的效率。

从存储空间的角度看,典型的情况是维度表比事实表小很多。这就使得雪花化的维度表相对于星型模式来说,在存储空间上的优势没那么明显了。

举例来说,假设某个大型连锁商超在 220 个区县的 300 个商场,共有 100 万条销售记录。
星型模式的设计会产生 1000300 条记录,其中事实表 1000000 条记录,商场维度表有 300 条记录,每个区县信息作为商场的一个属性,显式地出现在商场维度表中。

在规范化的雪花模式中,会建立一个区县维度表,该表有 220 条记录,商场表引用区县表的主键,有 300 条记录,事实表没有变,还是 1000000 条记录,总的记录数 1000520(1000000+300+220)。

在这种情况(作为子表的商场记录数和父表的区县记录数差别不大)下,星型模式所需的空间反而比雪花模式要少。如果商场有 10000 家,情况就不一样了,星型模式的记录数是 1010000,雪花模式的记录数是 1010220,从记录数上看,还是雪花模型多。但是,星型模式的商场表中会有 10000 个冗余的区县属性信息,而在雪花模式中,商场表中只有 10000个区县的主键,而需要存储的区县属性信息只有 220 个,当区县的属性很多时,会大大减少数据存储占用的空间。

有些数据库开发者采取一种折中的方式,底层使用雪花模型,上层用表连接建立视图模拟星型模式。这种方法既通过对维度的规范化节省了存储空间,同时又对用户屏蔽了查询的复杂性。但是当外部的查询条件不需要连接整个维度表时,这种方法会带来性能损失。

2.5.3 优点

雪花模式是和星型模式类似的逻辑模型。实际上,星型模式是雪花模式的一个特例(维度没有多个层级,只有一层)。某些条件下,雪花模式更具优势:

  1. 在 Schema 中新增一个维度将变得更加容易;
  2. 规范化的维度属性节省存储空间。

例子:在电商数据仓库,星型模型中有一个商品销售事实表(Fact_Sales)和一个扁平化的维度表(Dim_Product)。结构如下:
在这里插入图片描述
在雪花模型中,商品维度可能是这样设计的:
在这里插入图片描述


现在业务需求变化,需要引入一个新的维度 — — “商品子类别”(SubCategory)。

在星型模型中,只能改变现有模型的情况下添加这个新维度,需要在Dim_Product 维度表中新增一个列SubCategoryName(蓝色字段)。

在雪花模型中,只需在 Dim_SubCategory 表中增加相应的记录,由于Dim_Product 已经通过 CategoryID 与 Dim_Category 关联,而 Dim_Category 又可以轻松地通过 SubCategoryID 与新的 Dim_SubCategory 关联,所以无需对事实表或者现有的维度表做任何修改。这种设计允许我们在不影响现有模型的基础上,更加灵活地添加、更新或扩展维度信息。

2.5.4 缺点
  1. 雪花模型的主要缺点是维度属性规范化增加了查询的连接操作和复杂度。相对于平面化的单表维度,多表连接的查询性能会有所下降。但雪花模型的查询性能问题近年来随着数据浏览工具的不断优化而得到缓解。

  2. 和具有更高规范化级别的事务型模式相比,雪花模式并不确保数据完整性。

  3. 向雪花模式的表中装载数据时,一定要有严格的控制和管理,避免数据的异常插入或更新。


2.6 星座模型

数据仓库是由多个主题组成的,包含多个事实表,而维表是公共的,可以被多个事实表关联使用,这种模式可以看做星型模式的汇集,因而称作星系模式或者事实星座模式。

在这里插入图片描述
星座模式是数据仓库最常使用的数据模式,尤其是企业级数据仓库(EDW)。

这也是数据仓库区别于数据集市的一个典型的特征,从根本上而言,数据仓库数据模型的模式更多是为了避免冗余和数据复用,套用现成的模式,是设计数据仓库最合理的选择。

“事实星座模式”的架构。这种设计强调避免冗余和数据复用,从而支持整个企业的决策分析需求。相比之下,数据集市则通常是针对某个特定业务领域或部门的需求建立的小规模、快速响应的数据集合,它们可能没有统一的维度模型和共享维度表。

2.7 星型模型 VS 雪花模型

在这里插入图片描述
星型模型因为数据的冗余所以很多统计查询不需要做外部的连接,因此一般情况下效率比雪花型模型要高

星型结构不用考虑很多正规化的因素,设计与实现都比较简单。雪花型模型由于去除了冗余,有些统计就需要通过表的联接才能产生,所以效率不一定有星型模型高。正规化也是一种比较复杂的过程,相应的数据库结构设计、数据的ETL、以及后期的维护都要复杂一些。因此在冗余可以接受的前提下,实际运用中星型模型使用更多,也更有效率

通过上面的对比我们可以发现,在数据仓库建设中大多时候比较适合使用星型模型构建底层数据 Hive 表,通过大量的冗余来提升查询效率,星型模型对 OLAP的分析引擎支持比较友好,这一点在 Kylin 中比较能体现。而雪花模型在关系型数据库中如 MySQL,Oracle 中非常常见,尤其像电商的数据库表。在数据仓库中雪花模型的应用场景比较少,但也不是没有,所以在具体设计的时候,可以考虑是不是能结合两者的优点参与设计,以此达到设计的最优化目的。

3. Data Vault 模型(了解即可)

3.1 Data Vault 模型简介

Data Vault 是面向细节的可追踪历史的一组有连接关系规范化表的集合。这些表可以支持一个或多个业务功能,它是一种综合了第三范式(3NF)和星型模型优点的建模方法。其设计理念是要满足企业对灵活性、可扩展性、一致性和对需求的适应性要求,是一种专为企业级数据仓库量身定制的建模方式。

Data Vault 方法需要跟踪所有数据的来源,因此其中每个数据行都要包含数据来源和装载时间属性,用以审计和跟踪数据值所对应的源系统

3.2 Data Vault 模型组成部分

  • 从模型结构上看:
    在这里插入图片描述
    Data Vault 模型是一种中心辐射式模型,其设计重点围绕着业务键的集成模式。这些业务键是存储在多个系统中的、针对各种信息的键,用于定位和唯一标识记录或数据。

    Data Vault 模型主要分为三种类型的表:中心表(Hub)、链接表(Link)、卫星表/附属表(Satellite),其中中心表记录业务主键,链接表记录业务关系,卫星表记录业务描述。

    下面来看一个实际的例子:如下图,hub—中心表、link—链接表、sat—卫星表。
    在这里插入图片描述

  • 从构建流程上看:
    在这里插入图片描述

3.2.1 中心表(Hub 组件)

中心表用来保存一个组织内的每个实体的业务主键,业务主键唯一标识某个业务实体。中心表和源系统表是相互独立的。当一个业务主键被用在多个系统时,它在 Data Vault 中也只保留一份,其他的组件都能接到这一个业务主键上。这就意味着业务数据都集成到了一起。

  • hub_key 代理主键,通过对业务主键进行 MD5 计算所得
  • business_key业务主键,唯一标识业务主键,来自业务的源系统
  • load_dts 数据第一次装载到数据仓库时系统生成的时间
  • rec_src 定义了数据来源(例如数据源系统或表)
3.2.2 链接表(Link 组件)

链接表是不同中心表之间的关系链接,链接表一般由一组外键字段构成,通过存储相关业务实体间 Hub 表的代理主键(Surrorgate Key),以记录一对多、多对多的业务实体间关系,如员工与企业的雇佣关系,账户与客户之间的关系等。链
接表主要包括主键、外键 1、···、外键 n、装载时间戳、数据来源系统等字段构成,其中主键对应多个外键的唯一组合,一般是与业务无关的序列数值。

  • link_key代理主键,使用相关的父 Hub 表的业务主键拼接后计算 MD5值
  • hub_keys hubs 的代理键
  • hub_business_keys hubs 的业务主键
  • load_dts 第一次装载数据的时间
  • rec_src 源系统信息
3.2.3 附属表(Satellite 组件)

附属表用于保存中心表和链接表的描述属性,包含了所有历史变化数据,附属表有且仅有一个唯一外键关联到中心表或链接表。

Hub 表中业务主键所对应的业务描述,即业务实体的属性信息,这些信息具有时效性,随时间变化而可能产生变化,因此,Satellite 组件内的记录均具有时间维,可记录实体属性的历史变化情况。根据实体属性变化频率的不同,可将一类实体的业务属性分为若干 Satellite 表,通过向 Satellite 分表追加记录,以实现在更小粒度下,实现第二类渐变维的保存历史数据特性。

Satellite 组件包括以下关键字段:

  • sta_key代理主键,相关的 hub 或 link 表的主键和数据载入时间的 MD5值
  • hub_or_link_key 父 hub 或 Link 的代理主键
  • attribute_columns 属性数据列
  • hash_diff 各列拼接后的 MD5 值计算
  • sat_load_dts 数据装载时间
  • sat_rec_src 数据来源信息

3.3 Data Vault 模型的特点

一个设计良好的 Data Vault 模型应该具有以下特点:

  1. 所有数据都基于时间来存储,即使数据是低质量的,也不能在 ETL 过程中处理掉。依赖越少越好。
  2. 和源系统越独立越好。
  3. 设计上适合变化:源系统中数据的变化;在不改变模型的情况下可扩展。
  4. ETL 作业可以重复执行。
  5. 数据完全可追踪。

4. 各模型对比

在这里插入图片描述


文章转载自:

http://3Usox52a.wkrkb.cn
http://PVLXmgdX.wkrkb.cn
http://QmLkbYQ1.wkrkb.cn
http://i9tIXJAW.wkrkb.cn
http://m8Brzlb0.wkrkb.cn
http://LsjmbaDG.wkrkb.cn
http://jbsKE0u7.wkrkb.cn
http://Hy32LLGL.wkrkb.cn
http://DpoFZDSU.wkrkb.cn
http://8B8XRXSY.wkrkb.cn
http://OLAVGuSD.wkrkb.cn
http://zOCzWQkq.wkrkb.cn
http://f1TL9tuO.wkrkb.cn
http://tVThrQ07.wkrkb.cn
http://9qEPOm4F.wkrkb.cn
http://96JczCgP.wkrkb.cn
http://oetvoBjG.wkrkb.cn
http://FVzEQxg7.wkrkb.cn
http://kwx4Ic98.wkrkb.cn
http://x1kZEJD0.wkrkb.cn
http://3dTYknkn.wkrkb.cn
http://ulEKo5fa.wkrkb.cn
http://90rgTqCK.wkrkb.cn
http://yEELm2h8.wkrkb.cn
http://rAO5NbND.wkrkb.cn
http://23hvG8EG.wkrkb.cn
http://J3fdmIzW.wkrkb.cn
http://6xuxqCDs.wkrkb.cn
http://b2h6weQu.wkrkb.cn
http://l2dOopVH.wkrkb.cn
http://www.dtcms.com/a/372355.html

相关文章:

  • 致远A8V5 9.0授权文件
  • 【New Phytologist】​​单细胞多组学揭示根毛对盐胁迫的特异性响应文献分享
  • MyBatis 拦截器让搞定监控、脱敏和权限控制
  • 20250907-0101:LangChain 核心价值补充
  • 论CMD、.NET、PowerShell、cmdlet四者关系
  • 从IFA展会看MOVA的“全维进阶”如何重新定义智能家居边界
  • SpringBoot 数据脱敏实战: 构建企业级敏感信息保护体系
  • 公链分析报告 - 模块化区块链1
  • 20250907-01:理解 LangChain 是什么 为什么诞生
  • 做一个鉴权系统
  • Javaweb - 14.5 Vue3 路由机制
  • 2.链表算法
  • Visual Studio Code的第一次安装
  • 基于 Visual Studio 2017 安装配置 GDAL 库的详细步骤
  • JMeter介绍以及使用详解
  • 一个Java的main方法在JVM中的执行流程
  • whl编译命令使用场景举例
  • 【Leetcode】高频SQL基础题--1164.指定日期的产品价格
  • 力扣1210. 穿过迷宫的最少移动次数 详解
  • Redis 从入门到精通:全平台安装与性能优化配置指南
  • RestClient查询和数据聚合
  • 前后端中的回调机制:含义、作用与实现详解
  • 四、神经网络的学习(下)
  • 万字详解网络编程之socket
  • PNG和JPEG和BMP文件格式转换
  • 语音之战+通用大模型,AI霸权决战打响
  • eslint 和 prettier 的相同点和区别
  • 苹果 FoundationModels 秘典侠客行:隐私为先的端侧 AI 江湖
  • hot100链表类题目
  • 算法:链表