【问题标题】:Uniqueness in DynamoDB secondary indexDynamoDB 二级索引的唯一性
【发布时间】:2014-08-15 03:32:02
【问题描述】:

问题:

主键是复合哈希范围键的 DynamoDB 表是唯一的。这是否也扩展到二级索引?

示例:

我有一个带有 post_id 主键和 comment_id 范围键的 cmets DynamoDB 表。 此外,还有一个带有 date-user_id 范围键的本地二级索引。

每个条目都是用户在帖子中留下的评论。二级索引的目的是计算在特定日期有多少独立用户对帖子发表了评论。

条目 1: post_id:1 评论编号:1 date-user_id: 2014_06_24-1

条目 2: post_id:1 评论编号:2 date-user_id: 2014_06_24-1

条目 3: post_id:1 评论编号:3 date-user_id: 2014_06_24-2

当我执行指定二级索引的查询并传入 post_id 等于 1 且 date-user_id 等于 2014_06_24-1 的条件时,我得到的计数为 2,我期望计数为 1。

为什么二级索引有两个具有相同主键/范围键的条目。

【问题讨论】:

    标签: amazon-web-services amazon-dynamodb


    【解决方案1】:

    二级索引不保证唯一性。来自文档:

    此外,请记住全局二级索引不强制唯一性

    http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/GuidelinesForTables.html

    【讨论】:

    【解决方案2】:

    不,他们没有。索引是异步更新的,这意味着它们最终将保持一致,这也意味着 dynamodb 在您进行更新调用时将无法强制执行唯一性(它不会检查二级索引的唯一性,如这是一个异步操作;如果是这样,它将无法返回失败,因为实时调用已经完成)。

    另一方面,这也是您只能对 GSI 索引执行 Scan 或 Query 而不能执行 GetItem 的原因(即 GetItem 应该返回一个项目,但在没有唯一性约束)。

    【讨论】:

    【解决方案3】:

    本地二级索引 (LSI) 中的每个项目与表中的相应项目具有 1:1 的关系。在上面的示例中,虽然 LSI 中的条目 1 和条目 2 具有相同的范围键值,但它们指向的表中的项目是不同的。因此索引键(散列或散列+范围)不是唯一的。

    全球二级索引 (GSI) 在这方面与 LSI 类似。每个 GSI 项目都包含表哈希和范围键(对应项目的)。更多详情请访问http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/GSI.html#GSI.Projections

    【讨论】:

      【解决方案4】:

      实际上可以通过组合事务和多个表来确保GSI的唯一性。

      例如假设您的主表有这些索引:

      record_id(分区键) 名称 (GSI)

      如果要确保“name”在此表中是唯一的,请创建具有以下索引的辅助表:

      名称(分区键)

      然后在主表中创建文档时,将其作为事务的一部分执行,您还可以在第二个表中创建一个文档,并具有确保名称不存在的特殊条件,例如该交易将有以下更新:

      PutItem(Table=mainTable, ConditionExpression='attribute_not_exists(#RECORD_ID)',...)

      PutItem(Table=namesTable,ConditionExpression='attribute_not_exists(#NAME)',...)

      从主表中删除一个项目还可以确保在事务中从两个表中删除两个文档,这基本上确保了引用完整性。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-04-11
        • 1970-01-01
        • 2016-05-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多