数据仓库工具箱—读书笔记02(Kimball维度建模技术概述03、维度表技术基础)
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) 用于存储描述性信息(维度属性),为事实表提供上下文支持。
维度表结构通常围绕某个分析维度组织,如客户、产品、时间、地区等。
- 粒度清晰🍕:每条记录代表一个唯一的维度实体,粒度必须清晰(如每个客户、每个产品)。
- 主键唯一🍔:维度表的主键是每个维度实体的唯一标识,通常称为代理键(Surrogate Key)。
- 描述性属性🍟:维度表的列通常包含详细的描述信息,用于为事实表提供上下文。
- 数据量小🍿:相对于事实表,维度表的数据量通常较小,但可能包含丰富的属性字段。
- 变化管理🥓:维度表需要管理属性值的历史变化(例如,采用缓慢变化维度策略)。
维度表的主要字段
字段类别 | 说明 |
---|---|
代理键(Surrogate Key) | 维度表的主键,用于唯一标识维度记录,通常是系统生成的数字或UUID。 |
业务键(Business Key) | 来源系统的唯一标识符(如客户ID、产品SKU等),用于追踪源数据。 |
描述属性 | 描述维度实体的属性,如客户的姓名、产品的类别等,用于丰富分析的上下文。 |
分组属性 | 用于分类的字段,如产品类别、地理区域等,方便聚合分析。 |
时间属性 | 用于标记或分析维度实体的时间变化,例如产品的上市日期、客户的注册日期等。 |
2.3.2 维度代理键(Surrogate Key)
维度代理键 是在维度表中用于唯一标识每条记录的人工生成的键,通常是一个简单的数字或唯一标识符(UUID)。代理键与事实表中的外键相对应,用于实现事实表和维度表之间的关联。
- 唯一性:每条记录都有唯一的代理键,用来区分不同的维度实体。
- 系统生成:代理键通常由数据仓库系统生成,而不是从源系统继承的业务键。
- 稳定性:即使源系统中的业务键发生变化,代理键仍然保持不变。
- 效率高:代理键通常为整数类型(如
INT
或BIGINT
),占用存储空间小,性能高。
Demo😋😋😋:
代理键(Surrogate Key) | 客户ID(业务键) | 客户姓名 | 性别 | 城市 | 注册日期 |
---|---|---|---|---|---|
1 | CUST001 | Alice | Female | New York | 2023-01-10 |
2 | CUST002 | Bob | Male | Los Angeles | 2023-03-15 |
3 | CUST003 | Charlie | Male | Chicago | 2023-06-20 |
- 代理键 (
1
,2
,3
) 是系统生成的,与源系统无关。 - 业务键 (
CUST001
,CUST002
,CUST003
) 来自源系统,用于表示客户的原始标识。
代理键的优点
- 避免业务键变动的影响😋:源系统的业务键(如产品SKU或客户ID)可能会发生变更,而代理键的稳定性确保了数据仓库的结构不受影响。
- 支持缓慢变化维度(SCD)😎:当维度属性发生变化时,代理键可以区分不同版本的记录,帮助跟踪历史数据。
Demo🤣🤣🤣:
- 当客户的地址发生变化时,可以新增一条记录,并分配新的代理键。
代理键 | 客户ID(业务键) | 客户姓名 | 性别 | 城市 | 生效开始日期 | 生效结束日期 |
---|---|---|---|---|---|---|
1 | CUST001 | Alice | Female | New York | 2023-01-10 | 2023-05-01 |
2 | CUST001 | Alice | Female | Boston | 2023-05-02 | NULL |
- 第一条记录表示客户 Alice 在 New York 的历史状态。
- 第二条记录表示客户 Alice 在 Boston 的当前状态。
- 使用代理键(
1
和2
)可以区分这些不同的状态,而业务键(CUST001
)仍然一致。
- 提高查询效率:代理键的数值型特性比复杂的业务键(如字符串类型)更适合索引和连接操作。
- 支持多源数据集成:当维度数据来源于多个不同的源系统时,代理键可以统一标识不同来源的数据。
代理键的生成方式
- 自动递增数字:最常见的方法,通常由数据库的自动增量机制(如
AUTO_INCREMENT
)生成。 - UUID:全局唯一标识符,适用于分布式数据仓库,但存储空间和查询效率较低。
- 批量生成:通过ETL工具在加载数据时批量生成代理键。
代理键和业务键的区别
代理键 | 客户ID(业务键) | 客户姓名 | 性别 | 城市 | 生效开始日期 | 生效结束日期 |
---|---|---|---|---|---|---|
1 | CUST001 | Alice | Female | New York | 2023-01-10 | 2023-05-01 |
2 | CUST001 | Alice | Female | Boston | 2023-05-02 | NULL |
-
代理键(Surrogate Key):
- 由系统生成,通常是整数类型。
- 在数据仓库中作为维度表的主键,用于连接事实表。不受源系统数据变化的影响。
-
业务键(Business Key):
- 来源于源系统,表示业务实体的唯一标识(如产品ID、客户ID等)。
- 在数据仓库中用于追踪和映射源系统数据。
为什么使用代理键实现事实表和维度表之间的关联,而不是业务键?
-
稳定性:
- 业务键来自源系统,但可能会发生变化,例如产品ID或客户ID因为业务调整而修改。
- 代理键是系统生成的唯一标识,独立于源系统,具有更高的稳定性和一致性。
-
效率:
- 业务键通常是字符串类型(如
P12345
或CUST001
),占用存储空间较大,连接操作效率较低。 - 代理键通常是整数类型(如
INT
或BIGINT
),在存储和查询时更高效,尤其适合数据量大的事实表。
- 业务键通常是字符串类型(如
-
缓慢变化维度(SCD)的支持:
- 如果使用业务键作为关联,当维度数据发生变化(如客户地址变更)时,难以保留历史版本。
- 使用代理键,可以在维度表中为同一个业务键生成多个版本记录,从而轻松跟踪历史数据。
-
多源系统的数据集成:
- 不同源系统可能使用不同的业务键格式(如客户ID在一个系统中是数字,在另一个系统中是字符串)。
- 通过引入代理键,可以统一不同源系统的数据。
Demo🤣🤣🤣:
产品维度表 (dim_product
)
product_sk (代理键) | product_id (业务键) | product_name | category | price |
---|---|---|---|---|
1 | P1001 | “Laptop X1” | Electronics | 1500.00 |
2 | P1002 | “Smartphone Z” | Electronics | 800.00 |
销售事实表 (fact_sales
)
sale_id | product_sk (外键) | quantity_sold | sale_date |
---|---|---|---|
1001 | 1 | 10 | 2023-12-10 |
1002 | 2 | 5 | 2023-12-10 |
dim_product
表的product_sk
是代理键(系统生成)。fact_sales
表通过外键product_sk
关联到dim_product
表。
为什么不用 product_id
直接关联?
- 如果
product_id
(业务键)在源系统中发生变化,例如从P1001
改为PROD1001
,这种变更会导致事实表中记录失效,关联关系断裂。 - 代理键保持稳定,即使业务键发生变化,只需在维度表中更新即可,而不影响事实表的外键关系。
2.3.3 自然键、持久键和超自然建
- 自然键(Natural Key)
自然键是指在操作型系统中已经存在的、能够唯一标识实体的键。它直接来源于业务规则和现实世界的唯一标识符,例如雇员号、产品编号、订单号等。
- 自然键受业务规则的影响,且通常无法被数据仓库(DW/BI系统)控制。
- 在某些情况下,自然键可能会发生变化,比如雇员辞职后重新回到公司,系统会为其分配新的雇员号。
- 这种变化对于数据仓库来说会带来问题,特别是当我们需要跨时间段跟踪和汇总历史数据时。
- 持久键(Surrogate Key)
为了应对自然键的变化,数据仓库使用持久键🤣🤣🤣。
持久键是一种由数据仓库系统人工生成的唯一标识符,通常是递增的整数或其他类型的唯一标识符。
持久键的设计独立于业务过程,它并不依赖于业务规则,因此可以保持不变,即使业务中的自然键发生变化。
Demo🤣🤣🤣:
雇员维度表
员工_SK(持久键) | 员工_ID(自然键) | 员工姓名 | 状态 | 入职日期 | 离职日期 |
---|---|---|---|---|---|
1 | 101 | 张三 | 在职 | 2010-01-01 | NULL |
2 | 102 | 李四 | 在职 | 2012-03-15 | NULL |
3 | 101 | 张三 | 离职 | 2015-01-01 | 2016-01-01 |
4 | 103 | 王五 | 在职 | 2016-04-10 | NULL |
5 | 201 | 张三 | 在职 | 2017-06-01 | NULL |
-
持久键(Employee_SK):在数据仓库中,持久键代表数据仓库中的每一条记录,通常是数字形式的唯一标识符。
-
持久键的“不会变化”是指它在数据仓库中始终保持唯一性和稳定性,而不是在每次记录的变化(如状态变化、重新入职)时都变。每条记录的持久键始终标识那条特定的记录。
-
不同的记录(例如同一员工的入职、离职、再入职)会得到不同的持久键,以确保数据的完整性。
- 持久性超自然键(Persistent Surrogate Key)
持久性超自然键这个术语,实际上就是对持久键进一步描述的一个补充。强调了持久键的持久性和超自然特性。
在数据仓库中,当某个实体(如雇员、客户等)在多个生命周期中有多个自然键变动时,持久键依然保持不变,始终指向同一实体。
- 格式独立于业务过程:持久键的值(通常是整数)不受业务规则或实际应用场景的限制,它是完全独立的。例如,一个雇员的持久键可能是递增的整数
1, 2, 3…
,这些值与实际的雇员号码无关。 - 递增分配:持久键通常从整数
1
开始递增,确保每条记录有唯一标识符,并且在整个数据仓库中唯一。
2.3.4 下钻
下钻是从较高的聚合层次(汇总数据)进入更详细的层次(如具体记录)的过程。
Demo🤣🤣🤣:
对销售数据集进行分析,数据以地区、时间、产品类别等维度进行汇总。
- 高层次:首先看到的是整个国家的销售总额。
- 下钻:可以选择“按省份”来查看销售数据,进一步细分到每个城市的销售额,甚至深入到具体的每个销售订单。
- 进一步下钻:按“产品类别”或者“销售人员”等维度,查看更细粒度的数据。
年份 | 季度 | 总销售额 |
---|---|---|
2024 | Q1 | 100万元 |
2024 | Q2 | 150万元 |
2024 | Q3 | 200万元 |
2024 | Q4 | 180万元 |
-
从总销售额下钻到季度:2024年的销售总额汇总为630万元,然后可以选择按季度进一步查看销售数据。
-
从季度下钻到月度:可以选择进一步下钻到每个季度的月度销售额。
-
从月度下钻到具体销售订单:如果希望深入了解某个月或某个产品的具体订单情况,可以继续下钻到具体的销售记录。
Tips:
- 上卷(Drill-up)🤣🤣🤣:与下钻相对,上卷是指从较低层次的数据返回到更高层次的聚合信息。比如,在月度数据下钻到季度或年度时,可以通过“上卷”查看汇总的季度或年度数据。
2.3.5 退化维度
退化维度(Degenerate Dimension,简称DD)是数据仓库设计中的一个概念,通常用于事实表(Fact Table)中的维度列。
退化维度并不是指一种独立的维度表,而是指那些在事实表中作为维度存在,但没有单独维度表来描述的维度。😂
退化维度是直接存储在事实表中的维度,它不需要独立的维度表,因为它没有复杂的属性结构或层次。🤓
退化维度可以简化数据仓库的设计,减少不必要的表和关联,同时提高查询效率。
Tips:
- 不需要独立维度表:退化维度通常只是某个业务过程中的一些关键字段,虽然它们像维度一样存在于事实表中,但没有单独的维度表来存储详细信息。
- 简单性:这些维度通常非常简单,且通常不会变化,适合直接存储在事实表中。
- 没有层次结构:退化维度没有复杂的层次结构或属性,因此不需要单独的维度表来维护。
Demo🤣🤣🤣:
退化维度通常用于那些在业务操作中需要频繁访问,但又不需要额外描述的字段。
- 订单编号:在零售、物流或电商数据仓库中,订单编号通常是事实表中的一个字段,作为客户交易的唯一标识。它没有额外的属性,也不需要进一步分解,因此不需要建立单独的维度表。
- 发票编号:财务数据仓库中,发票编号常作为事实表的字段,记录交易或支付的具体编号。这些编号本身通常没有多层次的描述,且通常直接与事实表关联。
销售事实表:
销售ID(Sale_ID) | 订单编号(Order_ID) | 销售金额(Sale_Amount) | 销售日期(Sale_Date) |
---|---|---|---|
1 | 1001 | 2000 | 2024-12-01 |
2 | 1002 | 1500 | 2024-12-02 |
3 | 1003 | 5000 | 2024-12-03 |
订单编号(Order_ID)就是一个退化维度。它代表了每个销售交易的唯一标识符,但不需要单独为其建立维度表,因为它本身没有更多的层次或属性(除了作为订单的唯一标识符)。
Tips:
-
避免重复和冗余:虽然退化维度在事实表中直接存储,但要确保这些字段不会引起数据冗余或重复。退化维度通常是唯一的标识符。
-
提高查询效率:将这些字段作为退化维度存储在事实表中,可以提高查询性能,因为查询可以直接通过事实表检索数据,避免了多表连接。
-
简单且稳定的维度:退化维度通常是业务中一些简单、稳定的标识符,它们不会频繁变化,通常只是一个值(如编号、ID等),没有更多的属性或层级结构。
退化维度与维度表的区别:
- 维度表:通常包含一个主键字段,以及与业务相关的多个属性(如“产品维度表”可能包括产品编号、产品名称、产品类别等属性)。维度表是独立的,通常是星型模式(Star Schema)或雪花型模式(Snowflake Schema)的一部分。
- 退化维度:没有独立的维度表,它通常只是事实表中的一个字段,用于标识某个业务过程,但没有额外的属性或描述。
2.3.6 非规范化扁平维度
非规范化扁平维度是通过将多个维度表合并为一个扁平表(多个维度表合并为一个大表)来提高查询性能,减少联接操作,简化查询,但同时也带来数据冗余和更新维护上的问题
在这种设计中,数据不按规范化的方式进行存储,而是以扁平的结构存储在一个维度表中🤔。
其主要目的是减少复杂的表连接,提供更高效的查询性能,特别是在OLAP查询(联机分析处理)中。
- 非规范化扁平维度的特点🤨
- 数据冗余:为了提高查询性能,多个属性会被合并到一个表中,因此会导致数据冗余。例如,一个表中可能包含多个不同维度的属性,如产品、客户、地区等,而这些维度在规范化设计中通常会分布在不同的维度表中。
- 减少联接操作:通过将多个维度合并为一个扁平维度表,查询时不需要对多个维度表进行连接操作,这在查询过程中能够节省大量的时间和计算资源。
- 简化查询:查询时不需要复杂的联接,直接从一个表中提取所有相关信息,通常适用于需要频繁分析和聚合的场景。
- 存储空间:由于数据冗余和扁平化存储,非规范化扁平维度表通常会占用更多的存储空间。
- 非规范化与规范化的对比
-
规范化设计:规范化设计的目标是消除数据冗余,将数据分割成多个表,并通过主键/外键关系来连接。这样可以减少存储空间并避免数据冗余,但查询时需要对多个表进行联接,可能导致查询效率较低。
-
非规范化设计:非规范化设计通过将多个相关的属性和维度放在一个表中,避免了复杂的联接操作。这种方法通常会导致数据冗余,但查询速度较快,因为数据已经被“预处理”并且存储为一个扁平化的结构。
Demo:
规范化设计:
-
产品维度表(Product Dimension):
Product_ID Product_Name Category 1 手机 电子产品 2 衣服 服装 -
客户维度表(Customer Dimension):
Customer_ID Customer_Name Customer_Segment 101 张三 VIP 102 李四 普通 -
地区维度表(Region Dimension):
Region_ID Region_Name 1 北京 2 上海 -
销售事实表(Sales Fact):
Sales_ID Product_ID Customer_ID Region_ID Amount 1 1 101 1 1000 2 2 102 2 500
非规范化扁平维度设计:
- 销售维度表(Flattened Sales Dimension):
Sales_ID Product_ID Product_Name Category Customer_ID Customer_Name Customer_Segment Region_ID Region_Name Amount 1 1 手机 电子产品 101 张三 VIP 1 北京 1000 2 2 衣服 服装 102 李四 普通 2 上海 500
销售维度表中包含了所有维度的字段:产品名称、产品类别、客户姓名、客户细分、地区名称等。
非规范化扁平维度设计在查询时不需要对不同的维度表进行联接,直接通过一个扁平的表进行分析。
2.3.7 多层次维度
多层次维度(Hierarchical Dimension)是指的是在维度中存在层次结构,每个层次代表不同的聚合级别。
通过多层次维度,用户可以根据需要从较高层次的数据下钻(drill-down)到更详细的层次,或者从较低层次的数据上卷(drill-up)到更高层次的汇总数据。
Demo:
时间维度(Time Dimension)
时间_ID | 年 | 季度 | 月 | 周 | 日 |
---|---|---|---|---|---|
1 | 2024 | Q1 | 1 | 1 | 2024-01-01 |
2 | 2024 | Q1 | 1 | 2 | 2024-01-02 |
3 | 2024 | Q1 | 1 | 3 | 2024-01-03 |
4 | 2024 | Q1 | 2 | 4 | 2024-02-01 |
5 | 2024 | Q2 | 4 | 12 | 2024-04-01 |
6 | 2024 | Q2 | 5 | 13 | 2024-05-01 |
在这个表中,年、季度、月、周和日形成了多层次结构。可以按不同层级进行下钻或上卷:
- 按年:用户可以先看到汇总的年度数据(例如,2024年的总销售额)。
- 按季度:再按季度深入(例如,Q1的销售额)。
- 按月:进一步查看每个月的数据(例如,2024年1月的销售额)。
- 按日:可以查看具体某一天的数据(例如,2024年1月1日的销售额)。
地理维度(Geography Dimension)
地理_ID | 国家 | 省/市 | 城市 | 区域 |
---|---|---|---|---|
1 | 中国 | 北京市 | 北京市 | 朝阳区 |
2 | 中国 | 上海市 | 上海市 | 徐汇区 |
3 | 美国 | 加利福尼亚州 | 洛杉矶 | 市中心区 |
4 | 美国 | 纽约州 | 纽约市 | 曼哈顿区 |
层次结构包括国家、省/市、城市和区域。可以从“国家”开始查看汇总数据,逐步下钻到具体的城市或区域。
2.3.8 文档属性的标识与指示器
文档属性的标识与指示器是用于描述和管理文档的特性、状态和行为的关键元素。
标识符(ID)确保文档的唯一性,而指示器反映文档的状态、权限或任务要求。
Demo:
文档管理系统中,关于公司年度财务报告的文档。文档的属性可能包括:
- 文档ID:
Doc2024_FinancialReport
- 文档名称:
2024年财务报告
- 文档类型:
财务报告
- 创建日期:
2024-01-01
- 修改日期:
2024-03-01
- 版本号:
v1.1
- 作者:
yushifu
系统还可以有以下指示器来表示文档的状态:
- 审核指示器:
✔
表示文档已通过审核。 - 归档指示器:
未归档
,表示文档还没有归档。 - 权限指示器:
仅限财务部门
,表示只有财务部门人员可以访问此文档。
文档ID确保每个报告都是唯一的,审核指示器告诉用户文档是否已经审核通过,权限指示器则明确哪些用户可以访问这个文档。🤣🤣🤣
2.3.9 维度表中的空值属性
推荐采用描述性字符串替代空值,避免使用空值(NULL)的做法。
空值处理的不一致性
不同的数据库管理系统(DBMS)在处理空值时的行为可能不同,这会导致跨系统、跨平台的兼容性问题。特别是在进行分组、连接、聚合、排序等操作时,空值可能会被不同的数据库系统以不同的方式处理。
- 分组:在某些数据库中,空值可能会被视为一个单独的组,而在其他数据库中,空值可能会被忽略或与其他值合并。
- 聚合函数:某些聚合函数(如
COUNT
、SUM
等)在遇到空值时的行为不同。例如,某些数据库会将空值排除在外,而其他数据库则会将其计为零。 - 连接操作:在进行表连接时,空值可能导致不同的连接行为。使用空值时,联接条件的匹配可能不按预期工作,影响查询结果。
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):月份的名称,如
January
、February
等。 - 周数(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 | 日期 | 年 | 季度 | 月 | 月名称 | 周数 | 周几 | 日 | 工作日标识 | 是否节假日 |
---|---|---|---|---|---|---|---|---|---|---|
20240101 | 2024-01-01 | 2024 | 1 | 1 | January | 1 | 1 | 1 | 0 | 1 |
20240102 | 2024-01-02 | 2024 | 1 | 1 | January | 1 | 2 | 2 | 1 | 0 |
20240103 | 2024-01-03 | 2024 | 1 | 1 | January | 1 | 3 | 3 | 1 | 0 |
20240104 | 2024-01-04 | 2024 | 1 | 1 | January | 1 | 4 | 4 | 1 | 0 |
20240105 | 2024-01-05 | 2024 | 1 | 1 | January | 1 | 5 | 5 | 1 | 0 |
20240106 | 2024-01-06 | 2024 | 1 | 1 | January | 1 | 6 | 6 | 0 | 1 |
生成日历日期维度表通常有两种方式:
静态生成法
静态生成法适用于历史数据已经确定且维度的时间范围有限的情况。可以根据需要的日期范围(例如从2000年到2025年),手动或通过脚本生成日期维度表。该方式通常适合在小规模的业务中。
动态生成法
动态生成法适用于业务需求变化较快或维度表数据需要持续更新的情况。例如,使用ETL工具或SQL脚本动态生成,实时生成未来的日期维度,并支持自动更新。动态生成的日期维度表能够根据实际业务需求灵活调整。
2.3.11 扮演角色的维度
扮演角色的维度(Role-Playing Dimension)指的是同一维度表根据业务需求在不同的上下文中“扮演”不同角色的情况。这种设计模式主要用于处理同一维度在不同场景下的多次引用。
- 客户作为下单者:在订单事实表中,客户可能作为“下单者”角色存在。此时,客户ID会作为外键关联到客户维度表,以便获取下单者的详细信息。
- 客户作为收货人:在相同的订单事实表中,客户也可能作为“收货人”角色存在。此时,同样是客户维度,但由于角色不同,可能需要通过不同的外键(如
Customer_ID
和Receiver_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 |
---|---|---|---|
1001 | C001 | 500 | 1 |
1002 | C002 | 200 | 2 |
1003 | C003 | 150 | 3 |
通过 杂项维度ID
外键,可以查到该订单的状态、优先级、支付方式和订单类型,而不需要在事实表中重复存储这些字段。
何时使用杂项维度
- 多个低卡数属性:当一个事实表或维度表中有多个小属性,它们可能没有单独的业务含义,且数量有限。
- 避免冗余:当这些小属性是重复的且频繁出现时,使用杂项维度表可以避免在事实表中冗余存储它们。
- 简化数据模型:当这些小属性的独立性较弱且没有独立业务需求时,使用杂项维度表可以简化数据模型和减少表的数量。
2.3.13 雪花维度
雪花维度(Snowflake Dimension)是一种数据仓库设计模式,它是星型模式(Star Schema)的一种变体。
在雪花模型中,维度表被进一步规范化(Normalized),即将原本可以放在一个维度表中的多个字段分解成多个相关的子维度表。
相比星型模型中维度表的“扁平”结构,雪花模型的维度表具有更多的层次关系,形成类似雪花形状的结构,因此得名“雪花维度”。
- 规范化:雪花维度通过规范化的方式,将维度表中的字段分解成多个子表,减少了数据的冗余。例如,在产品维度表中,如果有产品类别和产品品牌字段,可能会将这两个字段分别抽象成独立的“产品类别”维度和“产品品牌”维度。
- 多层级关系:雪花维度的结构通常包含多个层次。例如,产品维度可能有“产品类别” → “产品品牌” → “产品名称”这样的层次结构,这样可以更灵活地进行数据管理。
- 复杂的查询:雪花模型的查询通常比星型模型更复杂,因为它需要多表连接来获取完整的维度信息。
Demo🤣🤣🤣:
星型模型中的产品维度
产品ID | 产品名称 | 品牌 | 类别 |
---|---|---|---|
P001 | 手机 | 苹果 | 电子产品 |
P002 | 洗衣机 | 海尔 | 家电 |
P003 | 电视机 | 索尼 | 家电 |
雪花模型中的产品维度
在雪花模型中,产品维度表被进一步规范化,拆分成多个子表。
- 产品维度表:
产品ID | 产品名称 | 品牌ID | 类别ID |
---|---|---|---|
P001 | 手机 | B001 | C001 |
P002 | 洗衣机 | B002 | C002 |
P003 | 电视机 | B003 | C002 |
- 品牌维度表:
品牌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 |
---|---|---|
1 | E001 | R001 |
1 | E002 | R002 |
2 | E003 | R001 |
- 产品维度:
产品ID | 产品名称 |
---|---|
P001 | 手机 |
P002 | 电视机 |
P003 | 洗衣机 |
- 供应商维度:
供应商ID | 供应商名称 |
---|---|
S001 | 苹果公司 |
S002 | 三星公司 |
S003 | 海尔公司 |
- 支架维度表:
支架维度ID | 产品ID | 供应商ID |
---|---|---|
1 | P001 | S001 |
1 | P001 | S002 |
2 | P002 | S003 |
支架维度的优点
-
简化多对多关系:支架维度可以帮助解决事实表和维度表之间的多对多关系,避免了将多个维度值重复存储在事实表中的冗余数据。
-
提高查询灵活性:支架维度可以灵活地关联多个维度,使得查询更具灵活性。通过支架维度表,可以在多个维度之间进行更复杂的分析。
支架维度的缺点
- 查询复杂性:支架维度的使用增加了查询的复杂性,因为查询时需要多表连接。如果查询涉及多个支架维度,可能需要做大量的联接操作。
- ETL过程复杂:在ETL过程中,需要将多个维度表中的数据组合到支架维度表中,这可能增加ETL过程的复杂性和计算成本。
整理不易,列位一键三连,谢谢支持~🤣🤣🤣
相关文章:
数据仓库工具箱—读书笔记02(Kimball维度建模技术概述03、维度表技术基础)
Kimball维度建模技术概述 记录一下读《数据仓库工具箱》时的思考,摘录一些书中关于维度建模比较重要的思想与大家分享🤣🤣🤣 第二章前言部分作者提到:技术的介绍应该通过涵盖各种行业的熟悉的用例展开(赞同…...
Linux中常用的Shell脚本(运维+常用)汇总
废话不多说,直接上干货! 一、运维脚本 (1)监控CPU和内存的使用情况 #!/bin/bashcpu_threshold80 mem_threshold80# 获取CPU和内存使用率 cpu_usage$(top -bn1 | grep "Cpu(s)" | sed "s/.*, *\([0-9.]*\)%* id.…...
Java 方法注释:规范、实用和高质量的写法
目录 为什么要注释方法? 方法注释的基本要求 Javadoc 注释格式 示例:一个计算圆面积的方法 代码示例 注释分析 如何写出高质量的 Java 方法注释? 1. 关注可读性 2. 使用 Javadoc 格式 3. 描述异常 4. 适当的解释复杂的算法 5. 避…...
解决JIRA、Confluence用户自动注销、反复登录的问题
一、问题描述:当工作从从confluence里面打开jira的时候,在回到confluence时候,就自动退出了,需要账号密码登录重复登录,使人十分厌恶。 二、原因分析: 访问 JIRA、Confluence 或任何其他具有相同域或 IP 上…...
Python9-作业2
记录python学习,直到学会基本的爬虫,使用python搭建接口自动化测试就算学会了,在进阶webui自动化,app自动化 python基础8-灵活运用顺序、选择、循环结构 作业2九九乘法表三种方式打印九九乘法表使用两个嵌套循环使用列表推导式和…...
基于c语言的union、字符串、格式化输入输出
结构体之共用体union 共用体也叫联合体,其关键词为union 与结构体不同的是,共用体所开辟的存储空间仅仅为其中最长类型变量的存储空间而不是全部变量的存储空间,由于同一内存单元在同一时间内只能存放其中一种的数据类型,因此在每…...
SpringCloudAlibaba实战入门之路由网关Gateway初体验(十)
Spring Cloud 原先整合 Zuul 作为网关组件,Zuul 由 Netflix 公司提供的,现在已经不维护了。后面 Netflix 公司又出来了一个 Zuul2.0 网关,但由于一直没有发布稳定版本,所以 Spring Cloud 等不及了就自己推出一个网关,已…...
活着就好20241227
亲爱的朋友们,大家早上好!🌞 今天是27号,星期五,2024年12月的第二十七天,同时也是第51周的第五天,农历甲辰[龙]年十一月初二十三日。在这晨光渐浓的美好时刻,愿那温暖而明媚的阳光洒…...
robotframework中的测试套件
一. 简介 本文简单来了解一下,robotframework中的测试套件。 二. robotframework中测试套件 1. 什么是测试套件? 测试套件(Test Suite) 是一组相关测试用例的集合。每个测试套件通常代表一个特定的功能模块、系统组件或业务流程…...
Echarts连接数据库,实时绘制图表详解
文章目录 Echarts连接数据库,实时绘制图表详解一、引言二、步骤一:环境准备与数据库连接1、环境搭建2、数据库连接 三、步骤二:数据获取与处理1、查询数据库2、数据处理 四、步骤三:ECharts图表配置与渲染1、配置ECharts选项2、动…...
【QED】爱丽丝与混沌的无尽海
文章目录 题目题目描述输入输出格式数据范围测试样例 思路代码复杂度分析时间复杂度空间复杂度 题目 题目链接🔗 题目描述 如图所示,爱丽丝在一个3x3的迷宫之中,每个方格中标有 1 − 9 1-9 1−9各不相同的数字,爱丽丝可以从一格…...
CHM助手 >> 如何安装CHM助手
1 如何安装CHM助手 下载CHM助手.ezip,下载地址打开EverEdit,选择主菜单“扩展 -> 扩展管理 -> 从本地文件安装扩展”,在弹出的文件浏览窗口中选择插件安装包,如下图所示: 🕮说明: …...
硬件设计:LVDS电平标准
什么是LVDS? LVDS(Low-Voltage Differential Signaling)是一种高速、低功耗的差分信号传输标准。它通过一对差分信号线(通常是两根互补信号线)来传输数据,广泛应用于高速数字通信领域。 LVDS 的核心特点 低…...
宝塔-firefox(Docker应用)-构建自己的Web浏览器
安装基础软件 宝塔中安装firefox(Docker应用) 。宝塔中需要先安装docker及docker-composefirefox配置安装 点击firefox应用,选择【安装配置】点击右边绿色按钮,进行安装,这一步等待docker-compose根据你的配置初始化docker应用 等待安装 …...
微信小程序-基于Vant Weapp UI 组件库的Area 省市区选择
Area 省市区选择,省市区选择组件通常与 弹出层 组件配合使用。 areaList 格式 areaList 为对象结构,包含 province_list、city_list、county_list 三个 key。 每项以地区码作为 key,省市区名字作为 value。地区码为 6 位数字,前两…...
宏转录组+HiFi宏基因组:揭示厌氧消化中的碳流和能量转换
厌氧消化是一种重要的工程生物技术,对有机废物的资源回收和可再生能源的生产起着关键作用。然而,由于对未培养的厌氧菌及其适应环境变化的能力了解有限,这限制了该技术的优化和生物气生产的可持续性。今天小编带大家看一篇发表在《Microbiome…...
【VSCode】工作区及设置
【VSCode】工作区及设置 VSCode介绍工作区设置 VSCode介绍 Visual Studio Code(简称VSCode)是一个由微软开发的免费、开源的代码编辑器,以下是VSCode的一些功能及特性: 编辑器核心: 多文档界面:VSCode允许…...
瀚高数据库
文章目录 瀚高数据库安装瀚高数据库快速入门遇到的问题总结 瀚高数据库 瀚高数据库(HanGaoDB)是一款在分布式存储、高并发处理和高可用性方面表现优异的数据库,特别适用于大数据、高吞吐量、高并发的应用场景。它结合了传统 SQL 数据库和分布…...
xterm遇到的问题及解决方案
xterm遇到的问题及解决方案 /r插入终端导致的之后插入的数据覆盖了改行头部的数据 问题说明 如图所示,当在一行输入的候,输入的l插入到了改行的头部。 查看ws返回数据 可见ws返回的信息存在\r字符,在xterm.js中\r是回车字符的意思&…...
嵌入式单片机温湿度模块控制与实现
温湿度模块的使用 温湿度模块的特点 温湿度模块的原理通信的开始(打电话) 通信的过程(交流中)...
表达式语句、复合语句和空语句
欢迎拜访:雾里看山-CSDN博客 本篇主题:表达式语句、复合语句和空语句 发布时间:2024.12.26 隶属专栏:C语言 目录 1. 表达式语句定义作用常见类型赋值语句函数调用语句 2. 复合语句定义作用变量作用域 3. 空语句定义作用 1. 表达式…...
Dilateformer实战:使用Dilateformer实现图像分类任务(二)
文章目录 训练部分导入项目使用的库设置随机因子设置全局参数图像预处理与增强读取数据设置Loss设置模型设置优化器和学习率调整策略设置混合精度,DP多卡,EMA定义训练和验证函数训练函数验证函数调用训练和验证方法 运行以及结果查看测试完整的代码 在上…...
Kubernetes 镜像拉取策略全解析:如何根据需求选择最佳配置?
在Kubernetes集群里,拉取容器镜像是一个非常关键的步骤。这些镜像包含了应用程序及其所有需要的依赖项,Kubernetes通过拉取这些镜像来启动Pod中的容器。为了提升集群的稳定性、速度和安全性,Kubernetes提供了几种不同的镜像拉取策略。这篇文章…...
上海AI中心记录
1、js事件循环 调用栈(Call Stack): JavaScript 是单线程的,所有的代码执行都是在调用栈中进行的。当函数被调用时,进入栈中;执行完毕后,从栈中弹出。 任务队列(Task Queueÿ…...
oscp学习之路,Kioptix Level2靶场通关教程
oscp学习之路,Kioptix Level2靶场通关教程 靶场下载:Kioptrix Level 2.zip 链接: https://pan.baidu.com/s/1gxVRhrzLW1oI_MhcfWPn0w?pwd1111 提取码: 1111 搭建好靶场之后输入ip a看一下攻击机的IP。 确定好本机IP后,使用nmap扫描网段&…...
基于SpringBoot的蜗牛兼职网的设计与实现
一、项目背景 随着社会的快速发展,计算机的影响是全面且深入的。人们生活水平的不断提高,日常生活中人们对蜗牛兼职网方面的要求也在不断提高,需要兼职工作的人数更是不断增加,使得蜗牛兼职网的开发成为必需而且紧迫的事情。蜗牛…...
C++软件设计模式之装饰器模式
装饰器模式(Decorator Pattern)是C软件设计模式中的一种结构型设计模式,主要用于解决在不改变现有对象结构的情况下动态地给对象添加新功能的问题。通过使用装饰器模式,可以在运行时为对象添加新的行为,而不需要修改其…...
Spring Boot项目接收前端参数的11种方式
大家好,我是袁庭新。在前后端项目交互中,前端传递的数据可以通过HTTP请求发送到后端, 后端在Spring Boot中如何接收各种复杂的前端数据呢?这篇文章总结了11种在Spring Boot中接收前端数据的方式。 1 搭建项目 1.通过Spring Init…...
通过GRE协议组建VPN网络
GRE(Generic Routing Encapsulation,通用路由封装协议)协议是一种简单而有效的封装协议,它在网络中的广泛应用,比如在构建VPN网络。 GRE是一种封装协议,它允许网络层协议(如IP)的…...
you-get使用cookies下载B站视频
B站视频更换BV号以后,使用you-get不能下载了。 首先更新你的you-get pip install --upgrade you-get 更新完成后再次使用you-get -u 命令会显示使用cookies才能下载更多清晰度的视频 使用Edge浏览器,添加插件 Cookie-Editor 点击上图的导出按钮&am…...
使用Excel制作通达信自定义“序列数据“
序列数据的视频教程演示 Excel制作通达信自定义序列数据 1.序列数据的制作方法:删掉没有用的数据(行与列)和股代码格式处理,是和外部数据的制作方法是相同,自己上面看历史博文。只需要判断一下,股代码跟随的…...
基于 Nginx 的网站服务器与 LNMP 平台搭建指南
一,Nginx概述 (一)Nginx的作用 Nginx在网络服务器架构中扮演着多面的角色。其初始设定专注于静态网络数据的处理,能高效地为用户提供诸如HTML,CSS,JavaScript等静态资源。当面对动态数据时,借助php - fpm模块,Nginx能够解析php源代码,实现动态页面的生成与展示。在处理…...
OpenCV计算机视觉 03 椒盐噪声的添加与常见的平滑处理方式(均值、方框、高斯、中值)
上一篇文章:OpenCV计算机视觉 02 图片修改 图像运算 边缘填充 阈值处理 添加椒盐噪声 def add_peppersalt_noise(image, n10000):result image.copy()h, w image.shape[:2] # 获取图片的高和宽for i in range(n): # 生成n个椒盐噪声x np.random.randint(…...
WPF自定义窗口 输入验证不生效
WPF自定义窗口 输入验证不生效 WPF ValidationRule 不生效 WPF ValidationRule 不生效 解决方案:在WindowStyle的Template中添加AdornerDecorator标签。 <Style x:Key"WindowStyle1" TargetType"{x:Type Window}"><Setter Property&…...
【MySQL】 SQL优化讲解
一、优化前的思考 在定位到慢查询后,面试官常问如何优化或分析慢查询的SQL语句。若存在聚合查询、多表查询,可尝试优化SQL语句结构,如多表查询可新增临时表;若表数据量过大,可添加索引,但添加索引后仍慢则…...
05.HTTPS的实现原理-HTTPS的握手流程(TLS1.2)
05.HTTPS的实现原理-HTTPS的握手流程(TLS1.2) 简介1. TLS握手过程概述2. TLS握手过程细化3. 主密钥(对称密钥)生成过程4. 密码规范变更 简介 主要讲述了混合加密流程完成后,客户端和服务器如何共同获得相同的对称密钥…...
Java获取自身被调用点
1. 场景 打印日志的时候,需要获取是在哪个地方被调用了,把调用点的信息一并打印出来。 2. 获取自身被调用点的方法 可以通过获取线程的调用栈,遍历后找到调用点。 3. 代码实现 import java.text.SimpleDateFormat; import java.util.Dat…...
有序之美:C++ Set的哲学与诗意
文章目录 前言一.C set 的概念1.1 set 的定义1.2 set 的特点二. set 的构造方法2.1 常见构造函数2.1.1 示例:不同构造方法 2.2 相关文档 三.set 的常用操作3.1 插入操作详解3.1.1 使用 insert() 插入元素3.1.2 使用 emplace() 插入元素3.1.3 插入区间元素 3.2 查找操…...
22. 仿LISP运算
题目描述 LISP语言唯一的语法就是括号要配对 形如(OP P1 P2 ...),括号内元素由单个空格分割。其中第一个元素OP为操作符,后续元素均为其参数,参数个数取决于操作符类型。注意:参数P1,P2也有可能是另外一个嵌套的(OP P1 P2...),当前…...
大模型应用技术系列(三): 深入理解大模型应用中的Cache:GPTCache
前言 无论在什么技术栈中,缓存都是比较重要的一部分。在大模型技术栈中,缓存存在于技术栈中的不同层次。本文将主要聚焦于技术栈中应用层和底层基座之间中间件层的缓存(个人定位),以开源项目GPTCache(LLM的语义缓存)为例,深入讲解这部分缓存的结构和关键实现。 完整技术…...
MATLAB语言的网络编程
标题:MATLAB中的网络编程:深入探索与实践 一、引言 在现代科学和工程领域中,网络编程已经成为了数据处理、信号分析、模型构建等众多任务中不可或缺的一环。MATLAB作为一款强大的数学计算软件,不仅提供了丰富的数值计算功能&…...
边缘计算收益稳定
要使自己的PCDN(Personal Content Delivery Network,个人内容分发网络)收益更稳定,可以从以下几个方面进行努力: 一、选择合适的PCDN平台 平台稳定性:选择技术成熟、稳定性高的PCDN平台,确保内…...
计算机网络 (7)物理层下面的传输媒体
一、定义与位置 物理层是计算机网络体系结构的最低层,它位于传输媒体(传输介质)之上,主要作用是为数据链路层提供一个原始比特流的物理连接。这里的“比特流”是指数据以一个个0或1的二进制代码形式表示。物理层并不是特指某种传输…...
【GoPL】1.2 命令行参数
1.2 命令行参数 24-12-26 大部分程序处理输入,然后产生一些输出,这大概有点像计算的定义 但是程序怎么操作输入的数据?(用参数来操作)输入可能来自文件、网络连接、用户的键盘输入、命令行参数(不同的编程范式) os包提供函数和其他值来处理…...
高精度问题
目录 算法实现基础 高精度加法AB 测试链接 源代码 代码重点 高精度减法A-B 测试链接 源代码 代码重点 高精度乘法A*b和A*B 测试链接 源代码 代码重点 高精度除法A/b和A/B 测试链接 源代码 代码重点 高精度求和差积商余 算法实现基础 本算法调用STL…...
【无线通信】蜂窝系统——干扰与系统容量
干扰是蜂窝无线系统性能的主要限制因素。干扰来源包括同一小区中的其他移动终端、邻近小区正在进行的通话、其他基站在同一频段内的工作信号,或者任何不属于蜂窝系统的设备偶然向蜂窝频段泄漏信号。语音信道中的干扰会导致串音,使得用户在通话时听到背景…...
深入探索仓颉编程语言:函数与结构类型的终极指南
引言 仓颉编程语言是一种现代化、语法精炼的编程语言,其设计目标是提供高度的灵活性与高性能的执行效率。函数与结构类型是仓颉语言的两大基础模块,也是开发者需要掌握的核心。本文将详细讲解仓颉语言中函数和结构类型的特性,辅以代码实例和…...
010-spring-后置处理器(重要)
org.mybatis.spring.mapper.MapperScannerConfigurer...
SQL实现新年倒计时功能
马上就到 2025 年了,给大家分享一个使用 SQL 实现的新年倒计时功能。 以下是 PostgreSQL 语法: DO $$ DECLAREdiff INTERVAL; BEGINRAISE NOTICE 2025新年倒计时开始:;LOOP-- 计算当前时间距离2025年的时间间隔diff age(timestamp 2025-01…...
list模拟实现
目录 节点结构 构造函数 insert erase push_back push_front pop_front pop_back 拷贝构造 析构函数 赋值重载 正向迭代器实现 clear 反向迭代器实现 测试list 附完整代码 参照数据结构篇: 带头双向循环链表 节点结构 namespace dck {template <class T&g…...