数据仓库工具箱—读书笔记02(Kimball维度建模技术概述03、维度表技术基础)

news2024/12/27 18:58:23

Kimball维度建模技术概述

记录一下读《数据仓库工具箱》时的思考,摘录一些书中关于维度建模比较重要的思想与大家分享🤣🤣🤣

在这里插入图片描述

第二章前言部分作者提到:技术的介绍应该通过涵盖各种行业的熟悉的用例展开(赞同哈哈 确实比抽象地讲解概念要好理解🤣🤣🤣)。

书中从第三章开始是通过各行业的用例去讲解维度建模,第二章则是维度建模技术的总体介绍(很多概念,挺抽象的🤣🤣🤣)。

前言部分作者也有提到:我们并不期望您一开始就从头到尾阅读本章,但希望您能将本章作为所提供的技术参考。本节介绍的技术,在所有维度设计工作中都需要考虑。本书的每一章几乎都会涉及本节所介绍的概念。

01、基本概念
02、事实表技术基础

书接上回~🤣🤣🤣🤣🤣🤣


Kimball维度建模技术概述

  • Kimball维度建模技术概述
    • 2.3 维度表技术基础
      • 2.3.1 维度表结构
      • 2.3.2 维度代理键(Surrogate Key)
      • 2.3.3 自然键、持久键和超自然建
      • 2.3.4 下钻
      • 2.3.5 退化维度
      • 2.3.6 非规范化扁平维度
      • 2.3.7 多层次维度
      • 2.3.8 文档属性的标识与指示器
      • 2.3.9 维度表中的空值属性
      • 2.3.10 日历日期维度
      • 2.3.11 扮演角色的维度
      • 2.3.12 杂项维度
      • 2.3.13 雪花维度
      • 2.3.14 支架维度
      • 整理不易,列位一键三连,谢谢支持~🤣🤣🤣

2.3 维度表技术基础

2.3.1 维度表结构

维度表(Dimension Table) 用于存储描述性信息(维度属性),为事实表提供上下文支持

在这里插入图片描述

维度表结构通常围绕某个分析维度组织,如客户、产品、时间、地区等。

  1. 粒度清晰🍕:每条记录代表一个唯一的维度实体,粒度必须清晰(如每个客户、每个产品)。
  2. 主键唯一🍔:维度表的主键是每个维度实体的唯一标识,通常称为代理键(Surrogate Key)。
  3. 描述性属性🍟:维度表的列通常包含详细的描述信息,用于为事实表提供上下文。
  4. 数据量小🍿:相对于事实表,维度表的数据量通常较小,但可能包含丰富的属性字段。
  5. 变化管理🥓:维度表需要管理属性值的历史变化(例如,采用缓慢变化维度策略)。

维度表的主要字段

字段类别说明
代理键(Surrogate Key)维度表的主键,用于唯一标识维度记录,通常是系统生成的数字或UUID。
业务键(Business Key)来源系统的唯一标识符(如客户ID、产品SKU等),用于追踪源数据。
描述属性描述维度实体的属性,如客户的姓名、产品的类别等,用于丰富分析的上下文。
分组属性用于分类的字段,如产品类别、地理区域等,方便聚合分析。
时间属性用于标记或分析维度实体的时间变化,例如产品的上市日期、客户的注册日期等。

2.3.2 维度代理键(Surrogate Key)

维度代理键 是在维度表中用于唯一标识每条记录的人工生成的键,通常是一个简单的数字或唯一标识符(UUID)。代理键与事实表中的外键相对应,用于实现事实表和维度表之间的关联。

  1. 唯一性:每条记录都有唯一的代理键,用来区分不同的维度实体。
  2. 系统生成:代理键通常由数据仓库系统生成,而不是从源系统继承的业务键。
  3. 稳定性:即使源系统中的业务键发生变化,代理键仍然保持不变。
  4. 效率高:代理键通常为整数类型(如INTBIGINT),占用存储空间小,性能高。

Demo😋😋😋:

代理键(Surrogate Key)客户ID(业务键)客户姓名性别城市注册日期
1CUST001AliceFemaleNew York2023-01-10
2CUST002BobMaleLos Angeles2023-03-15
3CUST003CharlieMaleChicago2023-06-20
  • 代理键 (1, 2, 3) 是系统生成的,与源系统无关。
  • 业务键 (CUST001, CUST002, CUST003) 来自源系统,用于表示客户的原始标识。

代理键的优点

  1. 避免业务键变动的影响😋:源系统的业务键(如产品SKU或客户ID)可能会发生变更,而代理键的稳定性确保了数据仓库的结构不受影响。
  2. 支持缓慢变化维度(SCD)😎:当维度属性发生变化时,代理键可以区分不同版本的记录,帮助跟踪历史数据。

Demo🤣🤣🤣:

  • 当客户的地址发生变化时,可以新增一条记录,并分配新的代理键。
代理键客户ID(业务键)客户姓名性别城市生效开始日期生效结束日期
1CUST001AliceFemaleNew York2023-01-102023-05-01
2CUST001AliceFemaleBoston2023-05-02NULL
  • 第一条记录表示客户 Alice 在 New York 的历史状态
  • 第二条记录表示客户 Alice 在 Boston 的当前状态
  • 使用代理键(12)可以区分这些不同的状态,而业务键(CUST001)仍然一致。

  1. 提高查询效率:代理键的数值型特性比复杂的业务键(如字符串类型)更适合索引和连接操作。
  2. 支持多源数据集成:当维度数据来源于多个不同的源系统时,代理键可以统一标识不同来源的数据。

