amazon-dynamodb - DynamoDB 如何查询重叠的时间范围
问题描述
考虑一个 DynamoDB 表,该表由一个主键和两个描述开始日期和结束日期的属性组成。如何在不扫描整个表的情况下查询一个时间范围是否与表中的时间范围重叠?
示例:发电机表有两条记录
PK Start End
A 2019-01-01 2019-10-01
B 2019-06-01 2019-08-01
查询哪些记录与时间范围 2018-02-01 到 2019-03-01 重叠。
解决方案
免责声明:这个答案是有缺陷的,并且没有考虑从查询范围内开始但在查询范围之外结束的范围,或者大于查询范围的范围。
如您所知,DynamoDB 无法在查询中使用多个索引。
在大多数数据库中,您可以在“开始”和“结束”列上放置索引,数据库引擎将能够相当快速地确定匹配记录的交集。
代替此功能,我们需要一种将范围信息编码为单个可索引字段的方法。
做到这一点的方法是利用“Z-order indexing”。
Z 顺序索引是一种编码多维信息的方法。
Z 顺序索引以及如何将其应用于 DynamoDB,在这篇亚马逊博客文章第 1部分和第 2部分中有详细描述。
本质上,它的工作方式是通过交织来自您要查询的字段的数据,您可以在二进制级别执行此操作,或者也可以在字符串级别执行此操作。
它可以应用于日期范围字符串的一种基本方法是将您的范围“20190101”到“20191001”交错到单个字段“2200119901100011”中
start end interleaved
20190101 20191001 2200119901100011
20190601 20190801 2200119900680011
然后查询“20190502”和“20190905”之间的日期,使用两个日期之间的公共前缀,在结束范围中添加一个(使用二进制表示的逻辑更简单)。
interleaved BETWEEN "22001199005" AND "2200119901" AND start >= "20190502" AND end < "20190905"
请注意,单独使用交错索引仍然是近似的,您仍然需要为开始和结束范围定义明确的条件。
但是,这种方法避免了扫描整个表。
当然,如果你查询一个很大的日期范围,无论如何它可能最终会查询整个表,范围越小,索引的效率就越高。
推荐阅读
- performance - 带有 v-for 的 Vue 组件渲染和加载第一个字节非常慢
- python - 如何在 python 中使用 pandas 以特定方式从数据框中选择数据
- java - 从 Apache Beam(GCP 数据流)写入 ConfluentCloud
- java - 将 JAXB 与 AutoValue 结合使用时,编组错误“没有无参数默认构造函数”
- laravel - file_exists():open_basedir 限制生效。文件 (/tmp) 不在允许的路径内
- java - 如何从firebase在textview中显示数据
- ios - 用图案图像填充多个 UIBezierPath
- android - 如何在 Exo 播放器中播放这样的 http 文件?
- mongodb - MongoDB和Mongo图表:如何计算数组中前一项的增量?
- continuous-integration - Gitlab CI/CD 管道。推入某个文件夹执行相关阶段