【问题标题】:How to handle many to many in DynamoDB如何在 DynamoDB 中处理多对多
【发布时间】:2018-01-31 08:02:08
【问题描述】:

我是 NoSql 和 DynamoDb 的新手,但来自 RDBMS.. 我的表正在从 MySql 移动到 DynamoDb。我有桌子:
客户(列:cid [PK]、姓名、联系人)
硬件(列:hid[PK]、名称、类型)
租金(列:rid[PK]、cid、hid、time)。 => 这是客户和硬件项目的关联。

一个客户可以拥有多个硬件项目,一个硬件项目可以在多个客户之间共享。

要求:客户和硬件项目的单独列表应该能够检索。
租金详情 - 哪个客户租用了哪个硬件项目。

我提到了this - 二级索引表。这是关于将所有列保留在一个表中。
我想有 2 个 DynamoDb 表:
客户 - 这具有类似于列和一组硬件项目哈希键的所有属性。 (然后我的问题是,当查询客户表以仅检索客户时,所有硬件密钥也被加载。)

请对表结构有任何指导吗?如何保存、加载甚至更新?
请问有java示例吗? (找不到任何与我的场景类似的有用资源)

【问题讨论】:

    标签: nosql amazon-dynamodb


    【解决方案1】:

    看看 DynamoDB 的邻接表设计模式 https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/bp-adjacency-graphs.html

    在您的情况下,基于邻接列表设计模式,您的架构可以设计如下
    分区键和排序键的前缀表示记录的类型。
    如果记录类型是客户,则分区键和排序键都应具有前缀“客户-”。
    如果记录是客户租用硬件,分区键的前缀应该是'customer-',排序键的前缀应该是'hardware-'

    base table
    +------------+------------+-------------+
    |PK          |SK          |Attributes   |
    |------------|------------|-------------|
    |customer-cid|customer-cid|name, contact|
    |hardware-hid|hardware-hid|name, type   |
    |customer-cid|hardware-hid|time         |
    +------------+------------+-------------+
    
    Global Secondary Index Table
    
    +------------+------------+----------+
    |GSI-1-PK    |GSI-1-SK    |Attributes|
    |------------|------------|----------|
    |hardware-hid|customer-cid|time      |
    +------------+------------+----------+
    

    客户和硬件应该存储在同一个表中。客户可以参考硬件
    SELECT * FROM base_table WHERE PK=customer-123 AND SK.startsWith('hardware-')
    如果您的硬件想要回馈客户,您应该使用 GSI 表
    SELECT * FROM GSI_table WHERE PK=hardware-333 AND SK.startsWith('customer-')

    注意:我写的SQL只是伪代码,仅供大家参考。

    【讨论】:

    • “全球二级索引表”真的是另一个单独的表吗?
    • 同一张表,只是使用不同的键作为分区键。 docs.aws.amazon.com/amazondynamodb/latest/developerguide/…
    • 主要原因是DynamoDB原生不支持外键。为了获得更好的性能,DynamoDB 应该尽可能少地接收请求。因此,要处理多对多关系,DynamoDB 不能充当设置多个表和外键的关系数据库。最佳实践是使用一张表来处理所有这些关系,并通过一个请求完成它。 PK 和 SK 中的前缀用于模拟 RDBMS 的表和外键。如果PK和SK相同,则匹配RDBMS的表,如果不同,则匹配RDBMS的外键。
    • 嗨 Yu,有没有办法创建 GSI?我的意思是,dynamodb 不会为 base_table 中的每一行创建一个条目吗?或者有没有办法告诉发电机“只有在 pk startsWith customer 和 sk startsWith hardware 时才插入 GSI”?
    【解决方案2】:

    看看this answer,它涵盖了许多与您相关的基础知识。

    DynamoDB 本身不支持外键。每个表都是独立的,没有特殊的工具可以使两个表保持同步。

    您的客户表中可能有一个名为hardwares 的属性。该属性将是客户拥有的硬件 ID 列表。如果您想查看属于某个客户的所有硬件项目,您可以:

    1. 对客户 ID 执行 GetItem。或者根据您查找客户的方式使用查询。
    2. 对于客户硬件属性中的每个硬件 ID,对 Hardware 表执行 GetItem。

    相对于 RDBMS 解决方案,使用 DynamoDB,您通常最终会在客户端应用程序中做更多事情。好处是它快速而简单。但是您会发现您可能会将大量工作从数据库服务器转移到客户端服务器。

    【讨论】:

    猜你喜欢
    • 2021-01-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-13
    • 1970-01-01
    • 2021-01-28
    相关资源
    最近更新 更多