【问题标题】:When it's worth the tradeoff of using local secondary index in DynamoDB?何时值得在 DynamoDB 中使用本地二级索引?
【发布时间】:2018-12-30 23:08:07
【问题描述】:

我已经阅读了guidelines 的二级索引,但我不确定快速搜索的能力何时超过了扫描属性的劣势。举个例子吧。

我正在为用户保存游戏进度数据。 PK 是用户 ID。我需要能够:

  1. 了解特定游戏的用户进度。

  2. 为用户获取所有已完成/正在进行的游戏。

因此,我可以将我的 SK 设计为 progress_{state} 以便能够快速查询所有游戏的进度(状态表示开始/完成),或者我可以将我的 SK 设计为 progress_ {gameId} 能够快速查询给定游戏的进度。但是,我不能同时使用 SK。当我选择一个时,另一个操作将需要扫描。

因此,我正在考虑使用 LSI,这将增加整个表的开销,正如 Amazon here 所指出的那样:

每个二级索引都意味着 DynamoDB 需要做更多的工作。当您在具有本地二级索引的表中添加、删除或替换项目时,DynamoDB 将使用额外的写入容量单位来更新相关索引。

我估计最多有数千种类型的游戏,我想知道是否值得使用 LSI,或者在我选择的其他操作中使用扫描是否更好。

有人对此类问题有任何实际经验吗?我找不到有关此主题的任何内容。

【问题讨论】:

    标签: amazon-web-services amazon-dynamodb amazon-dynamodb-index


    【解决方案1】:

    当您设计 DynamoDB 表时,主要成本因素是读取和写入的 IOPS。

    这就是为什么避免扫描通常更好的原因。扫描会消耗大量的读取 IOPS,并且会随着表中项目的数量而增加,因为扫描需要在返回匹配项目之前读取表中的所有项目。

    然后回到您使用 SK 进行进度的用例,最好使用属性并定义二级索引,因为您稍后需要更新状态(这在 PK 和 SK 中是不可能的)表)。

    因此,根据您的用例和问题中给出的信息,您可以将架构定义为;

    PK-用户ID SK-游戏ID GSI-进度(PK)

    快速查询所有游戏进度 GSI 进度(PK)

    注意:如果这是针对特定用户的;您可以将其更改为 LSI Progress。

    快速查询给定游戏的进度(假设对于给定用户) 使用 Table 的 UserID (PK) 和 GameID (SK) 查询

    【讨论】:

    • 嗨,Ashan,感谢您提供的有用答案。我可以再问一件事吗?目前,我将游戏数据(例如价格、游戏描述)和进度数据保存在一个具有不同 PK 的表中。您是否会将这张表拆分为 2 个(User_data/Game_data),这样游戏数据查询就不会受到 LSI 开销的“打击”,还是可以将所有内容保存在一张表中。
    • 嗨@Martin 似乎分成两个表是有道理的。这里的基本原理是保持项目小(以保持每个表项目的每个 IOPS 1kb 写入和 4kb 读取限制)并使用不同的查询模式分离数据。
    猜你喜欢
    • 2018-10-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-17
    相关资源
    最近更新 更多