代理键的生成方式

  1. 自动递增数字:最常见的方法,通常由数据库的自动增量机制(如AUTO_INCREMENT)生成。
  2. UUID:全局唯一标识符,适用于分布式数据仓库,但存储空间和查询效率较低。
  3. 批量生成:通过ETL工具在加载数据时批量生成代理键。

代理键和业务键的区别

代理键客户ID(业务键)客户姓名性别城市生效开始日期生效结束日期
1CUST001AliceFemaleNew York2023-01-102023-05-01
2CUST001AliceFemaleBoston2023-05-02NULL
  1. 代理键(Surrogate Key)

    • 由系统生成,通常是整数类型。
    • 在数据仓库中作为维度表的主键,用于连接事实表。不受源系统数据变化的影响。
  2. 业务键(Business Key)

    • 来源于源系统,表示业务实体的唯一标识(如产品ID、客户ID等)。
    • 在数据仓库中用于追踪和映射源系统数据。

为什么使用代理键实现事实表和维度表之间的关联,而不是业务键?

  1. 稳定性

    • 业务键来自源系统,但可能会发生变化,例如产品ID或客户ID因为业务调整而修改。
    • 代理键是系统生成的唯一标识,独立于源系统,具有更高的稳定性和一致性。
  2. 效率

    • 业务键通常是字符串类型(如 P12345CUST001),占用存储空间较大,连接操作效率较低。
    • 代理键通常是整数类型(如 INTBIGINT),在存储和查询时更高效,尤其适合数据量大的事实表。
  3. 缓慢变化维度(SCD)的支持

    • 如果使用业务键作为关联,当维度数据发生变化(如客户地址变更)时,难以保留历史版本
    • 使用代理键,可以在维度表中为同一个业务键生成多个版本记录,从而轻松跟踪历史数据。
  4. 多源系统的数据集成

    • 不同源系统可能使用不同的业务键格式(如客户ID在一个系统中是数字,在另一个系统中是字符串)。
    • 通过引入代理键,可以统一不同源系统的数据。

Demo🤣🤣🤣:
产品维度表 (dim_product)

product_sk (代理键)product_id (业务键)product_namecategoryprice
1P1001“Laptop X1”Electronics1500.00
2P1002“Smartphone Z”Electronics800.00

销售事实表 (fact_sales)

sale_idproduct_sk (外键)quantity_soldsale_date
10011102023-12-10
1002252023-12-10
  • dim_product 表的 product_sk 是代理键(系统生成)。
  • fact_sales 表通过外键 product_sk 关联到 dim_product 表。

为什么不用 product_id 直接关联?

  • 如果 product_id(业务键)在源系统中发生变化,例如从 P1001 改为 PROD1001,这种变更会导致事实表中记录失效,关联关系断裂。
  • 代理键保持稳定,即使业务键发生变化,只需在维度表中更新即可,而不影响事实表的外键关系。

2.3.3 自然键、持久键和超自然建

  1. 自然键(Natural Key)

自然键是指在操作型系统中已经存在的、能够唯一标识实体的键。它直接来源于业务规则和现实世界的唯一标识符,例如雇员号产品编号订单号等。

  • 自然键受业务规则的影响,且通常无法被数据仓库(DW/BI系统)控制。
  • 在某些情况下,自然键可能会发生变化,比如雇员辞职后重新回到公司,系统会为其分配新的雇员号。
  • 这种变化对于数据仓库来说会带来问题,特别是当我们需要跨时间段跟踪和汇总历史数据时。
  1. 持久键(Surrogate Key)

为了应对自然键的变化,数据仓库使用持久键🤣🤣🤣

持久键是一种由数据仓库系统人工生成的唯一标识符,通常是递增的整数或其他类型的唯一标识符。

持久键的设计独立于业务过程,它并不依赖于业务规则,因此可以保持不变,即使业务中的自然键发生变化。


Demo🤣🤣🤣:

雇员维度表

员工_SK(持久键)员工_ID(自然键)员工姓名状态入职日期离职日期
1101张三在职2010-01-01NULL
2102李四在职2012-03-15NULL
3101张三离职2015-01-012016-01-01
4103王五在职2016-04-10NULL
5201张三在职2017-06-01NULL
  • 持久键(Employee_SK):在数据仓库中,持久键代表数据仓库中的每一条记录,通常是数字形式的唯一标识符

  • 持久键的“不会变化”是指它在数据仓库中始终保持唯一性和稳定性,而不是在每次记录的变化(如状态变化、重新入职)时都变。每条记录的持久键始终标识那条特定的记录。

  • 不同的记录(例如同一员工的入职、离职、再入职)会得到不同的持久键,以确保数据的完整性。


  1. 持久性超自然键(Persistent Surrogate Key)

持久性超自然键这个术语,实际上就是对持久键进一步描述的一个补充。强调了持久键的持久性超自然特性。

