在向DynamoDB表添加项目时,我应该使用put命令还是update命令?
在向DynamoDB表添加项目时,我应该使用put命令还是update命令?
用于将项目添加到DynamoDB的put
方法中,将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
来确保具有相同主键year
2021的项目在表中不存在。如果项目存在,则会出现错误。否则,项目将被添加,并返回空字典。
除了使用put
方法之外,我还可以使用update
命令来实现相同的功能,例如:
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"不可用)。
在使用update
命令和put
命令之间是否存在性能下降?是否有任何理由我应该使用put
而不是update
?
在向DynamoDB表中添加项目时,我们应该使用put还是update命令?这个问题的出现的原因是因为putItem和updateItem之间在吞吐量方面存在差异。
根据官方AWS文档中的描述,putItem命令是将单个项目写入表中。如果表中已经存在具有相同主键的项目,则该操作将替换该项目。在计算预配置吞吐量消耗时,重要的是考虑项目的大小(取两者中较大的那个)。
而updateItem命令是修改表中的单个项目。DynamoDB会考虑项目在更新之前和之后的大小。消耗的预配置吞吐量反映了这两个项目大小中较大的那个。即使只更新了项目的一部分属性,updateItem仍然会消耗完整的预配置吞吐量(取"之前"和"之后"项目大小中较大的那个)。
根据上述描述,根据具体需求来决定使用哪个命令:
- 如果要替换整个项目,使用putItem命令。
- 如果只想更新单个属性,可以使用updateItem命令。当然,也可以使用putItem命令来更新属性。
参考文献:
- StackOverflow话题:Difference between DynamoDb PutItem vs UpdateItem?
- AWS关于数据消耗的文档:https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ProvisionedThroughput.html
在向DynamoDB表中添加项目时,应该使用put命令还是update命令的问题的出现是因为需要在不意外覆盖已存在的键的情况下添加项目。通过在更新表达式中添加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' )
在这个示例中,只有在项目实际存在时才会执行更新操作。您可以将ConditionExpression更改为attribute_not_exists(ID),以便仅在该键不存在时插入项目。我认为这样可以更好地控制何时/何时不将数据推送到表中。
通过使用ConditionExpression,我们可以根据条件决定是执行更新操作还是插入操作,从而避免意外地覆盖已存在的键。