因此,如果您使用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.com' }
};
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.com' }
};
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):
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:
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.
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中的预期约束以防止重复的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!