在数据仓库中,当某个实体(如雇员、客户等)在多个生命周期中有多个自然键变动时,持久键依然保持不变,始终指向同一实体。

  • 格式独立于业务过程:持久键的值(通常是整数)不受业务规则或实际应用场景的限制,它是完全独立的。例如,一个雇员的持久键可能是递增的整数 1, 2, 3…,这些值与实际的雇员号码无关。
  • 递增分配:持久键通常从整数 1 开始递增,确保每条记录有唯一标识符,并且在整个数据仓库中唯一。

2.3.4 下钻

下钻是从较高的聚合层次(汇总数据)进入更详细的层次(如具体记录)的过程

在这里插入图片描述

Demo🤣🤣🤣:

对销售数据集进行分析,数据以地区时间产品类别等维度进行汇总。

  • 高层次:首先看到的是整个国家的销售总额。
  • 下钻:可以选择“按省份”来查看销售数据,进一步细分到每个城市的销售额,甚至深入到具体的每个销售订单。
  • 进一步下钻:按“产品类别”或者“销售人员”等维度,查看更细粒度的数据。

Alt

年份季度总销售额
2024Q1100万元
2024Q2150万元
2024Q3200万元
2024Q4180万元
  1. 从总销售额下钻到季度:2024年的销售总额汇总为630万元,然后可以选择按季度进一步查看销售数据。

  2. 从季度下钻到月度:可以选择进一步下钻到每个季度的月度销售额。

  3. 从月度下钻到具体销售订单:如果希望深入了解某个月或某个产品的具体订单情况,可以继续下钻到具体的销售记录。


Tips:

在这里插入图片描述

  • 上卷(Drill-up)🤣🤣🤣:与下钻相对,上卷是指从较低层次的数据返回到更高层次的聚合信息。比如,在月度数据下钻到季度或年度时,可以通过“上卷”查看汇总的季度或年度数据。

2.3.5 退化维度

退化维度(Degenerate Dimension,简称DD)是数据仓库设计中的一个概念,通常用于事实表(Fact Table)中的维度列。

在这里插入图片描述
退化维度并不是指一种独立的维度表,而是指那些在事实表中作为维度存在,但没有单独维度表来描述的维度。😂

退化维度是直接存储在事实表中的维度,它不需要独立的维度表,因为它没有复杂的属性结构或层次。🤓

退化维度可以简化数据仓库的设计,减少不必要的表和关联,同时提高查询效率。

Tips:

  • 不需要独立维度表:退化维度通常只是某个业务过程中的一些关键字段,虽然它们像维度一样存在于事实表中,但没有单独的维度表来存储详细信息。
  • 简单性:这些维度通常非常简单,且通常不会变化,适合直接存储在事实表中。
  • 没有层次结构:退化维度没有复杂的层次结构或属性,因此不需要单独的维度表来维护。

Demo🤣🤣🤣:

退化维度通常用于那些在业务操作中需要频繁访问,但又不需要额外描述的字段。

在这里插入图片描述

  • 订单编号:在零售、物流或电商数据仓库中,订单编号通常是事实表中的一个字段,作为客户交易的唯一标识。它没有额外的属性,也不需要进一步分解,因此不需要建立单独的维度表。
  • 发票编号:财务数据仓库中,发票编号常作为事实表的字段,记录交易或支付的具体编号。这些编号本身通常没有多层次的描述,且通常直接与事实表关联。

销售事实表

销售ID(Sale_ID)订单编号(Order_ID)销售金额(Sale_Amount)销售日期(Sale_Date)
1100120002024-12-01
2100215002024-12-02
3100350002024-12-03

订单编号(Order_ID)就是一个退化维度。它代表了每个销售交易的唯一标识符,但不需要单独为其建立维度表,因为它本身没有更多的层次或属性(除了作为订单的唯一标识符)。


Tips:

  1. 避免重复和冗余:虽然退化维度在事实表中直接存储,但要确保这些字段不会引起数据冗余或重复。退化维度通常是唯一的标识符。

  2. 提高查询效率:将这些字段作为退化维度存储在事实表中,可以提高查询性能,因为查询可以直接通过事实表检索数据,避免了多表连接。

  3. 简单且稳定的维度:退化维度通常是业务中一些简单、稳定的标识符,它们不会频繁变化,通常只是一个值(如编号、ID等),没有更多的属性或层级结构。

退化维度与维度表的区别:

  • 维度表:通常包含一个主键字段,以及与业务相关的多个属性(如“产品维度表”可能包括产品编号、产品名称、产品类别等属性)。维度表是独立的,通常是星型模式(Star Schema)或雪花型模式(Snowflake Schema)的一部分。
  • 退化维度:没有独立的维度表,它通常只是事实表中的一个字段,用于标识某个业务过程,但没有额外的属性或描述。

2.3.6 非规范化扁平维度

非规范化扁平维度是通过将多个维度表合并为一个扁平表(多个维度表合并为一个大表)来提高查询性能,减少联接操作,简化查询,但同时也带来数据冗余和更新维护上的问题

在这里插入图片描述

在这种设计中,数据不按规范化的方式进行存储,而是以扁平的结构存储在一个维度表中🤔

主要目的是减少复杂的表连接,提供更高效的查询性能,特别是在OLAP查询(联机分析处理)中。


  1. 非规范化扁平维度的特点🤨

在这里插入图片描述

  • 数据冗余:为了提高查询性能,多个属性会被合并到一个表中,因此会导致数据冗余。例如,一个表中可能包含多个不同维度的属性,如产品、客户、地区等,而这些维度在规范化设计中通常会分布在不同的维度表中。
  • 减少联接操作:通过将多个维度合并为一个扁平维度表,查询时不需要对多个维度表进行连接操作,这在查询过程中能够节省大量的时间和计算资源。
  • 简化查询:查询时不需要复杂的联接,直接从一个表中提取所有相关信息,通常适用于需要频繁分析和聚合的场景。
  • 存储空间:由于数据冗余和扁平化存储,非规范化扁平维度表通常会占用更多的存储空间。

  1. 非规范化与规范化的对比
  • 规范化设计:规范化设计的目标是消除数据冗余,将数据分割成多个表,并通过主键/外键关系来连接。这样可以减少存储空间并避免数据冗余,但查询时需要对多个表进行联接,可能导致查询效率较低。

  • 非规范化设计:非规范化设计通过将多个相关的属性和维度放在一个表中,避免了复杂的联接操作。这种方法通常会导致数据冗余,但查询速度较快,因为数据已经被“预处理”并且存储为一个扁平化的结构。


Demo:

在这里插入图片描述

规范化设计

  • 产品维度表(Product Dimension)

    Product_IDProduct_NameCategory
    1手机电子产品
    2衣服服装
  • 客户维度表(Customer Dimension)

    Customer_IDCustomer_NameCustomer_Segment
    101张三VIP
    102李四普通
  • 地区维度表(Region Dimension)

    Region_IDRegion_Name
    1北京
    2上海
  • 销售事实表(Sales Fact)

    Sales_IDProduct_IDCustomer_IDRegion_IDAmount
    1110111000
    221022500

非规范化扁平维度设计

  • 销售维度表(Flattened Sales Dimension)
    Sales_IDProduct_IDProduct_NameCategoryCustomer_IDCustomer_NameCustomer_SegmentRegion_IDRegion_NameAmount
    11手机电子产品101张三VIP1北京1000
    22衣服服装102李四普通2上海500

销售维度表中包含了所有维度的字段:产品名称、产品类别、客户姓名、客户细分、地区名称等

非规范化扁平维度设计在查询时不需要对不同的维度表进行联接,直接通过一个扁平的表进行分析。


2.3.7 多层次维度

多层次维度(Hierarchical Dimension)是指的是在维度中存在层次结构每个层次代表不同的聚合级别

在这里插入图片描述

通过多层次维度,用户可以根据需要从较高层次的数据下钻(drill-down)到更详细的层次,或者从较低层次的数据上卷(drill-up)到更高层次的汇总数据


Demo:

在这里插入图片描述

时间维度(Time Dimension)

时间_ID季度
12024Q1112024-01-01
22024Q1122024-01-02
32024Q1132024-01-03
42024Q1242024-02-01
52024Q24122024-04-01
62024Q25132024-05-01

在这个表中,季度形成了多层次结构。可以按不同层级进行下钻或上卷:

  • 按年:用户可以先看到汇总的年度数据(例如,2024年的总销售额)。
  • 按季度:再按季度深入(例如,Q1的销售额)。
  • 按月:进一步查看每个月的数据(例如,2024年1月的销售额)。
  • 按日:可以查看具体某一天的数据(例如,2024年1月1日的销售额)。

地理维度(Geography Dimension)

地理_ID国家省/市城市区域
1中国北京市北京市朝阳区
2中国上海市上海市徐汇区
3美国加利福尼亚州洛杉矶市中心区
4美国纽约州纽约市曼哈顿区

层次结构包括国家省/市城市区域。可以从“国家”开始查看汇总数据,逐步下钻到具体的城市或区域。


2.3.8 文档属性的标识与指示器

文档属性的标识与指示器是用于描述和管理文档的特性、状态和行为的关键元素

标识符(ID)确保文档的唯一性,而指示器反映文档的状态、权限或任务要求。


Demo:

在这里插入图片描述

文档管理系统中,关于公司年度财务报告的文档。文档的属性可能包括:

  1. 文档IDDoc2024_FinancialReport
  2. 文档名称2024年财务报告
  3. 文档类型财务报告
  4. 创建日期2024-01-01
  5. 修改日期2024-03-01
  6. 版本号v1.1
  7. 作者yushifu

系统还可以有以下指示器来表示文档的状态:

  • 审核指示器 表示文档已通过审核。
  • 归档指示器未归档,表示文档还没有归档。
  • 权限指示器仅限财务部门,表示只有财务部门人员可以访问此文档。

文档ID确保每个报告都是唯一的,审核指示器告诉用户文档是否已经审核通过,权限指示器则明确哪些用户可以访问这个文档。🤣🤣🤣


2.3.9 维度表中的空值属性

推荐采用描述性字符串替代空值,避免使用空值(NULL)的做法。

空值处理的不一致性

