我应该在向 DynamoDB 添加项目时使用 put 还是 update 命令 table
Should I use put or update command while adding an item to DynamoDB table
以 year
作为主键且项目为:
let item = {
"year": 2021,
"title": "Title A"
}
我可以继续使用 put
方法将其添加到 DynamoDB:
var AWS = require('aws-sdk');
AWS.config.update({region: "us-east-1"});
const docClient = new DynamoDB.DocumentClient();
var params = {
TableName: TABLE_NAME,
Item: item,
ConditionExpression: "year <> :year",
ExpressionAttributeValues: {":year": 2021}
};
let promise = docClient.put(params).promise();
promise.then(res => {
console.log("res:", res);
});
请注意,我在这里使用 ConditionExpression
以确保 table 中不存在具有相同主键 year
2021 的项目。如果该项目存在,我将得到错误。否则,将添加该项目并返回空字典。
我可以使用 update
命令获得相同的功能,而不是使用 put
方法,例如:
let params = {
TableName: TABLE_NAME,
Key: {"year": year},
UpdateExpression: "SET year=:year",
ExpressionAttributeValues: {":year": year},
ConditionExpression: "year <> :year"
};
let promise = docClient.update(params).promise();
promise.then(res => {
console.log("res:", res);
});
虽然 put
和 update
命令都能很好地完成工作,但我更喜欢 update
命令,因为它允许我指定“ALL_NEW”作为 ReturnValues
参数的参数(对于 put
命令,选项“ALL_NEW”不可用)。
与 put
相比,使用 update
命令是否有任何性能下降?为什么我应该使用 put
而不是 update
?
没有性能差异,但在吞吐量方面存在差异。
PutItem - 将单个项目写入 table。如果 table 中存在具有相同主键的项目,则该操作将替换该项目。对于计算预配置的吞吐量消耗,重要的项目大小是两者中较大的一个。
UpdateItem - 修改 table 中的单个项目。 DynamoDB 会考虑项目在更新前后出现的大小。消耗的预配置吞吐量反映了这些项目大小中较大的一个。即使您只更新项目属性的一个子集,UpdateItem 仍会消耗全部预配吞吐量(“之前”和“之后”项目大小中的较大者)。
以上引自AWS官方文档(见参考资料)
然而一切都取决于你在做什么:
PUT 项目替换 DynamoDB 中的整个条目。
UPDATE 只能更新单个属性。您也可以使用 PUT 更新属性。
单个属性UPDATE == GET -> 在代码中修改单个属性 -> PUT记录数据到DB
参考文献:
简而言之,在这种特殊情况下,没有区别。
当项目不存在于 table 中时,put
和 update
具有相同的行为。关于@Daniel Hornik 提到的吞吐量差异,我不同意。在这种情况下,它们都使用相同的 WCU。因此,如果您使用预配置的写入吞吐量,您可以获得相同级别的吞吐量。
对我来说主要区别在于您可以添加 ConditionExpression,这样您就不会不小心覆盖已经存在的密钥。示例:
table.update_item(
Key={
'ID': '1'
},
UpdateExpression='SET #a= :a, #b= :b',
ConditionExpression='attribute_exists(ID)',
ExpressionAttributeValues={
':a': json.dumps(payload),
':b': str(datetime.now())
},
ExpressionAttributeNames={
'#a': 'attribute1',
'#b': 'attribute2'
},
ReturnValues='ALL_NEW'
)
此示例将仅在项目实际存在时执行更新。您可以将其更改为 attribute_not_exists(ID) 以仅在该键不存在时插入。我觉得这可以让您更好地控制 when/when 而不是将数据推送到您的 table.
以 year
作为主键且项目为:
let item = {
"year": 2021,
"title": "Title A"
}
我可以继续使用 put
方法将其添加到 DynamoDB:
var AWS = require('aws-sdk');
AWS.config.update({region: "us-east-1"});
const docClient = new DynamoDB.DocumentClient();
var params = {
TableName: TABLE_NAME,
Item: item,
ConditionExpression: "year <> :year",
ExpressionAttributeValues: {":year": 2021}
};
let promise = docClient.put(params).promise();
promise.then(res => {
console.log("res:", res);
});
请注意,我在这里使用 ConditionExpression
以确保 table 中不存在具有相同主键 year
2021 的项目。如果该项目存在,我将得到错误。否则,将添加该项目并返回空字典。
我可以使用 update
命令获得相同的功能,而不是使用 put
方法,例如:
let params = {
TableName: TABLE_NAME,
Key: {"year": year},
UpdateExpression: "SET year=:year",
ExpressionAttributeValues: {":year": year},
ConditionExpression: "year <> :year"
};
let promise = docClient.update(params).promise();
promise.then(res => {
console.log("res:", res);
});
虽然 put
和 update
命令都能很好地完成工作,但我更喜欢 update
命令,因为它允许我指定“ALL_NEW”作为 ReturnValues
参数的参数(对于 put
命令,选项“ALL_NEW”不可用)。
与 put
相比,使用 update
命令是否有任何性能下降?为什么我应该使用 put
而不是 update
?
没有性能差异,但在吞吐量方面存在差异。
PutItem - 将单个项目写入 table。如果 table 中存在具有相同主键的项目,则该操作将替换该项目。对于计算预配置的吞吐量消耗,重要的项目大小是两者中较大的一个。
UpdateItem - 修改 table 中的单个项目。 DynamoDB 会考虑项目在更新前后出现的大小。消耗的预配置吞吐量反映了这些项目大小中较大的一个。即使您只更新项目属性的一个子集,UpdateItem 仍会消耗全部预配吞吐量(“之前”和“之后”项目大小中的较大者)。
以上引自AWS官方文档(见参考资料)
然而一切都取决于你在做什么:
PUT 项目替换 DynamoDB 中的整个条目。 UPDATE 只能更新单个属性。您也可以使用 PUT 更新属性。
单个属性UPDATE == GET -> 在代码中修改单个属性 -> PUT记录数据到DB
参考文献:
简而言之,在这种特殊情况下,没有区别。
当项目不存在于 table 中时,put
和 update
具有相同的行为。关于@Daniel Hornik 提到的吞吐量差异,我不同意。在这种情况下,它们都使用相同的 WCU。因此,如果您使用预配置的写入吞吐量,您可以获得相同级别的吞吐量。
对我来说主要区别在于您可以添加 ConditionExpression,这样您就不会不小心覆盖已经存在的密钥。示例:
table.update_item(
Key={
'ID': '1'
},
UpdateExpression='SET #a= :a, #b= :b',
ConditionExpression='attribute_exists(ID)',
ExpressionAttributeValues={
':a': json.dumps(payload),
':b': str(datetime.now())
},
ExpressionAttributeNames={
'#a': 'attribute1',
'#b': 'attribute2'
},
ReturnValues='ALL_NEW'
)
此示例将仅在项目实际存在时执行更新。您可以将其更改为 attribute_not_exists(ID) 以仅在该键不存在时插入。我觉得这可以让您更好地控制 when/when 而不是将数据推送到您的 table.