Amazon Redshift 中的维度建模 | 亚马逊网络服务

Amazon Redshift 中的维度建模 | 亚马逊网络服务

源节点: 2778508

亚马逊Redshift 是一个完全托管的 PB 级云数据仓库,数以万计的客户每天使用它处理 EB 级数据,以支持他们的分析工作负载。 您可以使用维度模型构建数据、衡量业务流程并快速获得有价值的见解。 Amazon Redshift 提供内置功能来加速维度模型的建模、编排和报告过程。

在这篇文章中,我们讨论如何实现维度模型,特别是 金博尔方法论。 我们讨论在 Amazon Redshift 中实施维度和事实。 我们展示了如何执行提取、转换和加载 (ELT),这是一个集成过程,重点是将原始数据从数据湖获取到暂存层以执行建模。 总的来说,这篇文章将使您清楚地了解如何在 Amazon Redshift 中使用维度建模。

解决方案概述

下图说明了解决方案体系结构。

在以下各节中,我们首先讨论并演示维度模型的关键方面。 之后,我们使用 Amazon Redshift 创建一个数据集市,其中包含维度数据模型(包括维度和事实表)。 数据使用以下方式加载和暂存 COPY 命令,使用以下命令加载维度中的数据 合并 陈述和事实将被加入到从中得出见解的维度中。 我们使用以下方法安排维度和事实的加载 Amazon Redshift 查询编辑器 V2。 最后,我们使用 亚马逊QuickSight 以 QuickSight 仪表板的形式深入了解建模数据。

对于此解决方案,我们使用 Amazon Redshift 提供的示例数据集(标准化)进行活动门票销售。 在这篇文章中,为了简单和演示目的,我们缩小了数据集的范围。 下表显示了门票销售和场馆的数据示例。

Kimball 维度建模方法,设计维度模型有四个关键步骤:

  1. 确定业务流程。
  2. 声明数据的粒度。
  3. 确定并实施维度。
  4. 确定并落实事实。

此外,出于演示目的,我们添加了第五步,即报告和分析业务事件。

先决条件

对于本演练,您应该具有以下先决条件:

识别业务流程

简而言之,识别业务流程就是识别在组织内生成数据的可衡量事件。 通常,公司拥有某种可操作的源系统,可以以原始格式生成数据。 这是识别业务流程的各种来源的良好起点。

然后将业务流程持久化为 数据集市 以维度和事实的形式。 查看前面提到的示例数据集,我们可以清楚地看到业务流程是针对给定事件的销售。

一个常见的错误是使用公司的部门作为业务流程。 数据(业务流程)需要跨各个部门进行整合,在这种情况下,营销可以访问销售数据。 识别正确的业务流程至关重要 - 这一步出错可能会影响整个数据集市(可能会导致粒度重复以及最终报告中的指标不正确)。

声明数据的粒度

声明粒度是唯一标识数据源中的记录的行为。 事实表中使用粒度来准确测量数据并使您能够进一步汇总。 在我们的示例中,这可能是销售业务流程中的行项目。

在我们的用例中,可以通过查看销售发生时的交易时间来唯一标识销售; 这将是最原子级别的。

确定并实施维度

您的维度表描述了您的事实表及其属性。 在识别业务流程的描述性上下文时,您可以将文本存储在单独的表中,同时牢记事实表的粒度。 将维度表连接到事实表时,应该只有一行与事实表关联。 在我们的示例中,我们使用下表将其分成维度表; 这些字段描述了我们将测量的事实。

在设计维度模型(架构)的结构时,您可以创建一个 明星 or 雪花 架构。 结构应与业务流程紧密结合; 因此,星型模式最适合我们的示例。 下图显示了我们的实体关系图(ERD)。

在以下部分中,我们将详细介绍实现维度的步骤。

暂存源数据

在创建和加载维度表之前,我们需要源数据。 因此,我们将源数据暂存到暂存表或临时表中。 这通常被称为 暂存层,这是源数据的原始副本。 为了在 Amazon Redshift 中执行此操作,我们使用 复制命令 从位于 amazon-redshift 的 Dimension-modeling-in-amazon-redshift 公共 S3 存储桶加载数据 us-east-1 地区。 请注意,COPY 命令使用 AWS身份和访问管理 (IAM) 角色 访问亚马逊S3。 角色必须是 与集群关联。 完成以下步骤来暂存源数据:

  1. 创建 venue 源表:
