【问题标题】:Dynamodb single table structure for Many to many relation多对多关系的Dynamodb单表结构
【发布时间】:2021-01-18 03:03:39
【问题描述】:

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

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

访问模式

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

我尝试使用邻接模式进行建模

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

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

【问题讨论】:

    标签: amazon-web-services amazon-dynamodb


    【解决方案1】:

    如果您有一个包含 Category 的 PK 和一个包含 User 的 SK 来为每个类别中的用户建模,您可以创建一个 Global Secondary Index (GSI),其中 PK 指向原始表的 SK(User)和SK 指向原表的 PK (Category)。

    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)

    更新:根据 cmets 包含元数据的扩展模型

    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 查询表
    • 特定用户及其类别:查询 GSI_Users by U#x

    【讨论】:

    • Category 元数据和用户元数据呢?
    • 元数据仍然可以作为主表的一部分在单独的行中建模。
    • 要不将元数据复制到 GSI,您可以引入用于 GSI 的单独属性。我将在答案中添加一个扩展模型,请稍等。
    • 我的模型是否正确,我在 NoSql 工作台的截图中添加了
    • 我不知道您的模型是否正确,因为它包含很多不属于您的问题的信息。在不让元数据污染 GSI 的情况下为多对多关系建模的一种方法是我在更新的答案中概述的。
    猜你喜欢
    • 2020-04-18
    • 1970-01-01
    • 2021-07-10
    • 2021-01-13
    • 2015-10-08
    • 2021-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多