3

私は DynamoDB を初めて使用し、次のシナリオを node.js と DynamoDB で機能させるのに問題があります。

ユーザー テーブルにユーザーを挿入したいのですが、ユーザーの電子メール アドレスが既に存在する場合は成功させたくありません。

次のコードは、新しいユーザーを正常に挿入できます。

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」を追加の期待フィールドとして追加しようとしましたが、これは動作を変更しませんでした。

生成された UUID ではなく ID が固定されるようにコードを変更すると、ConditionalCheckFailedException が発生します。

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

「id」はハッシュキーで、「email」は範囲キーです。

この動作により、ハッシュ キーで指定されたレコードに対してのみ制約が機能すると考えるようになりました。その場合、AWS のドキュメントは非常に紛らわしいものになります (混乱する箇所を太字で強調しました)。

Exists が false の場合、Amazon DynamoDB は属性値がテーブルに存在しないと想定します。実際に値が存在しない場合、仮定は有効であり、操作は成功します。値が見つかった場合、存在しないという前提にもかかわらず、操作は ConditionalCheckFailedException で失敗します。

ドキュメントが正しいと仮定すると、私は何か間違ったことをしているに違いありませんか? どんな助けでも大歓迎です!

編集 2013-11-09

以下のコメントに基づいて、戦術を変更することにしました。不変ではない他のほとんどのドメイン オブジェクトで参照する必要がある値を使用することに少し気が進まないのです。これで、ユーザー ID のルックアップ/インデックス テーブルとして機能する電子メール アドレス テーブルができました。これにより、ユーザーに自分の電子メール アドレスを非常に簡単に変更させることができます (複数の電子メール アドレスをサポートすることもできます)。

助けてくれてありがとう!

4

1 に答える 1

3

範囲キーを持つ DynamoDB テーブルの項目は、ハッシュ キーと範囲キーの組み合わせであり、mysql での一意 (id、メール) のようなものです。したがって、最初のアプローチでは、電子メールが既にテーブルに存在するユーザーを挿入すると、uuid が完全に異なるため、まったく新しいアイテムが作成されます。

1 番目の項目 -> ハッシュ キー: 7f224b97-c144-4df2-bc3e-cfba69d5bc6e、範囲キー: my@email.com

2 番目の項目 -> ハッシュ キー: 34cc6d26-dce4-4eb4-afec-3a382d9579fc、範囲キー: my@email.com

そのため、期待される条件は実際に機能していますが、ハッシュ キー 7f224b97-c144-4df2-bc3e-cfba69d5bc6e を持つテーブル内の他のアイテムには範囲キー = my@email.com がなく、プット アイテムは成功します。

ユーザーの電子メールの一意性を本当に保証したい場合は、それをテーブルのハッシュ キーとして配置する必要があります。また、ユーザーにクエリを実行する場合も簡単になります。おそらくご存知のように、DynamoDB でクエリを実行するには、値がわからない場合は、クエリするハッシュ キーの正確な値を指定する必要があります。探しているハッシュ キーの場合、テーブル スキャンを実行する必要があります (はるかに非効率的です)。

したがって、uuid をハッシュ キーとして使用する場合は、テーブル スキャンを使用してユーザーを取得する必要があります (DB から取得するユーザーに関連付けられている uuid がわからないことを前提としています)。ユーザー メールをハッシュ キーとして使用すると、クエリを使用してそれらを取得できます。

それが役に立てば幸い!

于 2013-11-08T11:18:33.160 に答える