2012-10-25 40 views
5

我正在使用DynamoDB存储事件。 它们存储在1个事件表中,其中包含一个散列键'源ID'和一个范围键'版本'。每次发生源的新事件时,我想添加一个带有源ID和增加版本号的新项目。DynamoDB:如何执行条件写入来执行唯一的Hash + Range键

是否可以指定条件写入,以便重复项(相同的散列键和相同的范围键)永远不会存在?如果是这样,你会如何做到这一点?

我曾经使用过一个散列键深谙此道表:

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

,但不知道如何处理哈希+范围键....

+1

真的很老的问题,但dynamodb有一个原子增量版本,看看(主要是人们在这里清盘) –

+0

原子更新文档在这里:http://docs.aws.amazon.com/amazondynamodb/latest/APIReference/ API_UpdateItem.html – Deemoe

回答

3

我不知道的Java SDK以及但您可以在range_keyhash_key上指定“Exist = False”。

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

+0

感谢您的提示!我将尝试在范围键和散列键上指定“Exist = False”。出于兴趣,你为什么建议使用时间戳而不是版本号? – stikkos

+0

只为了让你的“身份证”一代:) – yadutaf

+0

我试过这个,但仍然无法得到这个工作....我收到错误:“不能期望一个属性有一个指定的值,而期待它不存在“。任何想法?? – stikkos

2

我试图执行散列和范围键的独特组合,并遇到这篇文章。我发现它并没有完全回答我的问题,但肯定指出了我的正确方向。这是试图整理松散的目的。

似乎DynamoDB实际上是通过设计强制执行散列和范围键的唯一组合。我引用

“表中的所有项目必须有主键属性值和亚马逊DynamoDB确保了该名称的值是唯一的”

http://aws.amazon.com/dynamodb/下与标题主键部分。

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

当我尝试在设置了值的散列键和范围键上设置exist = 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是否存在。如果它们存在,那意味着我正在更新项目而不是插入。