CREATE TABLE public.venue ( venueid bigint, venuename character varying(100), venuecity character varying(30), venuestate character(2), venueseats bigint
) DISTSTYLE AUTO SORTKEY (venueid);

  1. 加载场地数据:
COPY public.venue
FROM 's3://redshift-blogs/dimensional-modeling-in-amazon-redshift/venue.csv'
IAM_ROLE '<Your IAM role arn>'
DELIMITER ','
REGION 'us-east-1'
IGNOREHEADER 1

  1. 创建 sales 源表:
CREATE TABLE public.sales (
    salesid integer,
    venueid character varying(256),
    saletime timestamp without time zone,
    qtysold BIGINT,
    commission numeric(18,2),
    pricepaid numeric(18,2)
) DISTSTYLE AUTO;

  1. 加载销售源数据:
COPY public.sales
FROM 's3://redshift-blogs/dimensional-modeling-in-amazon-redshift/sales.csv'
IAM_ROLE '<Your IAM role arn>'
DELIMITER ','
REGION 'us-east-1'
IGNOREHEADER 1

  1. 创建 calendar 表:
CREATE TABLE public.DimCalendar(
    dateid smallint,
        caldate date,
        day varchar(20),
        week smallint,
        month varchar(20),
        qtr varchar(20),
        year smallint,
        holiday boolean
) DISTSTYLE AUTO
SORTKEY
    (dateid);

  1. 加载日历数据:
COPY public.DimCalendar
FROM 's3://redshift-blogs/dimensional-modeling-in-amazon-redshift/date.csv'
IAM_ROLE '<Your IAM role arn>'
DELIMITER ',' 
REGION 'us-east-1'
IGNOREHEADER 1

创建尺寸表

设计维度表可以取决于您的业务需求,例如,您是否需要跟踪数据随时间的变化? 有 七种不同的维度类型。 对于我们的示例,我们使用 类型1 因为我们不需要跟踪历史变化。 有关类型 2 的更多信息,请参阅 简化数据加载到 Amazon Redshift 中类型 2 缓慢变化的维度。 维度表将使用主键、代理键和一些添加的字段来非规范化,以指示对表的更改。 请看下面的代码:

create schema SalesMart;

CREATE TABLE SalesMart.DimVenue( 
    "VenueSkey" int IDENTITY(1,1) primary key
    ,"VenueId" VARCHAR NOT NULL
    ,"VenueName" VARCHAR NULL
    ,"VenueCity" VARCHAR NULL
    ,"VenueState" VARCHAR NULL
    ,"VenueSeats" INT NULL
    ,"InsertedDate" DATETIME NOT NULL
    ,"UpdatedDate" DATETIME NOT NULL
) 
diststyle AUTO;

关于创建维度表的一些注意事项:

  • 字段名称转换为商业友好名称
  • 我们的主键是 VenueID,我们用它来唯一标识销售发生的地点
  • 将添加另外两行,指示何时插入和更新记录(以跟踪更改)
  • 我们正在使用一个 AUTO分配方式 赋予 Amazon Redshift 选择和调整分发方式的责任

维度建模中要考虑的另一个重要因素是使用 代理键。 代理键是在维度建模中使用的人工键,用于唯一标识维度表中的每条记录。 它们通常作为连续整数生成,并且在业务领域中没有任何意义。 它们具有多种优点,例如确保唯一性和提高连接性能,因为它们通常比自然键小,并且作为代理键,它们不会随着时间的推移而改变。 这使我们能够保持一致并更轻松地连接事实和维度。

在 Amazon Redshift 中,代理键通常使用 IDENTITY 关键字创建。 例如,前面的 CREATE 语句创建一个维度表,其中包含 VenueSkey 代理键。 这 VenueSkey 当新行添加到表中时,列会自动填充唯一值。 然后可以使用该列将场地表连接到 FactSaleTransactions 表。

设计代理键的一些技巧:

  • 使用小型、固定宽度的数据类型作为代理键。 这将提高性能并减少存储空间。
  • 使用 IDENTITY 关键字,或使用顺序值或 GUID 值生成代理键。 这将确保代理键是唯一的并且无法更改。