不同的数据库管理系统(DBMS)在处理空值时的行为可能不同,这会导致跨系统、跨平台的兼容性问题。特别是在进行分组、连接、聚合、排序等操作时,空值可能会被不同的数据库系统以不同的方式处理。

  • 分组:在某些数据库中,空值可能会被视为一个单独的组,而在其他数据库中,空值可能会被忽略或与其他值合并。
  • 聚合函数:某些聚合函数(如 COUNTSUM 等)在遇到空值时的行为不同。例如,某些数据库会将空值排除在外,而其他数据库则会将其计为零。
  • 连接操作:在进行表连接时,空值可能导致不同的连接行为。使用空值时,联接条件的匹配可能不按预期工作,影响查询结果。

在这里插入图片描述


Demo:

某些员工的“部门”字段为空(NULL),可以使用“未知部门”来替代空值:

员工ID员工姓名部门
1张三销售部
2李四技术部
3王五未知部门

在查询时,无论使用哪个数据库系统,"未知部门" 都会被视为一个有效的字符串,参与分组、聚合和排序等操作,而不会因为空值的特殊处理导致不一致。

数据质量和业务逻辑

空值通常表示数据缺失或未定义,这在某些情况下可能是不可避免的。然而,过多的空值会导致数据质量问题和分析困难。采用描述性字符串替代空值,可以更明确地标识数据的缺失或异常,进而帮助维护数据的质量和一致性。

例如,当某个数据字段为空时,使用描述性字符串(如“待定”、“数据缺失”)可以明确表示该数据尚未确定或缺失,而不是简单的空值,避免了不确定性的困扰。

便于报告和展示

在生成报告和数据可视化时,空值可能会导致显示不完整或不易理解的结果。使用描述性字符串(如“无数据”、“待定”等)可以确保报告更加清晰易懂,避免了空值带来的空白或无意义的显示。

例如,当报表中出现空值时,用户可能无法理解该字段的实际含义,而用描述性字符串替代空值可以提供更多上下文信息,使报表更加直观和易于解读。


2.3.10 日历日期维度

日历日期维度(Calendar Date Dimension)通常用于描述与时间相关的各类信息。

Demo:

  • 日期ID(Date Key):每个日期的唯一标识符,通常是一个整型或字符型的字段,格式可以是YYYYMMDD(例如20241216)。
  • 日期(Date):实际的日期字段,通常是DATE类型,表示某一天。
  • (Year):日期所属的年份。
  • 季度(Quarter):日期所属的季度(通常是1, 2, 3, 4)。
  • 月份(Month):日期所属的月份(1到12)。
  • 月名称(Month Name):月份的名称,如JanuaryFebruary等。
  • 周数(Week Number):日期所属的周次(通常是1到52)。
  • 周末标识(Weekend Flag):标识某一天是否为周末。
  • 工作日标识(Weekday Flag):标识某一天是否为工作日。
  • 周几(Day of Week):表示日期是星期几(1到7,或者星期一到星期天)。
  • (Day of Month):日期是一个月中的第几天(1到31)。
  • 是否节假日(Holiday Flag):标识日期是否为节假日。
  • 是否上半年(First Half of Year Flag):标识日期是否为上半年(1表示上半年,0表示下半年)。
  • 季节(Season):日期所属的季节(如春、夏、秋、冬)。

设计原则

  • 唯一性:每一行代表一个日期,日期ID应确保唯一。
  • 灵活性:需要设计多个字段来支持按不同粒度进行时间分析。
  • 扩展性:日历维度应支持扩展,能够方便地处理未来的日期,避免在将来需要重新生成日期维度。
  • 考虑假期:如果业务涉及假期分析,应考虑在日期维度中加入假期字段。
日期ID日期季度月名称周数周几工作日标识是否节假日
202401012024-01-01202411January11101
202401022024-01-02202411January12210
202401032024-01-03202411January13310
202401042024-01-04202411January14410
202401052024-01-05202411January15510
202401062024-01-06202411January16601

生成日历日期维度表通常有两种方式:

静态生成法
静态生成法适用于历史数据已经确定且维度的时间范围有限的情况。可以根据需要的日期范围(例如从2000年到2025年),手动或通过脚本生成日期维度表。该方式通常适合在小规模的业务中。

动态生成法
动态生成法适用于业务需求变化较快或维度表数据需要持续更新的情况。例如,使用ETL工具或SQL脚本动态生成,实时生成未来的日期维度,并支持自动更新。动态生成的日期维度表能够根据实际业务需求灵活调整。


2.3.11 扮演角色的维度

扮演角色的维度(Role-Playing Dimension)指的是同一维度表根据业务需求在不同的上下文中“扮演”不同角色的情况。这种设计模式主要用于处理同一维度在不同场景下的多次引用。

在这里插入图片描述

  • 客户作为下单者:在订单事实表中,客户可能作为“下单者”角色存在。此时,客户ID会作为外键关联到客户维度表,以便获取下单者的详细信息。
  • 客户作为收货人:在相同的订单事实表中,客户也可能作为“收货人”角色存在。此时,同样是客户维度,但由于角色不同,可能需要通过不同的外键(如Customer_IDReceiver_ID)来区分。

处理方法

1 在事实表中使用多个外键
事实表中可以通过多个外键来引用同一个维度表。每个外键代表不同的角色,例如“下单者”和“收货人”都使用Customer_ID字段,但它们的业务角色不同。这样可以避免维度表冗余。

