扫描与查询
了解 Scan 和 Query 命令是什么,以及它们如何帮助我们搜索信息。
在 DynamoDB 中,有多种方式可以执行查询。其中一些方法比其他方法更高效,资源消耗也更少。在本课程中,我们将介绍两种最常用的查询形式,用于从 DynamoDB 获取信息。
什么是 Scan?
Scan 是一种可以在 DynamoDB 中执行的操作,用于获取表中的数据。通过 Scan,可以获取存储的所有记录。对于来自 SQL 环境的用户来说,这类似于执行 select * from table_name。如你所见,这种方式会读取表中所有存储的记录,因此在数据量较大的数据库中使用非常危险,可能对性能和成本造成严重影响。需要记住的是,DynamoDB 的吞吐量是按 RCUs(读容量单位)进行配置的。因此,在生产环境中应尽量避免使用此命令。
此外,还可以通过使用 filterExpressions 命令来筛选所需的信息。然而,问题在于,最终仍然会遍历整个表。唯一的区别是,返回的结果不会包含所有存储的数据,而仅包含符合过滤条件的数据。
如上图所示,整个表都会被访问,但只有满足 filterExpressions 中指定条件的特定记录才会被选中。
注意事项
第一个需要注意的是,该命令可以从任何来源执行,例如:通过集成在组件中的 SDK、AWS CLI,或直接通过 AWS 管理控制台。
第二个注意事项是,可以通过多线程并行执行此命令。基本上,可以同时运行多个线程查询数据库,以优化响应时间。在需要极短响应时间的场景下,这是一种非常有效的解决方案。
最后一个注意事项是,无论查询需要返回多少条记录,DynamoDB 每次最多只返回 1 MB 的数据。如果返回的数据超过 1 MB,则必须采用一种称为分页的策略。我们将在后续课程中详细介绍这一机制。
1aws dynamodb create-table \ 2 --table-name table-scan-cli \ 3 --attribute-definitions AttributeName=partitionkey,AttributeType=S AttributeName=rangeKey,AttributeType=S \ 4 --key-schema AttributeName=partitionkey,KeyType=HASH AttributeName=rangeKey,KeyType=RANGE \ 5 --provisioned-throughput ReadCapacityUnits=1,WriteCapacityUnits=1
1aws dynamodb put-item \ 2 --table-name table-scan-cli \ 3 --item '{"partitionkey": {"S": "123"},"rangeKey": {"S": "2022"}}'
1aws dynamodb scan \ 2 --table-name table-scan-cli \ 3 --filter-expression "rangeKey = :rangek" \ 4 --expression-attribute-values '{":rangek":{"S":"2022"}}'
什么是 Query?
除了 Scan,还有 Query 命令,它同样允许从 DynamoDB 获取数据集,但不同之处在于,它必须提供分区键。之所以如此,是因为 DynamoDB 会根据分区键定位特定分区中的记录或记录组。
需要牢记的是,DynamoDB 将数据存储在分区中,而分区键能够以 O(1) 的时间复杂度快速定位记录所在的位置。
上图展示了一个表中的若干记录。在此例中,正在查找键为 8 且 attr1 为 5 的记录。
与 Scan 类似,Query 命令也支持对返回的记录组进行过滤。具体有两种方式:
- 范围键:利用范围键,DynamoDB 可以在某个分区中筛选记录,并仅返回匹配该范围键的记录。
conditionExpressions:通过此命令,可以根据表中任意属性进行过滤,所有满足条件的记录都将被返回。
注意事项
必须设计合理的数据模型,使得记录能通过其分区键快速识别,因为分区键是查询记录的必要条件。
另外值得一提的是,如果表中存在全局二级索引(GSI),也可以在该索引上执行 Query 操作。此时需注意,实际上是在查询一个与主表不同的“备选表”,其分区键与原表不同。
1aws dynamodb create-table \ 2 --table-name table-query-cli \ 3 --attribute-definitions AttributeName=partitionkey,AttributeType=S AttributeName=rangeKey,AttributeType=S \ 4 --key-schema AttributeName=partitionkey,KeyType=HASH AttributeName=rangeKey,KeyType=RANGE \ 5 --provisioned-throughput ReadCapacityUnits=1,WriteCapacityUnits=1
1aws dynamodb put-item \ 2 --table-name table-query-cli \ 3 --item '{"partitionkey": {"S": "123"},"rangeKey": {"S": "2022"}}'
1aws dynamodb query \ 2 --table-name table-query-cli \ 3 --key-condition-expression "partitionkey = :myId" \ 4 --expression-attribute-values '{":myId": {"S": "123"}}'
核心要点
在查询数据库以获取数据组时,主要有两种方式:第一种是使用 Scan 命令,它会读取表中的全部数据;第二种是使用 Query 命令,它根据分区键精准定位并读取特定的数据组。