【问题标题】:Delete large data with same partition key from DynamoDB从 DynamoDB 中删除具有相同分区键的大数据
【发布时间】:2018-09-15 23:15:18
【问题描述】:

我有这样结构的 DynamoDB 表

A   B    C    D
1   id1  foo hi
1   id2  var hello

A 是分区键,B 是排序键。

假设我只有分区键,不知道排序键,我想删除所有具有相同分区键的条目。

所以我正在考虑通过查询加载具有固定大小(例如 1000)的条目并批量删除它们,直到 DynamoDB 中没有更多带有分区键的条目。

是否可以在不加载条目的情况下删除它们?

【问题讨论】:

  • 同样的问题和代码示例stackoverflow.com/a/16552620/8769801
  • 有没有办法删除只有哈希键(没有范围键)的项目?
  • 没有。这是一个肯定缺少的功能。希望在未来。

标签: amazon-dynamodb delete-operator


【解决方案1】:

https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_DeleteItem.html

删除项目

按主键删除表中的单个项目。

对于主键,您必须提供所有属性。为了 例如,使用简单的主键,您只需要提供一个值 为分区键。对于复合主键,您必须提供 分区键和排序键的值。

为了删除一个项目,您必须提供整个主键(分区 + 排序键)。因此,在您的情况下,您需要查询分区键,获取所有主键,然后使用它们删除每个项目。你也可以使用 BatchWriteItem

https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_BatchWriteItem.html

BatchWriteItem

BatchWriteItem 操作将多个项目放入或删除一个或 更多表。对 BatchWriteItem 的一次调用最多可以写入 16 MB 数据,其中可以包含多达 25 个放置或删除请求。 要写入的单个项目可以大到 400 KB。

DeleteRequest - 对指定项目执行 DeleteItem 操作。要删除的项目由 Key 子元素标识: Key - 唯一标识项目的主键属性值映射。 此映射中的每个条目都由一个属性名称和一个属性组成 价值。对于每个主键,您必须提供所有主键 属性。例如,使用简单的主键,您只需要 为分区键提供一个值。 对于复合主键, 您必须为分区键和排序键提供值

【讨论】:

  • 所以答案是否定的。对于复合主键 - 无法删除只有散列(分区)键的项目
  • @codereviewanskquestions 这个问题通常是通过在范围键上执行begins_with="id" 来设计的
【解决方案2】:

您可以在范围键上使用“begins_with”。

例如(伪代码)

DELETE WHERE A = '1' AND B BEGINS_WITH 'id'

【讨论】:

  • 它被否决了,因为问题是关于不使用 SQL 的 DynamoDB。使用 SQL 在这里根本不适用。
  • 也不能删除begins_with的项目,它只对查询可用。
【解决方案3】:

对于生产数据库和关键的 Amazon DynamoDB 表,建议使用批处理写入项来清除大量数据。

batch-write-item(使用 DeleteRequest)比 delete-item 快 10 到 15 倍。

aws dynamodb scan --table-name "test_table_name" --projection-expression "primary_key, timestamp" --filter-expression "timestamp < :oldest_date" --expression-attribute-values '{":oldest_date":{"S":"2020-02-01"}}' --max-items 25 --total-segments "$TOTAL_SEGMENT" --segment "$SEGMENT_NUMBER" > $SCAN_OUTPUT_FILE

cat $SCAN_OUTPUT_FILE | jq -r ".Items[] | tojson" | awk '{ print "{\"DeleteRequest\": {\"Key\": " $0 " }}," }' | sed '$ s/.$//' | sed '1 i { "test_table_name": [' | sed '$ a ] }' > $INPUT_FILE

aws dynamodb batch-write-item --request-items file://$INPUT_FILE

更多信息请查看@https://medium.com/analytics-vidhya/how-to-delete-huge-data-from-dynamodb-table-f3be586c011c

【讨论】:

    【解决方案4】:

    不可以,但您可以查询分区的所有项目,然后为每个项目发出单独的 DeleteRequest,您可以在最多 25 个项目的多个 BatchWrite 调用中批处理。

    JS 代码

    async function deleteItems(tableName, partitionId ) {
      
      const queryParams = {
        TableName: tableName,
        KeyConditionExpression: 'partitionId = :partitionId',
        ExpressionAttributeValues: { ':partitionId': partitionId } ,
      };
    
      const queryResults = await docClient.query(queryParams).promise()
      if (queryResults.Items && queryResults.Items.length > 0) {
        
        const batchCalls = chunks(queryResults.Items, 25).map( async (chunk) => {
          const deleteRequests = chunk.map( item => {
            return {
              DeleteRequest : {
                Key : {
                  'partitionId' : item.partitionId,
                  'sortId' : item.sortId,
    
                }
              }
            }
          })
    
          const batchWriteParams = {
            RequestItems : {
              [tableName] : deleteRequests
            }
          }
          await docClient.batchWrite(batchWriteParams).promise()
        })
    
        await Promise.all(batchCalls)
      }
    }
    
    // https://stackoverflow.com/a/37826698/3221253
    function chunks(inputArray, perChunk) {
      return inputArray.reduce((all,one,i) => {
        const ch = Math.floor(i/perChunk); 
        all[ch] = [].concat((all[ch]||[]),one); 
        return all
     }, [])
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-01-13
      • 1970-01-01
      • 2014-12-15
      • 1970-01-01
      • 1970-01-01
      • 2017-12-06
      • 1970-01-01
      相关资源
      最近更新 更多