2 为不同角色命名维度表
如果同一个维度表有多个角色并且角色之间有显著差异,可以考虑为每个角色创建不同的维度表,这样可以更加明确和简化查询。不过,这种方法可能会带来一些冗余,通常适用于角色差异较大的情况。

在这里插入图片描述

  • 下单客户维度(Order Customer Dimension)
  • 收货客户维度(Shipping Customer Dimension)

2.3.12 杂项维度

杂项维度(Junk Dimension)用于存储一些不属于任何主维度(如客户、时间、产品等)的低维度属性。这些属性通常不具备明显的业务含义,也不适合单独建立维度表,但它们对于业务分析和查询有一定的作用。

在这里插入图片描述

  • 减少维度表数量:一些低维度的属性如果每个都单独创建一个维度表,会导致维度表的数量过多,从而增加数据库的复杂性和维护成本。通过将它们放入一个杂项维度表,可以显著减少维度表的数量。

  • 简化数据模型:将多个不相关的低卡数字段合并成一个维度表,可以使数据模型更加简洁,避免冗余和不必要的复杂度。

在这里插入图片描述

  • 提高查询性能:由于这些字段通常是低卡数的(例如只有几个可能的值),将它们放入一个杂项维度表中,可以通过减少维度表的关联来提高查询性能。
  • 避免数据冗余:避免在多个事实表中重复存储这些独立的小字段,从而减少数据冗余。

常见的杂项维度字段

  • 状态标志:表示某个实体的状态,如“是否有效”、“是否已激活”等。
  • 类型标志:如“销售类型”、“订单类型”等。
  • 优先级:如“高优先级”、“低优先级”等。
  • 分类标签:如“客户分类”、“产品标签”等。
  • 小型代码:表示一些小的分类代码,如“支付方式”、“配送方式”等。

这些字段通常是用来为事实表提供额外的上下文信息的,但它们没有足够的业务含义来单独创建维度表。

Demo🤣🤣🤣:

在这里插入图片描述

杂项维度ID状态标志优先级支付方式订单类型
1启用信用卡在线
2启用支付宝离线
3禁用微信支付在线
4启用信用卡离线
  • 杂项维度ID:唯一标识符,用作其他表的外键。
  • 状态标志优先级支付方式订单类型:这些是低卡数的小属性,通过杂项维度ID将它们组合成一个记录。
订单ID客户ID销售金额杂项维度ID
1001C0015001
1002C0022002
1003C0031503

通过 杂项维度ID 外键,可以查到该订单的状态优先级支付方式订单类型,而不需要在事实表中重复存储这些字段。

何时使用杂项维度

  • 多个低卡数属性:当一个事实表或维度表中有多个小属性,它们可能没有单独的业务含义,且数量有限。
  • 避免冗余:当这些小属性是重复的且频繁出现时,使用杂项维度表可以避免在事实表中冗余存储它们。
  • 简化数据模型:当这些小属性的独立性较弱且没有独立业务需求时,使用杂项维度表可以简化数据模型和减少表的数量。

2.3.13 雪花维度

雪花维度(Snowflake Dimension)是一种数据仓库设计模式,它是星型模式(Star Schema)的一种变体。

在雪花模型中,维度表被进一步规范化(Normalized),即将原本可以放在一个维度表中的多个字段分解成多个相关的子维度表。

在这里插入图片描述

相比星型模型中维度表的“扁平”结构,雪花模型的维度表具有更多的层次关系,形成类似雪花形状的结构,因此得名“雪花维度”。

  • 规范化:雪花维度通过规范化的方式,将维度表中的字段分解成多个子表,减少了数据的冗余。例如,在产品维度表中,如果有产品类别和产品品牌字段,可能会将这两个字段分别抽象成独立的“产品类别”维度和“产品品牌”维度。
  • 多层级关系:雪花维度的结构通常包含多个层次。例如,产品维度可能有“产品类别” → “产品品牌” → “产品名称”这样的层次结构,这样可以更灵活地进行数据管理。
  • 复杂的查询:雪花模型的查询通常比星型模型更复杂,因为它需要多表连接来获取完整的维度信息。

Demo🤣🤣🤣:

星型模型中的产品维度

产品ID产品名称品牌类别
P001手机苹果电子产品
P002洗衣机海尔家电
P003电视机索尼家电

雪花模型中的产品维度

在雪花模型中,产品维度表被进一步规范化,拆分成多个子表。

  • 产品维度表
产品ID产品名称品牌ID类别ID
P001手机B001C001
P002洗衣机B002C002
P003电视机B003C002
  • 品牌维度表
品牌ID品牌名称
B001苹果
B002海尔
B003索尼
  • 类别维度表
类别ID类别名称
C001电子产品
C002家电
  • 减少数据冗余:通过规范化,雪花模型避免了数据的重复存储。例如,品牌和类别信息被提取到单独的表中,避免了每个产品记录中都存储品牌和类别信息。
  • 数据更新方便:因为数据冗余较少,如果品牌或类别信息发生变化,只需要在相应的子维度表中进行修改,不需要修改每一条产品记录。
  • 易于管理:规范化后的表更符合标准化的数据库设计原则,结构更加清晰,数据管理和维护更加规范。