使用 MERGE 加载昏暗表

有多种方法可以加载暗淡表。 需要考虑某些因素,例如性能、数据量,或许还有 SLA 加载时间。 随着 合并 语句,我们执行 upsert 而无需指定多个插入和更新命令。 您可以设置 合并 声明中 存储过程 填充数据。 然后,您可以安排存储过程通过查询编辑器以编程方式运行,我们将在本文后面进行演示。 以下代码创建一个名为的存储过程 SalesMart.DimVenueLoad:

CREATE OR REPLACE PROCEDURE SalesMart.DimVenueLoad()
AS $$
BEGIN
MERGE INTO SalesMart.DimVenue USING public.venue as MergeSource
ON SalesMart.DimVenue.VenueId = MergeSource.VenueId
WHEN MATCHED
THEN
UPDATE
SET VenueName = ISNULL(MergeSource.VenueName, 'Unknown')
, VenueCity = ISNULL(MergeSource.VenueCity, 'Unknown')
, VenueState = ISNULL(MergeSource.VenueState, 'Unknown')
, VenueSeats = ISNULL(MergeSource.VenueSeats, -1)
, UpdatedDate = GETDATE()
WHEN NOT MATCHED
THEN
INSERT (
VenueId
, VenueName
, VenueCity
, VenueState
, VenueSeats
, UpdatedDate
, InsertedDate
)
VALUES (
ISNULL(MergeSource.VenueId, -1)
, ISNULL(MergeSource.VenueName, 'Unknown')
, ISNULL(MergeSource.VenueCity, 'Unknown')
, ISNULL(MergeSource.VenueState, 'Unknown')
, ISNULL(MergeSource.VenueSeats, -1)
, ISNULL(GETDATE() , '1900-01-01')
, ISNULL(GETDATE() , '1900-01-01')
);
END;
$$
LANGUAGE plpgsql;

关于尺寸加载的一些注意事项:

  • 当第一次插入记录时,将填充插入日期和更新日期。 当任何值发生更改时,数据都会更新,更新日期反映更改时的日期。 插入的日期保留。
  • 由于数据将由业务用户使用,因此我们需要将 NULL 值(如果有)替换为更适合业务的值。

确定并落实事实

现在我们已经声明我们的grain是在特定时间发生的销售事件,我们的事实表将存储我们业务流程的数字事实。

我们已经确定了以下要衡量的数字事实:

  • 每次售出的门票数量
  • 销售佣金

落实事实

这里有 三种类型的事实表 (交易事实表、周期快照事实表、累积快照事实表)。 每个都提供不同的业务流程视图。 对于我们的示例,我们使用交易事实表。 完成以下步骤:

  1. 创建事实表
CREATE TABLE SalesMart.FactSaleTransactions( 
    CalendarDate date NOT NULL
    ,SaleTransactionTime DATETIME NOT NULL
    ,VenueSkey INT NOT NULL
    ,QuantitySold BIGINT NOT NULL
    ,SaleComission NUMERIC NOT NULL
    ,InsertedDate DATETIME DEFAULT GETDATE()
) diststyle AUTO;

添加具有默认值的插入日期,指示是否以及何时加载记录。 您可以在重新加载事实表时使用它来删除已加载的数据以避免重复。

加载事实表由连接关联维度的简单插入语句组成。 我们加入来自 DimVenue 创建的表,它描述了我们的事实。 这是最佳实践,但可选 日历日期 维度,允许最终用户导航事实表。 数据可以在有新销售时加载,也可以每天加载; 这就是插入日期或加载日期派上用场的地方。

我们使用存储过程加载事实表并使用日期参数。

  1. 使用以下代码创建存储过程。 为了保持我们在维度加载中应用的相同数据完整性,我们将 NULL 值(如果有)替换为更适合业务的值:
create or replace procedure SalesMart.FactSaleTransactionsLoad(loadate datetime)
language plpgsql
as
    $$
