简体   繁体   中英

Dynamodb update multiple Data

Suppose this is my DB table

[
{PK:'#author_1', SK: 'author', name: 'aytor'},
{PK:'#author_2', SK: 'author', name: 'ryan'},
{PK:'#book_1', SK: '#author_1', title: 'hello 123', author_name: 'aytor'},
{PK:'#book_2', SK: '#author_1', title: 'hello 456', author_name: 'aytor'},
{PK:'#book_3', SK: '#author_1', title: 'hello 789', author_name: 'aytor'},
 ]

My question is if the admin change author name how can I update all books author name.

Access pattern: get author_pk and update all books where Book SK=author_PK

I'm trying to solve this problem using AWS-SDK for node js

Duplicating data is a fine way to model one-to-many relationships in DynamoDB. However, it can be a less appealing strategy if the data you are duplicating is subject to change. If it's an infrequent operation, like updating the author of a book, it may be an acceptable approach.

With this data model, you'll need to fetch all books by author and manually update the author name of each book. You could either scan the table for all books by this author, or introduce a global secondary index on book items where the index PK = author_id and SK = book_id. That way, you'd be able to query a list of books for each author and issue updates accordingly.

DynamoDB does not offer a batch update operation. However, you can handle the concurrency in your application. With the was node SDK, it would look something like (in pseudocode, I have not tested this)


    const updates = [];
    let new_author_name = "Clancy"
    for (let i = 0; i < books.size; i++) {
        updates.push(ddb.update({
            TableName: 'MY_TABLE',
            Key: { PK: books[i].PK},
            UpdateExpression: 'SET #name = :name',
            ExpressionAttributeValues: {
                ':name': new_author_name
            },
            ExpressionAttributeNames: {
                '#name': 'name'
            }
        }).promise());
    }

    await Promise.all(updates);

The answer @seth-geoghegan gave is correct for the data you have. I wonder if you might want to change your data, however, to allow this to be a little easier. Instead of the book being the PK for book records why not make it the author ? You may still need to add a GSI if you need to get to a book by it's ID, but it would be a query either way (currently you have the book as the PK and the author as the SK , meaning you can't get at a single book using a get without knowing the author too).

[
{PK:'#author_1', SK: 'author', name: 'aytor'},
{PK:'#author_1', SK:'#book_1', title: 'hello 123', author_name: 'aytor'},
{PK:'#author_1', SK:'#book_2', title: 'hello 456', author_name: 'aytor'},
{PK:'#author_1', SK:'#book_3', title: 'hello 789', author_name: 'aytor'},
{PK:'#author_2', SK: 'author', name: 'ryan'},
 ]

This would allow you to query all records for the author and update the author name.

If you still need to query for a book by it's ID just add a GSI for that.

[
{PK:'#author_1', SK: 'author', name: 'aytor'},
{PK:'#author_1', SK:'#book_1', title: 'hello 123', author_name: 'aytor', GSI1PK: '#book_1'},
{PK:'#author_1', SK:'#book_2', title: 'hello 456', author_name: 'aytor', GSI1PK: '#book_2'},
{PK:'#author_1', SK:'#book_3', title: 'hello 789', author_name: 'aytor', GSI1PK: '#book_3'},
{PK:'#author_2', SK: 'author', name: 'ryan'},
 ]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM