【问题标题】:DynamoDB: How to perform conditional write to enforce unique Hash + Range keyDynamoDB:如何执行条件写入以强制执行唯一的 Hash + Range 键
【发布时间】:2012-10-25 18:19:43
【问题描述】:

我正在使用 DynamoDB 来存储事件。 它们存储在 1 个事件表中,带有哈希键“源 ID”和范围键“版本”。每次源发生新事件时,我想添加一个具有源 ID 和增加版本号的新项目。

是否可以指定条件写入以使重复项(相同的哈希键和相同的范围键)永远不存在?如果是这样,你会怎么做?

我已经成功地为只有一个哈希键的表完成了这项工作:

Map<String, ExpectedAttributeValue> expected = new HashMap<String, ExpectedAttributeValue>();
expected.put("key", new ExpectedAttributeValue().withExists(false));

但不确定如何处理 hash + range 键......

【问题讨论】:

标签: amazon-web-services amazon-dynamodb


【解决方案1】:

我不太了解 Java SDK,但您可以在 range_keyhash_key 上指定“Exist=False”。

也许更好的主意是使用时间戳而不是版本号?否则,也有生成唯一 ID 的技术。

【讨论】:

  • 感谢您的提示!我将尝试在范围键和哈希键上指定“Exist=False”。只是出于兴趣,您为什么建议使用时间戳而不是版本号更好?
  • 只是为了让你免于“id”一代:)
  • 我已经尝试过了,但仍然无法正常工作....我收到错误消息:“不能期望属性具有指定的值,而期望它不存在” .有什么想法吗??
【解决方案2】:

我试图强制使用哈希键和范围键的唯一组合,结果发现了这篇文章。我发现它并没有完全回答我的问题,但确实为我指明了正确的方向。这是为了收拾残局。

DynamoDB 似乎在设计上实际上强制执行哈希和范围键的唯一组合。我引用

“表中的所有项目都必须具有主键属性值,并且 Amazon DynamoDB 确保该名称的值是唯一的”

来自http://aws.amazon.com/dynamodb/,在标题为 Primary Key 的部分下。

在我自己使用 putItem 和 aws-sdk for nodejs 的测试中,我能够发布两个相同的项目而不会产生错误。当我检查数据库时,实际上只插入了一项。似乎第二次调用具有相同哈希和范围键组合的 putItem 被视为对原始项目的更新。

当我尝试在散列键和范围键上设置exist=false 选项并设置值时,我也收到错误“不能期望属性具有指定的值而期望它不存在”。为了解决这个错误,我删除了预期的 hash 和 range 键下的值,当我尝试插入相同的键两次时它开始产生验证错误。

所以,我的插入命令看起来像这样(Java 会有所不同,但希望你明白)

{     "TableName": "MyTableName",

 "Item"          :  {

                          "HashKeyFieldName": {

                                   "S": HashKeyValue

                          }, 

                          "RangeKeyFieldName": {

                                   "N": currentTime.getTime().toString()

                          },

                          "OtherField": {

                                   "N": "61404032632"

                          }

                      },

 "Expected":  {

                         "HashKeyFieldName"       : { "Exists" : false},
                         "RangeKeyFieldName"     : { "Exists" : false}

                    }

}

虽然最初我尝试进行条件插入以检查是否存在与我尝试插入的值相同的哈希值和范围值,但现在我只需要检查 HashField 和 RangeField 是否存在。如果它们存在,这意味着我正在更新项目而不是插入。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-20
    • 2010-09-10
    • 2011-06-19
    • 1970-01-01
    • 1970-01-01
    • 2018-07-17
    相关资源
    最近更新 更多