特性星型维度雪花维度
结构扁平化,所有维度字段都集中在一个维度表中规范化,维度表拆分成多个子维度表
查询性能查询速度较快,因为维度表不需要连接查询性能较差,需要多表JOIN操作
数据冗余可能存在冗余数据,因为重复存储相同的信息数据冗余少,减少了数据存储量
维护复杂度维护相对简单,因为只有一个维度表维护相对复杂,因为涉及多个维度表
ETL过程复杂度ETL过程较简单,数据直接插入维度表ETL过程复杂,需要分解并规范化数据

何时使用雪花维度

  • 数据的规范化需求:如果数据仓库中需要减少数据冗余并使数据更加规范化,雪花模型是一个好的选择。例如,产品的品牌和类别信息经常被重复使用,拆分成子表可以减少冗余。
  • 维度变化不频繁:当维度表中的字段变化不频繁时,使用雪花模型会让数据管理更加清晰,同时降低存储空间。
  • 查询负载较低或查询需求不复杂:如果查询性能不是最关键的因素,或者查询的维度表相对较小,雪花模型可以提供较好的数据结构和管理。

2.3.14 支架维度

支架维度(Bridge Dimension)是一种特殊类型的维度表,用于处理多对多关系的情况,尤其是在事实表和维度表之间存在复杂的多对多映射时。
在这里插入图片描述

支架维度的主要作用是解决在一个事实记录中需要关联多个维度值的场景,常见的应用场景包括多个角色、多个产品类别、多项业务标志等。

在这里插入图片描述

在某些情况下用来桥接两个维度表,使得每条事实记录能够同时关联多个维度值。支架维度的主要作用是将多个维度值组合在一起,作为一个联合维度,帮助简化多对多关系的处理。

在这里插入图片描述

Demo:

  • 员工维度
员工ID员工姓名
E001张三
E002李四
E003王五
  • 角色维度
角色ID角色名称
R001销售代表
R002客户经理
  • 支架维度表(桥接表):
支架维度ID员工ID角色ID
1E001R001
1E002R002
2E003R001

  • 产品维度
产品ID产品名称
P001手机
P002电视机
P003洗衣机
  • 供应商维度
供应商ID供应商名称
S001苹果公司
S002三星公司
S003海尔公司
  • 支架维度表
支架维度ID产品ID供应商ID
1P001S001
1P001S002
2P002S003

支架维度的优点

  • 简化多对多关系:支架维度可以帮助解决事实表和维度表之间的多对多关系,避免了将多个维度值重复存储在事实表中的冗余数据。

  • 提高查询灵活性:支架维度可以灵活地关联多个维度,使得查询更具灵活性。通过支架维度表,可以在多个维度之间进行更复杂的分析。

    在这里插入图片描述

支架维度的缺点

  • 查询复杂性:支架维度的使用增加了查询的复杂性,因为查询时需要多表连接。如果查询涉及多个支架维度,可能需要做大量的联接操作。
  • ETL过程复杂:在ETL过程中,需要将多个维度表中的数据组合到支架维度表中,这可能增加ETL过程的复杂性和计算成本。

整理不易,列位一键三连,谢谢支持~🤣🤣🤣

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2266550.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

设置首选网络类型以及调用Android框架层的隐藏API

在Android SDK中提供的framework.jar是阉割版本的,比如有些类标记为hide,这些类不会被打包到这个jar中,而有些只是类中的某个方法或或属性被标记为hide,则这些类或属性会被打包到framework.jar,但是我们无法调用&#…

3D几何建模引擎Parasolid功能解析

