无服务器:定义 dynamoDB table 以跨 2 个范围键进行高效扫描
Serverless: Define dynamoDB table for efficient scans across 2 range keys
我正在尝试定义一个 dynamodb table,以便我可以根据多个范围轻松地过滤它(date
和 type
都被认为是唯一的)。我最终得到了以下架构(从 中窃取),但它似乎对于主要用例(按 2 个范围过滤后返回数据)来说并不是特别有效。
将type
设为主要table的范围并将date
设置为localSecondaryIndex是否更好。或者是否有另一种方法可以保持与 GSI 相关的灵活性。
Properties:
TableName: TableName
AttributeDefinitions:
- AttributeName: id
AttributeType: S
- AttributeName: date
AttributeType: S
- AttributeName: type
AttributeType: S
KeySchema:
- AttributeName: id
KeyType: HASH
GlobalSecondaryIndexes:
- IndexName: dateIndex
KeySchema:
- AttributeName: date
KeyType: HASH
Projection:
ProjectionType: KEYS_ONLY
ProvisionedThroughput:
ReadCapacityUnits: 100
WriteCapacityUnits: 100
- IndexName: typeIndex
KeySchema:
- AttributeName: type
KeyType: HASH
Projection:
ProjectionType: KEYS_ONLY
ProvisionedThroughput:
ReadCapacityUnits: 100
WriteCapacityUnits: 100
ProvisionedThroughput:
ReadCapacityUnits: 100
WriteCapacityUnits: 100
如果您要检索非常大的“日期”范围和多个不同的“类型”,在某些情况下,完整扫描可能会有用。但是,使用查询操作和适当的 GSI 可能比完全扫描更好地检索您正在谈论的属性。
选项 1) GSI,“类型”作为哈希键,“日期”作为范围键
这是您尝试执行的操作的通用解决方案。您需要知道您尝试查找给定日期范围的“类型”。范围键上的关键条件将用于匹配您的日期范围。如果您需要在一个日期范围内查询多个“类型”,那么您将执行多个查询操作(每个“类型”一个)。
选项 2) 聚合列“TypeWithDate”上的 GSI
创建一个 GSI,将新属性“TypeWithDate”作为哈希键,该哈希键是“类型”和“日期”的串联(例如“mytype#2020-07-17”)。直接查询匹配键的数据。如果您要搜索的“日期”范围数量有限,或者您要查找的日期范围是零散的,则此方法有效。简单地遍历它们。
选项 3) 客户端过滤
可能效率不高,但可以避免创建额外的 GSI。您将重用上面的“日期”GSI 进行多次查询调用(“日期”中的每一天一次),然后进行客户端过滤以获取“类型”
对于上述所有选项,查询操作可以 return 多条记录,因此需要多次调用才能对所有结果进行分页。如果您的“日期”列也包含时间,那么如果您创建一个单独的没有时间的“日期”列,或者创建一个粒度来权衡您要查询的单个键的数量,那么直接查询“日期”的选项仍然是可能的。例如。 “2020-07-17T14:00:00”可以映射到“2020-07-17.14”小时的日期桶,但这需要每天对选项 2 和 3 进行 24 次查询查找。
我正在尝试定义一个 dynamodb table,以便我可以根据多个范围轻松地过滤它(date
和 type
都被认为是唯一的)。我最终得到了以下架构(从
将type
设为主要table的范围并将date
设置为localSecondaryIndex是否更好。或者是否有另一种方法可以保持与 GSI 相关的灵活性。
Properties:
TableName: TableName
AttributeDefinitions:
- AttributeName: id
AttributeType: S
- AttributeName: date
AttributeType: S
- AttributeName: type
AttributeType: S
KeySchema:
- AttributeName: id
KeyType: HASH
GlobalSecondaryIndexes:
- IndexName: dateIndex
KeySchema:
- AttributeName: date
KeyType: HASH
Projection:
ProjectionType: KEYS_ONLY
ProvisionedThroughput:
ReadCapacityUnits: 100
WriteCapacityUnits: 100
- IndexName: typeIndex
KeySchema:
- AttributeName: type
KeyType: HASH
Projection:
ProjectionType: KEYS_ONLY
ProvisionedThroughput:
ReadCapacityUnits: 100
WriteCapacityUnits: 100
ProvisionedThroughput:
ReadCapacityUnits: 100
WriteCapacityUnits: 100
如果您要检索非常大的“日期”范围和多个不同的“类型”,在某些情况下,完整扫描可能会有用。但是,使用查询操作和适当的 GSI 可能比完全扫描更好地检索您正在谈论的属性。
选项 1) GSI,“类型”作为哈希键,“日期”作为范围键
这是您尝试执行的操作的通用解决方案。您需要知道您尝试查找给定日期范围的“类型”。范围键上的关键条件将用于匹配您的日期范围。如果您需要在一个日期范围内查询多个“类型”,那么您将执行多个查询操作(每个“类型”一个)。
选项 2) 聚合列“TypeWithDate”上的 GSI
创建一个 GSI,将新属性“TypeWithDate”作为哈希键,该哈希键是“类型”和“日期”的串联(例如“mytype#2020-07-17”)。直接查询匹配键的数据。如果您要搜索的“日期”范围数量有限,或者您要查找的日期范围是零散的,则此方法有效。简单地遍历它们。
选项 3) 客户端过滤
可能效率不高,但可以避免创建额外的 GSI。您将重用上面的“日期”GSI 进行多次查询调用(“日期”中的每一天一次),然后进行客户端过滤以获取“类型”
对于上述所有选项,查询操作可以 return 多条记录,因此需要多次调用才能对所有结果进行分页。如果您的“日期”列也包含时间,那么如果您创建一个单独的没有时间的“日期”列,或者创建一个粒度来权衡您要查询的单个键的数量,那么直接查询“日期”的选项仍然是可能的。例如。 “2020-07-17T14:00:00”可以映射到“2020-07-17.14”小时的日期桶,但这需要每天对选项 2 和 3 进行 24 次查询查找。