dynamodb 中的预期约束以防止重复 [英] Expected constraint in dynamodb to prevent duplicates

查看:24
本文介绍了dynamodb 中的预期约束以防止重复的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是 DynamoDB 的新手,无法让以下场景在 node.js 和 DynamoDB 中工作:

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.com' }
};

dynamodb.putItem({
    TableName: 'user',
    Item: item,
    Expected: {
        email: { Exists: false }
    }
}, function (err, data) {
    if (err) {
        return callback(err);
    }
    callback();
});

我假设 Expected 值会通过引发 ConditionalCheckFailedException 错误来防止用户表中出现重复的电子邮件地址.不是这种情况;上面的代码将一致地插入重复的电子邮件.我尝试将id"添加为额外的预期字段,但这并没有改变行为.

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.

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

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.com' }
};

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

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

这种行为让我相信约束仅适用于使用散列键指定的记录.如果是这种情况,AWS 文档确实会非常混乱(我用粗体突出了让我感到困惑的地方):

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):

如果 Exists 为 false,Amazon DynamoDB 会假定属性值在表中不存在.如果实际上该值不存在,则假设有效并且操作成功.如果找到该值,尽管假设它不存在,操作将失败并出现 ConditionalCheckFailedException.

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!

编辑 2013-11-09

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

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

感谢您的帮助!

推荐答案

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

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:

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

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

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

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

所以 Expected 条件确实有效,但是表中哈希键为 7f224b97-c144-4df2-bc3e-cfba69d5bc6e 的其他项没有 Range 键 = my@email.com,并且 put 项成功.

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.com, and the put item succeeds.

如果你真的要保证用户邮件的唯一性,你应该把它作为表的Hash key.当您想要查询用户时,它也会让您更轻松:您可能知道,要在 DynamoDB 中执行查询,您必须指定要查询的哈希键的确切值,如果您不知道该值对于您要查找的哈希键,您将不得不执行表扫描(效率低得多).

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

因此,如果您使用 uuid 作为哈希键,则必须使用表扫描检索用户(我假设您不知道与要从 DB 检索的用户关联的 uuid).如果您使用用户邮件作为哈希键,您将能够使用查询来检索它们.

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.

希望对你有帮助!

这篇关于dynamodb 中的预期约束以防止重复的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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