在 DynamoDB 中为关系数据建模的示例 - Amazon DynamoDB
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

在 DynamoDB 中为关系数据建模的示例

此示例介绍如何在 Amazon DynamoDB 中为关系数据建模。DynamoDB 表设计对应 关系建模 显示的关系订单条目架构,采用 相邻列表设计模式,这是在 DynamoDB 中表示关系数据结构的常见方式。

设计模式需要定义一组通常与关系架构各个表关联的实体类型。随后,使用复合(分区和排序)主键将实体项目添加到表。这些实体项目的分区键是唯一标识项目的属性,在所有项目上通常称为 PK。排序键属性包含的属性值可以用于反向索引或全局二级索引,通常称为 SK

定义以下实体,支持关系订单条目架构。

  1. HR-Employee - PK:EmployeeID,SK:Employee Name

  2. HR-Region - PK:RegionID,SK:Region Name

  3. HR-Country-PK: CountryId,SK:国家名称

  4. HR-Location - PK:LocationID,SK:Country Name

  5. HR-Job - PK:JobID,SK:Job Title

  6. HR-Department - PK: DepartmentID, SK: DepartmentID

  7. Oe-customer-PK:客户 ID,SK:ID AccountRep

  8. OE-Order - PK OrderID,SK:CustomerID

  9. OE-Product - PK: ProductID, SK: Product Name

  10. OE-Warehouse - PK: WarehouseID, SK: Region Name

将这些实体项目添加到表后,可以将边缘项目添加到实体项目分区,定义这些项目之间的关系。下表演示此步骤。


      显示实体项目之间关系的示例表。

在此示例中,表的 EmployeeOrderProduct Entity 分区都具有额外边缘项目,这些项目包含指向表上其他实体项目的指针。接下来,定义几个全局二级索引 (GSI),支持之前定义的所有访问模式。实体项目不会对主键或排序键属性使用完全相同的值类型。只需要让主键和排序键属性在表上显示为插入。

一些实体使用正确名称,其他实体使用其他实体 ID 作为排序键值,可让同一个全局二级索引支持多种查询类型。此技术称为 GSI 重载,实际消除了对包含多种项目类型的表的 20 个全局二级索引的默认限制。在下图中显示为 GSI 1


      显示支持多种查询的全局二级索引的示例表。

GSI 2 旨在支持一种十分常见的应用程序访问模式,获取表中所有具有特定状态的项目。对于项目不均匀分布可用状态的大型表,此访问模式将产生热门键,除非项目分布在多个逻辑分区,可以并行查询。此设计模式称为 write sharding

要对 GSI 2 实现此模式,应用程序将为每个 Order 项目添加 GSI 2 主键属性,其中填充一个 0–N 之间的随机数,除非有具体理由,否则通常可以采用下面的公式计算 N。

ItemsPerRCU = 4KB / AvgItemSize PartitionMaxReadRate = 3K * ItemsPerRCU N = MaxRequiredIO / PartitionMaxReadRate

例如,假设预计以下内容:

  • 系统中将有最多 200 万个订单,5 年内将增至 300 万。

  • 多达 20% 的订单将在任何给定时间处于 OPEN 状态。

  • 平均订单记录约为 100 字节,订单分区 OrderItem 中有三条记录,每条记录约为 50 字节,因此您的订单实体平均大小为 250 字节。

对于此表,N 系数计算如下所示。

ItemsPerRCU = 4KB / 250B = 16 PartitionMaxReadRate = 3K * 16 = 48K N = (0.2 * 3M) / 48K = 13

在此情况下,需要在 GSI 2 的至少 13 个逻辑分区分布所有订单,确保读取所有具有 OPEN 状态的 Order 项目不会在物理存储层产生热门分区。可以填充允许数据集存在异常的数字。因此,使用 N = 15 的模型可能合适。如上所述,将 0–N 随机值添加到表上插入的每个 OrderOrderItem 记录的 GSI 2 PK 属性。

这种划分方式假定,需要收集所有 OPEN 发票的访问模式发生的频率相对较低,这样可以利用爆增容量满足请求。可以使用 StateDate Range 排序键条件查询以下全局二级索引,根据需要生成处于指定状态的部分或所有 Orders


      显示 GSI 2 主键和投影属性的示例表。

在此示例中,项目随机分布在 15 个逻辑分区。此结构之所以适用,是因为访问模式需要检索大量项目。因此,不可能所有 15 个线程都返回空结果集,这可能代表容量浪费。查询始终使用 1 个读取容量单位 (RCU) 或 1 个写入容量单位 (WCU),即使未返回任何内容或未写入任何数据。

如果访问模式需要对返回稀疏结果集的全局二级索引执行高速查询,更好的做法是使用哈希算法分配项目,而不是随机模式。在此情况下,选择的属性可能在运行查询时已知,插入项目时将该属性哈希至 0-14 键空间,然后可从全局二级索引高效读取项目。

最后,您可以再次访问之前定义的访问模式。下面是将用于新的 DynamoDB 版本应用程序的访问模式和查询条件列表。

访问模式 查询条件

1

按员工 ID 查找员工详细信息

表上的主键,ID="HR-EMPLOYEE"

2

按员工姓名查询员工详细信息

使用 GSI-1,PK="Employee Name"

3

仅获取员工的当前工作详细信息

表上的主键,PK=HR-EMPLOYEE-1,SK 以“JH”开头

4

为客户获取日期范围内的订单

分别使用 GSI-1、PK=CUSTOMER1、SK= “STATUS-DATE” StatusCode

5

显示所有客户的日期范围内处于 OPEN(未结)状态的所有订单

使用 GSI-2,PK=范围 [0..N] 内并行查询,SK 介于 OPEN-Date1 与 OPEN-Date2 之间

6

最近聘用的所有员工

使用 GSI-1,PK="HR-CONFIDENTIAL',SK > date1

7

查找特定仓库中的所有员工

使用 GSI-1,PK=WAREHOUSE1

8

获取产品的所有订单项,包括仓库位置清单

使用 GSI-1,PK=PRODUCT1

9

通过客户代表获取客户

使用 GSI-1,PK=ACCOUNT-REP

10

按客户代表和日期获取订单

分别使用 GSI-1、PK=ACCOUNT-REP、SK= “STATUS-DATE” StatusCode

11

获取具有特定职衔的所有员工

使用 GSI-1,PK=JOBTITLE

12

按产品和仓库获取清单

表上的主键,PK=OE-PRODUCT1,SK=PRODUCT1

13

获取总产品清单

表上的主键,PK=OE-PRODUCT1,SK=PRODUCT1

14

获取按订单总计和销售周期排名的客户代表

使用 GSI-1,PK=YYYY-Q1,=False scanIndexForward