我是NoSQL和DynamoDB的新手,我习惯使用RDBMS . 我正在为游戏设计数据库,我们正在使用DynamoDB和AWS Lambda作为后端 . 我为包含用户信息和资源的播放器配置文件创建了一个表名“Users” . 因为游戏有库存系统,我还创建了一个表名“UserItems” .
这一切都很好,直到我意识到DynamoDB没有事务,并且在两个表上执行的任何操作(例如使用增加资源的项目)在一个表上有可能失败而在另一个表上成功并且将导致丢失的数据影响我们的顾客 .
所以我想也许我的多表设计并不好,因为当我使用RDBMS时,我习惯设计多个表 . 这让我想到将整个“UserItems”存储为“用户”中的哈希,但我不确定这是一个好习惯,因为Users表中单行的大小会非常大(我们可能有500个唯一的项目)每个用户)以及每次从/向“用户”提取数据(大多数时候不需要“UserItems”数据)时,读/写吞吐量也会非常大 .
我该怎么做,保持多个表设计并手动处理事务或切换到单表设计?或者可能有第三种选择?
Updated: more information about my use case
目前我有2张 table
-
用户:UserId(密钥),用户名,金牌
-
UserItems:UserId(分区键),ItemId(排序键),Name,GoldValue
场景:
-
用户购买商品:Users.Gold将被推断,新的UserItem将被添加到UserItems表 .
-
用户出售项目:Users.Gold将增加,该项目将从UserItems表中删除 .
在上述两种情况下,我将不得不对2个表执行2次更新操作,没有事务,其中一个失败 .
为了解决这个问题,我考虑使用单表解决方案,它是一个包含4列UserId(key),Username,Gold,UserItems的单个Users表 . 然而,有两件事我担心:
-
UserItems中的数据可能会因单个单元格而变大,因为一个用户最多可以有500个项目 .
-
要添加/删除项目,我必须从dynamodb中提取UserItems,添加/删除项目,然后将其放回用户 . 所以我必须为1个动作做1次读取和1次写入操作 . 并且由于问题(1),读/写数据大小可能变得非常大 .
2 回答
NoSql数据库最适合非交易数据 . 如果你将规范化(将你的数据分成多个表)带入noSQL,那么你就是在打败它的全部目的 . 如果性能最重要,那么您应该考虑只为您的用例使用一个表 . DynamoDB支持范围键,也支持辅助索引 . 对于您的用例,最好重新设计表以使用Range Keys . 如果您可以分享有关当前表的更多详细信息,也许我可以帮助您获得更多输入 .
FWIW,NoSQL Design for DynamoDB上的AWS文档建议使用单个表: