维度建模与数据仓库设计:理论与实践案例

文章目录

定义

维度建模是一种用于数据仓库设计的技术,它的目标是使数据库结构更加直观,易于理解和使用,特别是对于那些进行数据查询和报告的非技术用户。它主要包括两个核心概念:事实表和维度表。

  • 事实表:这是数据仓库的核心,用于存储度量或业务过程的量化数据。例如,一个零售业务的事实表可能包含每笔销售的总额、数量和时间等信息。
  • 维度表:这些表包含描述性信息,用于"维度化"事实表中的量化数据。它们帮助用户理解事实表中的数据。继续上述例子,维度表可能包括客户信息、产品信息、商店信息等,每个维度表都与事实表通过外键关联。

案例:零售销售数据仓库

假设我们要为一家零售商建立数据仓库。在这个例子中,我们可能会有:

事实表:销售事实

  1. 销售ID
  2. 产品ID (外键,连接到产品维度表)
  3. 顾客ID (外键,连接到顾客维度表)
  4. 商店ID (外键,连接到商店维度表)
  5. 销售日期 (外键,连接到时间维度表)
  6. 销售金额
  7. 销售数量

维度表:产品维度

  1. 产品ID
  2. 产品名称
  3. 产品类别
  4. 产品价格

维度表:顾客维度

  1. 顾客ID
  2. 顾客姓名
  3. 顾客地址
  4. 顾客类别

维度表:商店维度

  1. 商店ID
  2. 商店名称
  3. 商店位置
  4. 商店类型

维度表:时间维度

  1. 日期
  2. 季度

在这个例子中,事实表提供了可度量的业务过程(例如,每笔销售的金额和数量),而维度表则提供了理解这些度量所需的上下文(例如,销售发生在哪个商店,由哪个顾客进行,涉及哪个产品)。通过这种方式,维度建模帮助用户以直观的方式理解和分析复杂的业务数据。

实践

创建维度表

产品维度表

复制代码
CREATE TABLE test.DimProduct (
    ProductID INT PRIMARY KEY,
    ProductName VARCHAR(255),
    Category VARCHAR(255),
    Price DECIMAL(10, 2)
);

顾客维度表

复制代码
CREATE TABLE test.DimCustomer (
    CustomerID INT PRIMARY KEY,
    CustomerName VARCHAR(255),
    Address VARCHAR(255),
    CustomerType VARCHAR(255)
);

商店维度表

复制代码
CREATE TABLE test.DimStore (
    StoreID INT PRIMARY KEY,
    StoreName VARCHAR(255),
    Location VARCHAR(255),
    StoreType VARCHAR(255)
);

时间维度表

复制代码
CREATE TABLE test.DimTime (
    DateKey DATE PRIMARY KEY,
    Day INT,
    Month INT,
    Quarter INT,
    Year INT
);

创建事实表

销售事实表

复制代码
CREATE TABLE test.FactSales (
    SaleID INT PRIMARY KEY,
    ProductID INT,
    CustomerID INT,
    StoreID INT,
    DateKey DATE,
    Amount DECIMAL(10, 2),
    Quantity INT,
    FOREIGN KEY (ProductID) REFERENCES DimProduct(ProductID),
    FOREIGN KEY (CustomerID) REFERENCES DimCustomer(CustomerID),
    FOREIGN KEY (StoreID) REFERENCES DimStore(StoreID),
    FOREIGN KEY (DateKey) REFERENCES DimTime(DateKey)
);

插入维度表数据

向产品维度表插入数据

复制代码
INSERT INTO test.DimProduct (ProductID, ProductName, Category, Price) VALUES
(1, '苹果手机', '电子产品', 5000.00),
(2, '三星电视', '电子产品', 3000.00),
(3, '联想笔记本', '电子产品', 4500.00);

select * from test.DimProduct;

如下:

向顾客维度表插入数据

复制代码
INSERT INTO test.DimCustomer (CustomerID, CustomerName, Address, CustomerType) VALUES
(1, '张三', '北京市', '个人'),
(2, '李四', '上海市', '企业'),
(3, '王五', '广州市', '个人');


select * from test.DimCustomer;

如下:

向商店维度表插入数据

复制代码
INSERT INTO test.DimStore (StoreID, StoreName, Location, StoreType) VALUES
(1, '京东商城', '在线', '电商'),
(2, '苏宁易购', '在线', '电商'),
(3, '国美电器', '线下', '实体店');


select * from test.DimStore;

如下:

向时间维度表插入数据

