DynamoDB - Put item if hash (or hash and range combination) doesn't exist

匿名 (未验证) 提交于 2019-12-03 01:48:02

问题:

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?

回答1:

You can't. All items in DynamoDB are indexed by either their hash or hash+range (depending on your table). A single hash key can have multiple range keys.

Say for example you have the following items:

  1. hash=A,range=1
  2. hash=A,range=2

You have 2 possible outcomes:

  1. If you try to put an item with hash=A,range=3 and attribute_not_exists(hash), you will get true. There is no item with hash=A,range=3 that exists that has an attribute named hash. If instead you use attribute_not_exists(range) there is no item with hash=A,range=3 that exists that has an attribute named range so you will also get true.

  2. If you try to put an item with hash=A,range=1 and attribute_not_exists(hash), you will get false there is an item with hash=A,range=3 that exists that has an attribute named hash. If instead you use attribute_not_exists(range) there is an item with hash=A,range=3 that exists that has an attribute named range.

What this attribute_not_exist is effectively doing for both of these is a does the item not exist check.


More in depth explanation:

  • Every item has both a hash and a range key
  • You are making a PutItem request and must provide both the hash and range
  • You are providing a ConditionExpression with attribute_not_exists on either the hash or range key

This means that one of two things will happen:

  1. The hash+range pair exists in the database.
    • attribute_not_exists(hash) must be true
    • attribute_not_exists(range) must be true
  2. The 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. You are effectively checking does an item with this hash+range key already exist.



回答2:

You can use AND operation if your table has hash and range

'ConditionExpression' => 'attribute_not_exists(hash) AND attribute_not_exists(range)'



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!