DynamoDb table 设计:单个 table 或多个 table
DynamoDb table design: Single table or multiple tables
我对 NoSQL 和 DynamoDB 很陌生,但我曾经使用过 RDBMS。我正在为一款游戏设计数据库,我们在后端使用 DynamoDB 和 AWS Lambda。我为包含用户信息和资源的播放器配置文件创建了一个 table 名称“Users”。因为游戏有库存系统,所以我还创建了一个 table 名称“UserItems”。
一切都很好,直到我意识到 DynamoDB 没有事务并且在两者上执行的任何操作 table(例如使用增加资源的项目)有可能在一个 table 而在其他人身上成功并会导致影响我们客户的数据丢失。
所以我在想也许我的多个 table 设计不好,因为我在使用 RDBMS 时设计多个 table 是我的习惯。这让我想到将整个“UserItems”作为散列存储在“Users”中,但我不确定这是一个好的做法,因为 Users table 中单行的大小会非常大(我们可能每个用户有 500 个唯一项目)并且每次我拉取或放入数据 from/to“用户”(大多数时候不需要“UserItems”数据)read/write 吞吐量也会非常大。
我该怎么办,保留多个 table 设计并手动处理交易,还是切换到单个 table 设计?或者也许还有第三种选择?
更新:关于我的用例的更多信息
目前我有 2 table
- 用户:UserId(密钥)、用户名、Gold
- UserItems:UserId(分区键)、ItemId(排序键)、名称、GoldValue
场景:
- 用户购买物品:Users.Gold 将推导,新的 UserItem 将添加到 UserItems table。
- 用户出售物品:Users.Gold将增加,该物品将从UserItems中删除table。
在上述两种情况下,我将不得不为 2 table 秒执行 2 次更新操作,如果没有事务,其中一个可能会失败。
为了解决这个问题,我考虑使用单个 table 解决方案,它是单个用户 table,具有 4 列 UserId(密钥)、用户名、Gold、UserItems。但是,我担心两件事:
- 对于单个单元格,UserItems 中的数据可能会变得很大,因为一个用户最多可以拥有 500 个项目。
- 到 add/delete 项我必须从 dynamodb 中提取 UserItems,add/delete 项然后将其放回用户中。所以我必须为 1 个操作执行 1 次读取和 1 次写入操作。由于问题 (1),read/write 数据大小可能会变得非常大。
NoSql 数据库最适合非交易数据。如果您将规范化(将数据拆分为多个 tables)引入 noSQL,那么您就达到了它的全部目的。如果性能是最重要的,那么您应该考虑只为您的用例设置一个 table。 DynamoDB 支持范围键,也支持二级索引。对于您的用例,最好重新设计 table 以使用范围键。
如果您可以分享更多关于您目前的 table 的详细信息,也许我可以帮助您提供更多信息。
FWIW,关于 NoSQL Design for DynamoDB 的 AWS 文档建议使用单个 table:
As a general rule, you should maintain as few tables as possible in a
DynamoDB application. As emphasized earlier, most well designed
applications require only one table, unless there is a specific reason
for using multiple tables.
Exceptions are cases where high-volume time series data are involved,
or datasets that have very different access patterns—but these are
exceptions. A single table with inverted indexes can usually enable
simple queries to create and retrieve the complex hierarchical data
structures required by your application.
我对 NoSQL 和 DynamoDB 很陌生,但我曾经使用过 RDBMS。我正在为一款游戏设计数据库,我们在后端使用 DynamoDB 和 AWS Lambda。我为包含用户信息和资源的播放器配置文件创建了一个 table 名称“Users”。因为游戏有库存系统,所以我还创建了一个 table 名称“UserItems”。
一切都很好,直到我意识到 DynamoDB 没有事务并且在两者上执行的任何操作 table(例如使用增加资源的项目)有可能在一个 table 而在其他人身上成功并会导致影响我们客户的数据丢失。
所以我在想也许我的多个 table 设计不好,因为我在使用 RDBMS 时设计多个 table 是我的习惯。这让我想到将整个“UserItems”作为散列存储在“Users”中,但我不确定这是一个好的做法,因为 Users table 中单行的大小会非常大(我们可能每个用户有 500 个唯一项目)并且每次我拉取或放入数据 from/to“用户”(大多数时候不需要“UserItems”数据)read/write 吞吐量也会非常大。
我该怎么办,保留多个 table 设计并手动处理交易,还是切换到单个 table 设计?或者也许还有第三种选择?
更新:关于我的用例的更多信息
目前我有 2 table
- 用户:UserId(密钥)、用户名、Gold
- UserItems:UserId(分区键)、ItemId(排序键)、名称、GoldValue
场景:
- 用户购买物品:Users.Gold 将推导,新的 UserItem 将添加到 UserItems table。
- 用户出售物品:Users.Gold将增加,该物品将从UserItems中删除table。
在上述两种情况下,我将不得不为 2 table 秒执行 2 次更新操作,如果没有事务,其中一个可能会失败。
为了解决这个问题,我考虑使用单个 table 解决方案,它是单个用户 table,具有 4 列 UserId(密钥)、用户名、Gold、UserItems。但是,我担心两件事:
- 对于单个单元格,UserItems 中的数据可能会变得很大,因为一个用户最多可以拥有 500 个项目。
- 到 add/delete 项我必须从 dynamodb 中提取 UserItems,add/delete 项然后将其放回用户中。所以我必须为 1 个操作执行 1 次读取和 1 次写入操作。由于问题 (1),read/write 数据大小可能会变得非常大。
NoSql 数据库最适合非交易数据。如果您将规范化(将数据拆分为多个 tables)引入 noSQL,那么您就达到了它的全部目的。如果性能是最重要的,那么您应该考虑只为您的用例设置一个 table。 DynamoDB 支持范围键,也支持二级索引。对于您的用例,最好重新设计 table 以使用范围键。 如果您可以分享更多关于您目前的 table 的详细信息,也许我可以帮助您提供更多信息。
FWIW,关于 NoSQL Design for DynamoDB 的 AWS 文档建议使用单个 table:
As a general rule, you should maintain as few tables as possible in a DynamoDB application. As emphasized earlier, most well designed applications require only one table, unless there is a specific reason for using multiple tables.
Exceptions are cases where high-volume time series data are involved, or datasets that have very different access patterns—but these are exceptions. A single table with inverted indexes can usually enable simple queries to create and retrieve the complex hierarchical data structures required by your application.