DynamoDB,哪个更好:多个小查询还是一个大查询?
DynamoDB, what's better: multiple small queries or one big query?
我有以下数据集
Post Table
| UserID | title |
-----------------------
| userA | Article 1 |
| userA | Article 2 |
| userB | Article 3 |
| userC | Article 4 |
| userB | Article 5 |
我想获取用户 A 和用户 B 的所有文章。
实际上,我可以在输入中输入 50 个用户 ID,在输出中输入一千个帖子。
执行此类查询的最佳方法是什么:
- UserID 上的 GSI 和每个 GSI 的查询(返回几行的 50 个查询)
- 使用“IN”过滤器对用户 ID 进行过滤器扫描?
- 还有其他解决方案吗?
使用 MySQL,我知道做一个大查询比做很多小查询要好。但是 DynamoDB 是这样吗?
使用 DynamoDB 时,您需要停止考虑 SQL 数据库。范式完全不同。
要回答您的问题,最好使用一个查询,因为即使您不使用所有小查询,小查询也总是会舍入您的读取容量。
尽可能避免扫描,这是最昂贵的扫描,因为过滤发生在之后所有文档都已阅读。
深入了解 DynamoDB
在您的情况下,我看到一个清晰的访问模式,其中您的 Primary Key
是 UserID
(您的 hashKey
)和 title
(您的 rangeKey
).
但是,这会使您的 table 非常严格,这意味着您的 hashKey
始终是 UserId
而您的 rangeKey
始终是 title
。因此,不要将您的密钥命名为 UserId
和 title
,而是使用通用名称,例如 pk
和 sk
,这些只是字符串。通过这种方式,您可以执行非常强大的查询(从 table 获取信息的最有效方式),例如 pk=userA and sk BEGINS_WITH Article
。但这假设您的所有文章都以单词 Article
开头,我认为情况并非如此。
更进一步,为了让您拥有一个 table 应用程序,您可以在保存不同实体时为其添加前缀。例如,您可以在所有 UserId
前加上 USER#
,在所有文章 title
前加上 ART#
,因此您的 table 看起来像(注意新名称列数):
Post Table
| pk | sk |
------------------------------
| USER#userA | ART#Article 1 |
| USER#userA | ART#Article 2 |
| USER#userB | ART#Article 3 |
| USER#userC | ART#Article 4 |
| USER#userB | ART#Article 5 |
使用此设置,您现在可以 pk=USER#userA and sk BEGINS_WITH ART#
为您提供 JUST ONE 查询,userA
的所有文章
使用这种前缀方法,没有什么能阻止您拥有异构单一 table(DynamoDB 的真正力量即将释放)。例如:
My heteregenous Table
| pk | sk |
--------------------------------
| USER#userA | ART#Article 1 |
| USER#userA | ART#Article 2 |
| USER#userB | ART#Article 3 |
| USER#userC | ART#Article 4 |
| USER#userB | ART#Article 5 |
| ART#Article 5 | COM#Comment 1 |
| ART#Article 5 | COM#Comment 2 |
| ART#Article 6 | COM#Comment 1 |
| ART#Article 6 | COM#Comment 2 |
如果您想要给定文章的所有评论怎么办?简单 pk=ART#Article 5 and sk BEGINS_WITH COM#
最后,您可以使用一种称为 倒排索引 的技术来创建 GSI,您只需将 pk
切换为 sk
和 sk
为您的 pk
提供更多潜在的查询。这在第一部中已经说的很清楚了,推荐大家按顺序观看:
我有以下数据集
Post Table
| UserID | title |
-----------------------
| userA | Article 1 |
| userA | Article 2 |
| userB | Article 3 |
| userC | Article 4 |
| userB | Article 5 |
我想获取用户 A 和用户 B 的所有文章。 实际上,我可以在输入中输入 50 个用户 ID,在输出中输入一千个帖子。
执行此类查询的最佳方法是什么:
- UserID 上的 GSI 和每个 GSI 的查询(返回几行的 50 个查询)
- 使用“IN”过滤器对用户 ID 进行过滤器扫描?
- 还有其他解决方案吗?
使用 MySQL,我知道做一个大查询比做很多小查询要好。但是 DynamoDB 是这样吗?
使用 DynamoDB 时,您需要停止考虑 SQL 数据库。范式完全不同。
要回答您的问题,最好使用一个查询,因为即使您不使用所有小查询,小查询也总是会舍入您的读取容量。
尽可能避免扫描,这是最昂贵的扫描,因为过滤发生在之后所有文档都已阅读。
深入了解 DynamoDB
在您的情况下,我看到一个清晰的访问模式,其中您的 Primary Key
是 UserID
(您的 hashKey
)和 title
(您的 rangeKey
).
但是,这会使您的 table 非常严格,这意味着您的 hashKey
始终是 UserId
而您的 rangeKey
始终是 title
。因此,不要将您的密钥命名为 UserId
和 title
,而是使用通用名称,例如 pk
和 sk
,这些只是字符串。通过这种方式,您可以执行非常强大的查询(从 table 获取信息的最有效方式),例如 pk=userA and sk BEGINS_WITH Article
。但这假设您的所有文章都以单词 Article
开头,我认为情况并非如此。
更进一步,为了让您拥有一个 table 应用程序,您可以在保存不同实体时为其添加前缀。例如,您可以在所有 UserId
前加上 USER#
,在所有文章 title
前加上 ART#
,因此您的 table 看起来像(注意新名称列数):
Post Table
| pk | sk |
------------------------------
| USER#userA | ART#Article 1 |
| USER#userA | ART#Article 2 |
| USER#userB | ART#Article 3 |
| USER#userC | ART#Article 4 |
| USER#userB | ART#Article 5 |
使用此设置,您现在可以 pk=USER#userA and sk BEGINS_WITH ART#
为您提供 JUST ONE 查询,userA
使用这种前缀方法,没有什么能阻止您拥有异构单一 table(DynamoDB 的真正力量即将释放)。例如:
My heteregenous Table
| pk | sk |
--------------------------------
| USER#userA | ART#Article 1 |
| USER#userA | ART#Article 2 |
| USER#userB | ART#Article 3 |
| USER#userC | ART#Article 4 |
| USER#userB | ART#Article 5 |
| ART#Article 5 | COM#Comment 1 |
| ART#Article 5 | COM#Comment 2 |
| ART#Article 6 | COM#Comment 1 |
| ART#Article 6 | COM#Comment 2 |
如果您想要给定文章的所有评论怎么办?简单 pk=ART#Article 5 and sk BEGINS_WITH COM#
最后,您可以使用一种称为 倒排索引 的技术来创建 GSI,您只需将 pk
切换为 sk
和 sk
为您的 pk
提供更多潜在的查询。这在第一部中已经说的很清楚了,推荐大家按顺序观看: