更新时间:2023-12-02 18:20:34
你不能.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:
hash
and a range
keyPutItem
request and must provide both the hash
and range
ConditionExpression
with attribute_not_exists
on either the hash
or range
attribute nameattribute_not_exists
condition is merely checking if an attribute with that name exists, it doesn't care about the valueLet'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
and attribute_not_exists(hash)
, the PutItem
will succeed because attribute_not_exists(hash)
evaluates to true
. No item exists with key hash=A,range=3
that satisfies the condition of attribute_not_exists(hash)
.
If you try to put an item with hash=A,range=3
and attribute_not_exists(range)
, the PutItem
will succeed because attribute_not_exists(range)
evaluates to true
. No item exists with key hash=A,range=3
that satisfies the condition of attribute_not_exists(range)
.
If you try to put an item with hash=A,range=1
and attribute_not_exists(hash)
, the PutItem
will fail because attribute_not_exists(hash)
evaluates to false
. An item exists with key hash=A,range=1
that does not satisfy the condition of attribute_not_exists(hash)
.
If you try to put an item with hash=A,range=1
and attribute_not_exists(range)
, the PutItem
will fail because attribute_not_exists(range)
evaluates to false
. An item exists with key hash=A,range=1
that does not satisfy the condition of attribute_not_exists(range)
.
This means that one of two things will happen:
hash
+range
pair exists in the database.
attribute_not_exists(hash)
must be true
attribute_not_exists(range)
must be true
hash
+range
pair does not exist in the database.
attribute_not_exists(hash)
must be false
attribute_not_exists(range)
must be false
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".