dynamodb中的预期约束以防止重复

编程入门 行业动态 更新时间:2024-10-28 12:16:13
本文介绍了dynamodb中的预期约束以防止重复的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我是DynamoDB的新手,我无法在node.js和DynamoDB中使用以下方案:

我想在用户中插入用户表,但是如果用户的电子邮件地址已经存在,我不希望此操作成功。

以下代码能够成功插入新用户:

var项目= { id:{S:uuid.v4()},电子邮件:{S:'my @ email'} }; dynamodb.putItem({ TableName:'user', Item:item,预期:{电子邮件:{存在:false} } },函数(错误,数据){ if(err){ return callback(err); } callback(); });

我认为Expected值会引发ConditionalCheckFailedException错误,从而防止用户表中的电子邮件地址重复。不是这种情况;上面的代码将一致地插入重复的电子邮件。我尝试将 id添加为附加的Expected字段,但这并没有改变行为。

当我修改代码时,确实得到了ConditionalCheckFailedException,因此ID为固定而不是生成的UUID;

var item = { id:{S:'Test'},电子邮件:{S:'my@email'} };

我应该解释一下, id是哈希键, email是范围键。

这种行为使我相信约束仅适用于使用哈希键指定的记录。如果是这样的话,AWS文档的确会非常混乱(我以粗体突出显示了使我感到困惑的地方):

如果Exists存在, Amazon DynamoDB假定表中不存在属性值。。如果实际上该值不存在,则该假设有效,并且操作成功。如果找到该值,则尽管假设该值不存在,但该操作将失败,并显示ConditionalCheckFailedException。

假设文档正确我一定做错了什么?任何帮助将不胜感激!

编辑2013-11-09

根据下面的评论,我决定更改策略。我有点不愿意在其他大多数不变的域对象中使用需要引用的值。我现在有一个电子邮件地址表,可以用作用户ID的查找/索引表。这使我可以让用户非常轻松地更改其电子邮件地址(我什至可以支持多个电子邮件地址)。

感谢帮助!

解决方案

DynamoDB中的项目带有范围键的表是哈希键和范围键的组合,在mysql中是唯一的(id,email)。因此,在第一种方法中,当您插入表中已经存在电子邮件的用户时,您将创建一个全新的项目,因为uuid完全不同:

第一项->哈希键:7f224b97-c144-4df2-bc3e-cfba69d5bc6e,范围键:my@email

第二项->哈希密钥:34cc6d26-dce4-4eb4-afec-3a382d9579fc,范围密钥:my@email

因此,预期条件确实有效,但该表中没有其他具有哈希键7f224b97-c144-4df2-bc3e-cfba69d5bc6e的项目具有Range键= my@email,并且放置项成功。

如果您确实要保证用户电子邮件的唯一性,则应将其作为表的哈希键。当您要查询用户时,这也将使您更轻松:如您所知,要在DynamoDB中执行查询,您必须指定要查询的哈希键的确切值(如果您不知道该值)

因此,如果您使用uuid作为哈希键,则必须执行表扫描(效率要低得多)。将必须使用表扫描来检索您的用户(我假设您不知道与要从数据库检索的用户关联的uuid)。如果您使用用户邮件作为哈希键,则可以使用查询来检索它们。

希望它会有所帮助!

I am new to DynamoDB and I am having trouble getting the following scenario to work in node.js and DynamoDB:

I want to insert a user in a user table but I don't want this to succeed if the user's email address already exists.

The following code is able to successfully insert a new user:

var item = { id: { S: uuid.v4()}, email: { S: 'my@email' } }; dynamodb.putItem({ TableName: 'user', Item: item, Expected: { email: { Exists: false } } }, function (err, data) { if (err) { return callback(err); } callback(); });

I assumed the Expected value would prevent duplicate email addresses in the user's table by raising an ConditionalCheckFailedException error. This is not the case; the code above will insert duplicate emails consistently. I tried adding the 'id' as an additional Expected field but this didn't change the behavior.

I do get a ConditionalCheckFailedException when I modify the code so the ID is fixed rather than a generated UUID;

var item = { id: { S: 'Test' }, email: { S: 'my@email' } };

I should explain, the 'id' is the hash key and 'email' is the range key.

This behavior led me to believe the constraints only work on the record specified with the hash key. If that were the case the AWS documentation would be very confusing indeed (I highlighted in bold what confuses me):

If Exists is false, Amazon DynamoDB assumes that the attribute value does not exist in the table. If in fact the value does not exist, then the assumption is valid and the operation succeeds. If the value is found, despite the assumption that it does not exist, the operation fails with a ConditionalCheckFailedException.

Assuming the documentation is correct I must be doing something wrong? Any help would be much appreciated!

EDIT 2013-11-09

Based on the comment below I decided to change tactics. I'm a bit reluctant to use a value that I need to reference in most other domain objects that isn't immutable. I now have an email address table that acts as a lookup / index table for user ID's. This allows me to have the user change his or her email address quite easily (I could even support multiple email addresses).

Thanks for the help!

解决方案

The items in a DynamoDB table with range key are the combination of hash key and range key, sort of a unique(id, email) in mysql. So in your first approach, when you insert a user who's email already exists in the table, you are creating a whole new item because the uuid is completely different:

1st item -> Hash key: 7f224b97-c144-4df2-bc3e-cfba69d5bc6e, Range key: my@email

2nd item -> Hash key: 34cc6d26-dce4-4eb4-afec-3a382d9579fc, Range key: my@email

So the Expected condition is working indeed, but no other item in the table with the Hash key 7f224b97-c144-4df2-bc3e-cfba69d5bc6e has a Range key = my@email, and the put item succeeds.

If you really want to guarantee the uniqueness of the user's email, you should put it as the Hash key of the table. It will also make things easier to you when you want to query a user: as you probably know, to perform a query in DynamoDB you have to specify the exact value of the hash key you want to query, if you do not know the value of the hash key you are looking for, you will have to perform a table scan (much more inefficient).

So if you use an uuid as a Hash key, you will have to retrieve your users using a table scan (I assume that you don't know the uuid associated to a user you want to retrieve from DB). If you use the user mail as the Hash key, you will be able to retrieve them using queries.

Hope it helps!

更多推荐

dynamodb中的预期约束以防止重复

本文发布于:2023-10-26 21:37:39,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1531419.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:以防止   dynamodb

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!