begin
--------------------------------------------------------------------
/*** Delete records loaded for the day, should there be any ***/
--------------------------------------------------------------------
Delete from SalesMart.FactSaleTransactions
where cast(InsertedDate as date) = CAST(loadate as date);
RAISE INFO 'Deleted rows for load date: %', loadate;
--------------------------------------------------------------------
/*** Insert records ***/
--------------------------------------------------------------------
INSERT INTO SalesMart.FactSaleTransactions (
CalendarDate    
,SaleTransactionTime    
,VenueSkey  
,QuantitySold  
,Salecomission
)
SELECT DISTINCT
    ISNULL(c.caldate, '1900-01-01') as CalendarDate
    ,ISNULL(a.saletime, '1900-01-01') as SaleTransactionTime
    ,ISNULL(b.VenueSkey, -1) as VenueSkey
    ,ISNULL(a.qtysold, 0) as QuantitySold
    ,ISNULL(a.commission, 0) as SaleComission
FROM
    public.sales as a
 
LEFT JOIN SalesMart.DimVenue as b
on a.venueid = b.venueid
 
LEFT JOIN public.DimCalendar as c
on to_char(a.saletime,'YYYYMMDD') = to_char(c.caldate,'YYYYMMDD');
--Optional filter, should you want to load only the latest data from source
--where cast(a.saletime as date) = cast(loadate as date);
  
end;
$$;

  1. 通过使用以下命令调用过程来加载数据:
call SalesMart.FactSaleTransactionsLoad(getdate())

安排数据加载

现在,我们可以通过在 Amazon Redshift 查询编辑器 V2 中调度存储过程来自动化建模过程。 完成以下步骤:

  1. 我们首先调用维度加载,维度加载成功运行后,事实加载开始:
BEGIN;
----Insert Dim Loads
call SalesMart.DimVenueLoad(); ----Insert Fact Loads. They will only run if the DimLoad is successful
call SalesMart.FactSaleTransactionsLoad(getdate());
END;

如果维度加载失败,事实加载将不会运行。 这确保了数据的一致性,因为我们不想加载具有过时维度的事实表。

  1. 要安排负载,请选择 活动行程 在查询编辑器 V2 中。

  1. 我们安排查询在每天凌晨 5:00 运行。
  2. 或者,您可以通过启用来添加失败通知 亚马逊简单通知服务 (Amazon SNS) 通知。

在 Amazon Quicksight 中报告和分析数据

QuickSight 是一项商业智能服务,可以轻松提供见解。 作为一项完全托管的服务,QuickSight 可让您轻松创建和发布交互式仪表板,然后可以从任何设备访问这些仪表板并将其嵌入到您的应用程序、门户和网站中。

我们使用数据集市以仪表板的形式直观地呈现事实。 要开始并设置 QuickSight,请参阅 使用非自动发现的数据库创建数据集.

在 QuickSight 中创建数据源后,我们将根据代理键将建模数据(数据集市)连接在一起 skey。 我们使用该数据集来可视化数据集市。

我们的最终仪表板将包含数据集市的见解并回答关键业务问题,例如每个场所的总佣金和销售额最高的日期。 以下屏幕截图显示了数据集市的最终产品。

清理

为了避免将来产生费用,请删除您在本文中创建的所有资源。

结论

我们现在已经成功地使用我们的数据集市实现了 DimVenue, DimCalendarFactSaleTransactions 表。 我们的仓库不完整; 因为我们可以用更多事实来扩展数据集市并实施更多集市,并且随着业务流程和需求随着时间的推移而增长,数据仓库也会随之增长。 在这篇文章中,我们提供了有关在 Amazon Redshift 中理解和实施维度建模的端到端视图。

开始使用您的 亚马逊Redshift 今天的维度模型。


作者简介

伯纳德·维斯特 是一位经验丰富的云工程师,在创建可扩展且高效的数据模型、定义数据集成策略以及确保数据治理和安全性方面拥有多年经验。 他热衷于使用数据来推动洞察力,同时满足业务需求和目标。

阿比舍克·潘 是与 AWS 印度公共部门客户合作的 WWSO SA 分析专家。 他与客户合作定义数据驱动策略,提供有关分析用例的深入讨论,并设计可扩展且高性能的分析应用程序。 他拥有 12 年的经验,对数据库、分析和 AI/ML 充满热情。 他是一位狂热的旅行家,并试图通过相机镜头捕捉世界。

时间戳记:

更多来自 AWS 大数据