一、什么是Parasolid? Parasolid是由Siemens PLM Software开发的高精度精密几何建模引擎。它全面评估CAD(计算机辅助设计)、CAM(计算机辅助制造)、CAE(计算机辅助工程)、PLM(产品生…

xinput1_3.dll放在哪里?当xinput1_3.dll丢失时的应对策略:详细解决方法汇总

在计算机系统的运行过程中,我们偶尔会遇到一些令人困扰的问题,其中xinput1_3.dll文件丢失就是较为常见的一种情况。这个看似不起眼的动态链接库文件,实则在许多软件和游戏的正常运行中发挥着至关重要的作用。一旦它丢失,可能会导致…

【开源免费】基于SpringBoot+Vue.JS安康旅游网站(JAVA毕业设计)

本文项目编号 T 098 ,文末自助获取源码 \color{red}{T098,文末自助获取源码} T098,文末自助获取源码 目录 一、系统介绍二、数据库设计三、配套教程3.1 启动教程3.2 讲解视频3.3 二次开发教程 四、功能截图五、文案资料5.1 选题背景5.2 国内…

CSS(三)盒子模型

目录 Content Padding Border Margin 盒子模型计算方式 使用 box-sizing 属性控制盒子模型的计算 所有的HTML元素都可以看作像下图这样一个矩形盒子: 这个模型包括了四个区域:content(内容区域)、padding(内边距…

LeetCode - Google 校招100题 第7天 序列(数据结构贪心) (15题)

欢迎关注我的CSDN:https://spike.blog.csdn.net/ 本文地址:https://spike.blog.csdn.net/article/details/144744418 相关文章: LeetCode 合计最常见的 112 题: 校招100题 第1天 链表(List) (19题)校招100题 第2天 树(Tree) (21题)校招100题 第3天 动态规划(DP) (

E-commerce .net+React(一)——项目初始化

文章目录 项目地址一、创建.Net环境1.1环境配置1.1.1 使用vscode创建webapi1.1.2 Clean architecture结构创建1.1.3 将创建好结构的项目添加到git里1.1.4 EF Core配置1. 在infrastructure里安装EF所需环境2. 创建Product数据模型3. 创建EF Core的DbContext 数据库上下文4. 创建…

农家乐系统|Java|SSM|VUE| 前后端分离

【技术栈】 1⃣️:架构: B/S、MVC 2⃣️:系统环境:Windowsh/Mac 3⃣️:开发环境:IDEA、JDK1.8、Maven、Mysql5.7 4⃣️:技术栈:Java、Mysql、SSM、Mybatis-Plus、VUE、jquery,html 5⃣️数据库可…

NIPS2014 | GAN: 生成对抗网络

Generative Adversarial Nets 摘要-Abstract引言-Introduction相关工作-Related Work对抗网络-Adversarial Nets理论结果-Theoretical Results实验-Experiments优势和不足-Advantages and disadvantages缺点优点 结论及未来工作-Conclusions and future work研究总结未来研究方…

《战神:诸神黄昏》游戏运行时提示找不到emp.dll怎么办?emp.dll丢失如何修复?

《战神:诸神黄昏》游戏运行时提示找不到emp.dll怎么办?emp.dll丢失的修复方法 在畅游《战神:诸神黄昏》这款史诗级游戏的过程中,如果突然遭遇“找不到emp.dll”的错误提示,无疑会打断你的冒险之旅。作为一名深耕软件开…

笔记本通过HDMI转VGA线连接戴尔显示器,wifi不可用或网速变慢

早上开开心心的来使用我的分屏显示器,结果winP开拓展,我的wifi就断掉了,琢磨了好一阵我以为是wifi的问题,发现不进行拓展,网络又好了,一上午就研究这个了,说是hdmi信号干扰了wifi信号啥的额&…

【MATLAB第110期】#保姆级教学 | 基于MATLAB的PAWN全局敏感性分析方法(无目标函数)含特征变量置信区间分析

【MATLAB第110期】#保姆级教学 | 基于MATLAB的PAWN全局敏感性分析方法(无目标函数)含特征变量置信区间分析 一、介绍 PAWN(Probabilistic Analysis With Numerical Uncertainties)是一种基于密度的全局敏感性分析(Gl…

BiTCN-BiGRU基于双向时间卷积网络结合双向门控循环单元的数据多特征分类预测(多输入单输出)

Matlab实现BiTCN-BiGRU基于双向时间卷积网络结合双向门控循环单元的数据多特征分类预测(多输入单输出) 目录 Matlab实现BiTCN-BiGRU基于双向时间卷积网络结合双向门控循环单元的数据多特征分类预测(多输入单输出)分类效果基本描述…

python: Oracle Stored Procedure query table

oracel sql script CREATE OR REPLACE PROCEDURE SelectSchool(paramSchoolId IN char,p_cursor OUT SYS_REFCURSOR ) AS BEGINOPEN p_cursor FORSELECT *FROM SchoolWHERE SchoolId paramSchoolId; END SelectSchool; /-- 查询所有 CREATE OR REPLACE PROCEDURE SelectScho…

软件老化分析

软件老化 课程:软件质量分析 作业 解答 Python代码如下: n int(input("类别数:")) theta list(map(float, input("各个类别的权重:").split())) m list(map(int, input("各个类别的度量元数量&…

cesium通过经纬度获取3dtiles 得feature信息

找到这里3dtiles的两种访问方式: 1.1 3DTileContent#getFeature 这里涉及3DTile 数据结构,暂不了解3DTile 数据结构,因此暂不使用。 1.2 scene.pick 本次使用 scene表示虚拟场景中所有 3D 图形对象和状态的容器;scene中…

【Lua之·Lua与C/C++交互·Lua CAPI访问栈操作】

系列文章目录 文章目录 前言一、概述1.1 Lua堆栈 二、栈操作2.1 基本的栈操作2.2 入栈操作函数2.3 出栈操作函数2.4 既入栈又出栈的操作函数2.5 栈检查与类型转换函数2.5 获取表数据 三、实例演示总结 前言 Lua是一种轻量级的、高性能的脚本语言,经常被用于游戏开发…

Linux -- 生产消费模型

目录 概念 代码 BlockQueue.hpp 代码: 伪唤醒!! Thread.hpp 代码: Task.hpp 代码: test.cc 代码: 再次理解 概念 生产消费模型,也称为生产者-消费者问题,是计算机科学中的一…

DevOps实战:用Kubernetes和Argo打造自动化CI/CD流程(1)

DevOps实战:用Kubernetes和Argo打造自动化CI/CD流程(1) 架构 架构图 本设计方案的目标是在一台阿里云ECS服务器上搭建一个轻量级的Kubernetes服务k3s节点,并基于Argo搭建一套完整的DevOps CI/CD服务平台,包括Argo CD…

React 第二十节 useRef 用途使用技巧注意事项详解

简述 useRef 用于操作不需要在视图上渲染的属性数据,用于访问真实的DOM节点,或者React组件的实例对象,允许直接操作DOM元素或者是组件; 写法 const inpRef useRef(params)参数: useRef(params),接收的 …