Dynamodb更新多个数据
Dynamodb update multiple Data
假设这是我的数据库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'},
]
我的问题是,如果 管理员更改作者 姓名,我该如何更新所有书籍的作者姓名。
访问模式:获取 author_pk
并更新 Book SK=author_PK
中的所有书籍
我正在尝试对节点 js
使用 AWS-SDK
来解决这个问题
复制数据是在 DynamoDB 中模拟一对多关系的好方法。但是,如果您正在复制的数据可能会发生变化,那么这可能不是一个吸引人的策略。如果它是一个不频繁的操作,比如更新一本书的作者,它可能是一个 acceptable 方法。
使用此数据模型,您需要按作者获取所有书籍并手动更新每本书的作者姓名。您可以为该作者的所有书籍 scan
table,或者在索引 PK = author_id 和 SK = book_id 的书籍项目上引入全局二级索引。这样,您就可以 query
列出每位作者的书籍并相应地发布更新。
DynamoDB 不提供批量更新操作。但是,您可以在应用程序中处理并发。使用 was 节点 SDK,它看起来像(在伪代码中,我没有测试过)
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);
@seth-geoghegan 给出的答案对于您拥有的数据是正确的。但是,我想知道您是否想更改您的数据,让这更容易一些。为什么不将 book
作为书籍记录的 PK
而不是 author
?如果您需要通过 ID 获取图书,您可能仍需要添加 GSI,但无论哪种方式,它都是 query
(目前您将 book
作为 PK
并且author
与 SK
相同,这意味着您无法在不了解作者的情况下使用 get
阅读一本书。
[
{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'},
]
这将允许您查询作者的所有记录并更新作者姓名。
如果您仍然需要通过 ID 查询图书,只需为此添加一个 GSI。
[
{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'},
]
假设这是我的数据库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'},
]
我的问题是,如果 管理员更改作者 姓名,我该如何更新所有书籍的作者姓名。
访问模式:获取 author_pk
并更新 Book SK=author_PK
我正在尝试对节点 js
AWS-SDK
来解决这个问题
复制数据是在 DynamoDB 中模拟一对多关系的好方法。但是,如果您正在复制的数据可能会发生变化,那么这可能不是一个吸引人的策略。如果它是一个不频繁的操作,比如更新一本书的作者,它可能是一个 acceptable 方法。
使用此数据模型,您需要按作者获取所有书籍并手动更新每本书的作者姓名。您可以为该作者的所有书籍 scan
table,或者在索引 PK = author_id 和 SK = book_id 的书籍项目上引入全局二级索引。这样,您就可以 query
列出每位作者的书籍并相应地发布更新。
DynamoDB 不提供批量更新操作。但是,您可以在应用程序中处理并发。使用 was 节点 SDK,它看起来像(在伪代码中,我没有测试过)
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);
@seth-geoghegan 给出的答案对于您拥有的数据是正确的。但是,我想知道您是否想更改您的数据,让这更容易一些。为什么不将 book
作为书籍记录的 PK
而不是 author
?如果您需要通过 ID 获取图书,您可能仍需要添加 GSI,但无论哪种方式,它都是 query
(目前您将 book
作为 PK
并且author
与 SK
相同,这意味着您无法在不了解作者的情况下使用 get
阅读一本书。
[
{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'},
]
这将允许您查询作者的所有记录并更新作者姓名。
如果您仍然需要通过 ID 查询图书,只需为此添加一个 GSI。
[
{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'},
]