DynamoDb表设计:单表或多表

Bin*_*ong 11 amazon-web-services nosql amazon-dynamodb aws-lambda

我是NoSQL和DynamoDB的新手,我习惯使用RDBMS.我正在为游戏设计数据库,我们正在使用DynamoDB和AWS Lambda作为后端.我为包含用户信息和资源的播放器配置文件创建了一个表名"Users".因为游戏有库存系统,我还创建了一个表名"UserItems".

这一切都很好,直到我意识到DynamoDB没有事务,并且在两个表上执行的任何操作(例如使用增加资源的项目)在一个表上有可能失败而在另一个表上成功并且将导致丢失的数据影响我们的顾客.

所以我想也许我的多表设计并不好,因为当我使用RDBMS时,我习惯设计多个表.这让我想到将整个"UserItems"存储为"用户"中的哈希,但我不确定这是一个好习惯,因为Users表中单行的大小会非常大(我们可能有500个唯一的项目)每个用户)以及每次从/向"用户"提取数据(大多数时候不需要"UserItems"数据)时,读/写吞吐量也会非常大.

我该怎么做,保持多个表设计并手动处理事务或切换到单表设计?或者可能有第三种选择?

更新:有关我的用例的更多信息

目前我有2张桌子

  • 用户:UserId(密钥),用户名,金牌
  • UserItems:UserId(分区键),ItemId(排序键),Name,GoldValue

场景:

  1. 用户购买项目:Users.Gold将被推断,新的UserItem将被添加到UserItems表.
  2. 用户销售商品:Users.Gold将增加,商品将从UserItems表中删除.

在上述两种情况下,我将不得不对2个表执行2次更新操作,没有事务,其中一个失败.

为了解决这个问题,我考虑使用单表解决方案,它是一个包含4列UserId(key),Username,Gold,UserItems的单个Users表.然而,有两件事我担心:

  1. UserItems中的数据可能对单个单元格来说很大,因为一个用户最多可以有500个项目.
  2. 要添加/删除项目,我必须从dynamodb中提取UserItems,添加/删除项目,然后将其放回用户.所以我必须为1个动作做1次读取和1次写入操作.并且由于问题(1),读/写数据大小可能变得非常大.

Eug*_*ash 8

FWIW,关于DynamoDB NoSQL Design的AWS文档建议使用单个表:

作为一般规则,您应该在DynamoDB应用程序中维护尽可能少的表.如前所述,除非有使用多个表的特定原因,否则大多数设计良好的应用程序需要一个表.

例外情况是涉及大量时间序列数据的情况,或具有非常不同的访问模式的数据集 - 但这些是例外.具有反向索引的单个表通常可以使简单查询创建和检索应用程序所需的复杂分层数据结构.

  • 对我来说奇怪的是...他们说大多数应用程序只需要一个表,但是两个用例之一使用三个表https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/SampleData.CreateTables.html# SampleData.CreateTables2 (4认同)
  • 实际上,我参加了有关 noSQL 设计的高级课程,整个“单表”规则甚至不是一个好的规则。 (3认同)
  • @MichaelBrown我认为这只是为了简单起见 - 这是一个针对绝对初学者的教程,因此明智的做法是不要让读者一开始就陷入高级概念的泥沼 (2认同)

小智 6

NoSql数据库最适合非事务性数据。如果将规范化(将数据拆分到多个表中)引入noSQL,那么您将击败整个目标。如果性能是最重要的,那么您应该考虑只为您的用例准备一个表。DynamoDB支持范围键,也支持辅助索引。对于您的用例,最好重新设计表以使用范围键。如果您可以共享有关当前表的更多详细信息,也许我可以为您提供更多输入。