6

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

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

对于只有一个哈希键的表,我已经成功地做到了这一点:

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

但不确定如何处理哈希 + 范围键....

4

2 回答 2

3

我不太了解 Java SDK,但您可以在range_keyhash_key.

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

于 2012-10-25T19:00:33.087 回答
2

我试图强制执行哈希和范围键的唯一组合,并遇到了这篇文章。我发现它并没有完全回答我的问题,但确实为我指明了正确的方向。这是一种整理松散末端的尝试。

看起来 DynamoDB 实际上是通过设计强制执行哈希和范围键的唯一组合。我引用

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

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

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

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

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

{     "TableName": "MyTableName",

 "Item"          :  {

                          "HashKeyFieldName": {

                                   "S": HashKeyValue

                          }, 

                          "RangeKeyFieldName": {

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

                          },

                          "OtherField": {

                                   "N": "61404032632"

                          }

                      },

 "Expected":  {

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

                    }

}

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

于 2013-02-22T03:28:41.440 回答