我正在使用DynamoDB来存储事件。 它们存储在1个事件表中,其中包含散列键“Source ID”和范围键“version”。每当源发生新事件时,我想添加一个带有源ID和增加版本号的新项目。
是否可以指定条件写入,以便重复项(相同的哈希键和相同的范围键)永远不会存在?如果是这样,你会怎么做?
我已经成功完成了只有一个哈希键的表:
Map<String, ExpectedAttributeValue> expected = new HashMap<String, ExpectedAttributeValue>();
expected.put("key", new ExpectedAttributeValue().withExists(false));
但不确定如何处理散列+范围键....
答案 0 :(得分:3)
我不太了解Java SDK,但您可以在range_key
和hash_key
上指定“Exist = False”。
也许更好的想法是使用时间戳而不是版本号?否则,还有生成唯一ID的技术。
答案 1 :(得分:2)
我试图强制执行散列和范围键的独特组合,并且遇到了这篇文章。我发现它并没有完全回答我的问题,但我确实指出了正确的方向。这是为了整理松散的目的。
似乎DynamoDB实际上是按照设计强制执行散列和范围键的唯一组合。我引用
“表中的所有项目必须具有主键属性的值,并且Amazon DynamoDB确保该名称的值是唯一的”
来自http://aws.amazon.com/dynamodb/下标题为主键的部分。
在我自己的测试中使用putItem和nodejs的aws-sdk我能够发布两个相同的项而不会产生错误。当我检查数据库时,实际只插入了一个项目。似乎第二次调用putItem具有相同的散列和范围键组合被视为对原始项的更新。
当我尝试在设置值的哈希键和范围键上设置exist = false选项时,我也收到错误“不能指望某个属性具有指定值,而期望它不存在”。要解决此错误,我删除了预期的散列和范围键下的值,当我尝试插入两次相同的密钥时,它开始生成验证错误。
所以,我的insert命令看起来像这样(对于Java会有所不同,但希望你能得到这个想法)
{ "TableName": "MyTableName",
"Item" : {
"HashKeyFieldName": {
"S": HashKeyValue
},
"RangeKeyFieldName": {
"N": currentTime.getTime().toString()
},
"OtherField": {
"N": "61404032632"
}
},
"Expected": {
"HashKeyFieldName" : { "Exists" : false},
"RangeKeyFieldName" : { "Exists" : false}
}
}
虽然最初我试图做一个条件插入来检查是否有一个哈希值和范围值与我试图插入的相同,现在我只需要检查HashField和RangeField是否存在。如果它们存在,那意味着我正在更新项目而不是插入。