DynamoDB - 如果哈希(或哈希和范围组合)不存在则放置项目 [英] DynamoDB - Put item if hash (or hash and range combination) doesn't exist
问题描述
这是我的用例:我有一个带有哈希 + 范围键的 Dynamo 表.当我将新项目放入表中时,我想做一个唯一性检查.有时我想保证哈希是唯一的(忽略范围).其他时候我想允许重复的哈希,但保证哈希和范围组合是唯一的.我怎样才能做到这一点?
我尝试了attribute_not_exists.它似乎处理第二种情况,它检查哈希+键组合.这是一个 PHP 示例:
$client->putItem(array('表名' =>'测试','项目' =>大批('哈希' =>数组('S' => 'abcdefg'),'范围' =>array('S' => '其他值'),'随便' =>数组('N' => 233)),'条件表达式' =>'attribute_not_exists(散列)'));
奇怪的是,我使用 attribute_not_exists(hash)
还是 attribute_not_exists(range)
似乎并不重要.他们似乎都在做同样的事情.这是它应该如何工作的?
知道如何处理我只想检查 hash
的唯一性的情况吗?
你不能.DynamoDB 中的所有项目都由它们的 hash
或 hash
+range
索引(取决于您的表).
对目前正在发生的事情的一种总结:
- 一个哈希键可以有多个范围键.
- 每个项目都有一个
hash
和一个range
键 - 您正在发出
PutItem
请求并且必须同时提供hash
和range
- 您在
hash
或range
属性名称上提供带有attribute_not_exists
的ConditionExpression
attribute_not_exists
条件只是检查具有该名称的属性是否存在,它不关心值
让我们看一个例子.让我们从包含以下数据的 hash
+range
键表开始:
hash=A,range=1
hash=A,range=2
有四种可能的情况:
如果您尝试使用
hash=A,range=3
和attribute_not_exists(hash)
放置项目,则PutItem
将成功,因为attribute_not_exists(hash)
的计算结果为true
.不存在键hash=A,range=3
满足attribute_not_exists(hash)
条件的项.如果您尝试使用
hash=A,range=3
和attribute_not_exists(range)
放置项目,则PutItem
将成功,因为attribute_not_exists(range)
的计算结果为true
.不存在键hash=A,range=3
满足attribute_not_exists(range)
条件的项.如果您尝试使用
hash=A,range=1
和attribute_not_exists(hash)
放置项目,则PutItem
将失败,因为attribute_not_exists(hash)
的计算结果为false
.存在不满足attribute_not_exists(hash)
条件的键hash=A,range=1
的项.如果您尝试使用
hash=A,range=1
和attribute_not_exists(range)
放置项目,则PutItem
将失败,因为attribute_not_exists(range)
的计算结果为false
.存在不满足attribute_not_exists(range)
条件的键hash=A,range=1
的项.
这意味着会发生以下两种情况之一:
hash
+range
对存在于数据库中.attribute_not_exists(hash)
必须为true
attribute_not_exists(range)
必须为true
hash
+range
对在数据库中不存在.attribute_not_exists(hash)
必须为false
attribute_not_exists(range)
必须为false
在这两种情况下,无论将其放在散列键还是范围键上,都会得到相同的结果.hash
+range
键标识整个表中的单个项目,并且您的条件正在对该项目进行评估.
您实际上是在执行 如果具有此 hash
+range
键的项目尚不存在,则放置该项目".p>
Here are my use cases: I have a Dynamo table with a hash + range key. When I put new items in the table, I want to do a uniqueness check. Sometimes I want to guarantee that the hash is unique (ignoring the range). Other times I want to allow duplicate hashes, but guarantee that the hash and range combination is unique. How can I accomplish this?
I experimented with attribute_not_exists. It seems to handle the second case, where it checks the hash + key combination. Here's a PHP sample:
$client->putItem(array(
'TableName' => 'test',
'Item' => array(
'hash' => array('S' => 'abcdefg'),
'range' => array('S' => 'some other value'),
'whatever' => array('N' => 233)
),
'ConditionExpression' => 'attribute_not_exists(hash)'
));
Oddly, it doesn't seem to matter if I use attribute_not_exists(hash)
or attribute_not_exists(range)
. They both seem to do exactly the same thing. Is this how it's supposed to work?
Any idea how to handle the case where I only want to check hash
for uniqueness?
You can't. All items in DynamoDB are indexed by either their hash
or hash
+range
(depending on your table).
A sort of summary of what is going on so far:
- A single hash key can have multiple range keys.
- Every item has both a
hash
and arange
key - You are making a
PutItem
request and must provide both thehash
andrange
- You are providing a
ConditionExpression
withattribute_not_exists
on either thehash
orrange
attribute name - The
attribute_not_exists
condition is merely checking if an attribute with that name exists, it doesn't care about the value
Let's walk through an example. Let's start with a hash
+range
key table with this data:
hash=A,range=1
hash=A,range=2
There are four possible cases:
If you try to put an item with
hash=A,range=3
andattribute_not_exists(hash)
, thePutItem
will succeed becauseattribute_not_exists(hash)
evaluates totrue
. No item exists with keyhash=A,range=3
that satisfies the condition ofattribute_not_exists(hash)
.If you try to put an item with
hash=A,range=3
andattribute_not_exists(range)
, thePutItem
will succeed becauseattribute_not_exists(range)
evaluates totrue
. No item exists with keyhash=A,range=3
that satisfies the condition ofattribute_not_exists(range)
.If you try to put an item with
hash=A,range=1
andattribute_not_exists(hash)
, thePutItem
will fail becauseattribute_not_exists(hash)
evaluates tofalse
. An item exists with keyhash=A,range=1
that does not satisfy the condition ofattribute_not_exists(hash)
.If you try to put an item with
hash=A,range=1
andattribute_not_exists(range)
, thePutItem
will fail becauseattribute_not_exists(range)
evaluates tofalse
. An item exists with keyhash=A,range=1
that does not satisfy the condition ofattribute_not_exists(range)
.
This means that one of two things will happen:
- The
hash
+range
pair exists in the database.attribute_not_exists(hash)
must betrue
attribute_not_exists(range)
must betrue
- The
hash
+range
pair does not exist in the database.attribute_not_exists(hash)
must befalse
attribute_not_exists(range)
must befalse
In both cases, you get the same result regardless of whether you put it on the hash or the range key. The hash
+range
key identifies a single item in the entire table, and your condition is being evaluated on that item.
You are effectively performing a "put this item if an item with this hash
+range
key does not already exist".
这篇关于DynamoDB - 如果哈希(或哈希和范围组合)不存在则放置项目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!