DynamoDB - 如果哈希(或哈希和范围组合)不存在则放置项目 [英] DynamoDB - Put item if hash (or hash and range combination) doesn't exist

查看:12
本文介绍了DynamoDB - 如果哈希(或哈希和范围组合)不存在则放置项目的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我的用例:我有一个带有哈希 + 范围键的 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 中的所有项目都由它们的 hashhash+range 索引(取决于您的表).

对目前正在发生的事情的一种总结:

  • 一个哈希键可以有多个范围键.
  • 每个项目都有一个 hash 和一个 range
  • 您正在发出 PutItem 请求并且必须同时提供 hashrange
  • 您在 hashrange 属性名称上提供带有 attribute_not_existsConditionExpression
  • attribute_not_exists 条件只是检查具有该名称的属性是否存在,它不关心值

让我们看一个例子.让我们从包含以下数据的 hash+range 键表开始:

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

有四种可能的情况:

  1. 如果您尝试使用 hash=A,range=3attribute_not_exists(hash) 放置项目,则 PutItem将成功,因为 attribute_not_exists(hash) 的计算结果为 true.不存在键 hash=A,range=3 满足 attribute_not_exists(hash) 条件的项.

  2. 如果您尝试使用 hash=A,range=3attribute_not_exists(range) 放置项目,则 PutItem将成功,因为 attribute_not_exists(range) 的计算结果为 true.不存在键 hash=A,range=3 满足 attribute_not_exists(range) 条件的项.

  3. 如果您尝试使用 hash=A,range=1attribute_not_exists(hash) 放置项目,则 PutItem将失败,因为 attribute_not_exists(hash) 的计算结果为 false.存在不满足 attribute_not_exists(hash) 条件的键 hash=A,range=1 的项.

  4. 如果您尝试使用 hash=A,range=1attribute_not_exists(range) 放置项目,则 PutItem将失败,因为 attribute_not_exists(range) 的计算结果为 false.存在不满足 attribute_not_exists(range) 条件的键 hash=A,range=1 的项.

这意味着会发生以下两种情况之一:

  1. hash+range 对存在于数据库中.
    • attribute_not_exists(hash) 必须为 true
    • attribute_not_exists(range) 必须为 true
  2. 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 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 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:

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

There are four possible cases:

  1. 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).

  2. 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).

  3. 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).

  4. 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:

  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. 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