多对多关系的Dynamodb单表结构

时间:2021-01-17 17:24:27

标签: amazon-web-services amazon-dynamodb

我们有两个实体类别和用户。很经典的多2多关系。

  1. 用户可以被标记到多个类别
  2. 类别可以有多个用户

访问模式

  1. 获取类别列表
  2. 获取用户列表,以及用户所属的类别
  3. 获取单个用户,具有单个用户所属的类别
  4. 获取特定类别的用户列表

我尝试使用邻接模式建模 table adjacency type index

但我对如何查询没有什么困惑

  1. 用户列表并获取每个用户所属的所有类别

1 个答案:

答案 0 :(得分:2)

如果您有一个包含类别的 PK 和包含用户的 SK 来为每个类别中的用户建模,您可以创建一个全局二级索引 (GSI),其中 PK 指向原始表的 SK(用户)和SK 指向原始表的 PK(类别)。

Table
| PK  | SK  | ...
| C#1 | U#1 | ...
| C#1 | U#2 | ...
| C#2 | U#1 | ...
| C#2 | U#3 | ...

GSI
| Table_SK | Table_PK | ...
| U#1      | C#1      | ...
| U#1      | C#2      | ...
| U#2      | C#1      | ...
| U#3      | C#2      | ...

现在可以查询了:

  • 所有类别,包括其各自的用户(扫描表)
  • 单个类别中的所有用户(查询表)
  • 所有用户,包括他们各自的类别(扫描 GSI)
  • 单个用户所属的所有类别(查询 GSI)

更新:扩展模型以根据评论包含元数据

Table
| PK  | SK   | CAT | USR | Metadata
 ---------------------------------------
|     | DATA |           | { ...: ... } 
| C#1 | U#1  | C#1 | U#1 | { ...: ... } (copied from user record)
|     | U#2  | C#1 | U#1 | { ...: ... } (copied from user record)
 ---------------------------------------
|     | DATA |           | { ...: ... }
| C#2 | U#1  | C#1 | U#1 | { ...: ... } (copied from user record)
|     | U#3  | C#1 | U#1 | { ...: ... } (copied from user record)
 ---------------------------------------
| U#1 | DATA |           | { ...: ... }
 ---------------------------------------
| U#2 | DATA |           | { ...: ... }
 ---------------------------------------
| U#3 | DATA |           | { ...: ... }
 ---------------------------------------

GSI_Users
| Table_USR | Table_CAT |
 -----------------------
| U#1       | C#1       |
|           | C#2       |
 -----------------------
| U#2       | C#1       |
 -----------------------
| U#3       | C#2       |
 -----------------------

GSI_Categories
| Table_CAT | Table_USR |
 -----------------------
| C#1       | U#1       |
|           | U#2       |
 -----------------------
| C#2       | U#1       |
|           | U#3       |
 -----------------------

查询:

  • 所有类别(包括他们的用户):扫描 GSI_Categories
  • 所有用户(包括他们的类别):扫描 GSI_Users
  • 特定类别(包括元数据):按 C#xSK=DATA 查询表
  • 特定类别及其用户:按 C#x 查询 GSI_Categories
  • 特定用户(包括元数据):按 U#xSK=DATA 查询表
  • 特定用户及其类别:按 U#x 查询 GSI_Users