跨主索引和全局二级索引的 DynamoDB 键唯一性

Posted

技术标签:

【中文标题】跨主索引和全局二级索引的 DynamoDB 键唯一性【英文标题】:DynamoDB key uniqueness across primary and global secondary index 【发布时间】:2014-08-17 14:45:36 【问题描述】:

我正在创建一个 DynamoDB 表来保存与单个对象关联的 cmets。

评论在特定时间发布到对象,我使用发布的时间作为范围,因此 cmets 可以按时间降序排序。我有一个发布评论的用户的 userId 的全局二级索引,这应该允许我获取给定用户发布的所有 cmets。

我的问题是,这把钥匙是独一无二的吗?我担心,由于两个用户在技术上可以同时向同一个 objectId 发表评论,因此评论哈希和范围键将是相同的。

我的希望是,由于同一用户不可能同时在同一对象上发布两个 cmets,因此全局二级索引将使键唯一。

 Comment table:

   Hash Key                   Range Key                      Global Secondary Index Hash
 ---------------------------------------------------------------------------------------
|   objectId   |              datePosted                 |           userId             |
| (not unique) |      (not unique if multiple users      | (unique across objectId and  |
|              |  post for the same object @ same time)  |         datePosted)          |
 ---------------------------------------------------------------------------------------

【问题讨论】:

【参考方案1】:

DynamoDB 索引与唯一性无关。 Global 和 local 索引允许有重复的哈希键和范围键对。只有表本身的哈希键和范围键是唯一的。

在您的示例中,两个不同的用户可能在同一时刻对一个对象发表评论,并产生一个重复的 objectId、datePosted 键。有几种方法可以解决这个问题。您可以在主键为空的条件下使用 PutItem 请求,如 API reference 中所述。这将导致第二个评论保存失败,您可以向用户报告错误或简单地使用更新的时间戳重试。没有条件,第二条评论将覆盖第一条。或者,您可以将表的范围键设置为 datePosted 与 userId 连接的复合值。这样,范围键将始终是唯一的,但仍将按日期时间顺序排序。这是 DynamoDB 的常见做法。

【讨论】:

“或者,您可以将表格的范围键设置为 datePosted 与 userId 连接的复合值。”,谢谢! "这样,范围键将始终是唯一的,但仍将按日期时间顺序排序。" - 真的吗?如果您将 datePosted 与 userId 连接起来,那么它不会成为 String 类型,并且对字符串的排序与对日期时间的排序不同。我错过了什么吗? 您必须使用正确的排序日期格式,即 ISO 8601,这在计算机尤其是数据库中非常常见。

以上是关于跨主索引和全局二级索引的 DynamoDB 键唯一性的主要内容,如果未能解决你的问题,请参考以下文章

使用二级索引改进数据访问DynamoDB

使用全局二级索引的 DynamoDB 表查询项

使用带有全局二级索引的 boto3 在 dynamodb 上进行有条件的放置

我们可以更新 DynamoDB 表的现有全局二级索引的投影吗?

如何使用 DynamoDB 建模双键/二级索引约束?

DynamoDB 中本地索引和全局索引的区别