复制代码
INSERT INTO test.DimTime (DateKey, Day, Month, Quarter, Year) VALUES
('2023-01-01', 1, 1, 1, 2023),
('2023-02-01', 1, 2, 1, 2023),
('2023-03-01', 1, 3, 1, 2023);



select * from test.DimTime;

如下:

插入事实表数据

向销售事实表插入数据

复制代码
INSERT INTO test.FactSales (SaleID, ProductID, CustomerID, StoreID, DateKey, Amount, Quantity) VALUES
(1, 1, 1, 1, '2023-01-01', 5000.00, 1),
(2, 2, 2, 2, '2023-02-01', 6000.00, 2),
(3, 3, 3, 3, '2023-03-01', 4500.00, 1);


select * from test.FactSales ;

如下:

增改查

向产品维度表添加新产品

复制代码
INSERT INTO test.DimProduct (ProductID, ProductName, Category, Price) VALUES
(4, '惠普打印机', '电子产品', 800.00);

从顾客维度表删除一位顾客

假设顾客ID为3的顾客不再是我们的客户,我们可以从顾客维度表中删除这条记录。

更新商店维度表中的商店信息

如果商店ID为3的商店更改了其名称,我们可以更新这条信息。

复制代码
UPDATE test.DimStore SET StoreName = '新国美电器' WHERE StoreID = 3;

查询2023年第一季度的总销售额

这个查询将涉及联接事实表和时间维度表,以计算特定时间段内的总销售额。

复制代码
SELECT
    SUM(test.FactSales.Amount) AS TotalSales
FROM
    test.FactSales
JOIN
    test.DimTime ON test.FactSales.DateKey = test.DimTime.DateKey
WHERE
    test.DimTime.Year = 2023 AND test.DimTime.Quarter = 1;

如下:

  • FROM FactSales: 这是查询的主表,我们从这个事实表开始。
  • JOIN DimTime ON FactSales.DateKey = DimTime.DateKey: 这里我们通过JOIN操作将FactSales表和DimTime表联接起来。联接的条件是FactSales.DateKey
  • DimTime.DateKey,意味着我们只关心那些在两个表中都有匹配日期的行。
  • WHERE DimTime.Year = 2023 AND DimTime.Quarter = 1: 这个条件进一步过滤结果,只包括2023年第一季度的数据。
  • SELECT SUM(FactSales.Amount) AS TotalSales: 最后,我们对联接后的数据进行汇总,计算总销售额。

查询特定顾客的购买历史

这个查询显示了顾客ID为1的顾客在不同时间购买的产品。

复制代码
SELECT
    DimCustomer.CustomerName,
    DimProduct.ProductName,
    FactSales.DateKey,
    FactSales.Amount
FROM
    test.FactSales
JOIN
    test.DimCustomer ON FactSales.CustomerID = DimCustomer.CustomerID
JOIN
    test.DimProduct ON FactSales.ProductID = DimProduct.ProductID
WHERE
    DimCustomer.CustomerID = 1;

如下:

在这个查询中,我们首先联接FactSales和DimCustomer,然后再将结果与DimProduct联接。最终的结果集包含了顾客姓名、产品名称、购买日期和购买金额,这些信息来自三个不同的表。

相关推荐
存在morning3 小时前
【GO语言开发实践】二 GO 并发快速上手
大数据·开发语言·golang
nassi_3 小时前
对AI工程问题的一些思考
大数据·人工智能·hadoop
沪漂阿龙6 小时前
面试题详解:检索链路设计全攻略——RAG 检索架构、查询理解、多路召回、混合检索、Rerank、上下文构造与评估闭环
大数据·人工智能·架构
金融小师妹6 小时前
基于AI通胀预期模型与美元流动性监测框架的黄金6周新低行分析:美元五连涨周期下贵金属定价机制重构研究
大数据·人工智能·重构·逻辑回归·线性回归
智慧医养结合软件开源7 小时前
智慧养老系统医生管理模块:专业赋能,筑牢老人诊疗安全防线
大数据·人工智能·安全·生活
身如柳絮随风扬8 小时前
Git 核心操作:rebase 与 merge 的区别,以及分支管理最佳实践
大数据·git
多年小白8 小时前
兆易创新分析
大数据·人工智能·ai·金融·区块链
财迅通Ai9 小时前
海立股份:公司旗下海立特冷“人体降温系统”入选市级先进技术推荐目录
大数据·人工智能·海立股份
captain_AIouo10 小时前
Captain AI以视频运营破局!助Ozon商家抢占流量红利
大数据·人工智能·经验分享·aigc·音视频
TDengine (老段)10 小时前
TDengine 一条 SQL 从客户端到执行完成的全链路
大数据·数据库·sql·物联网·时序数据库·tdengine·涛思数据