【问题标题】:DynamoDB How to query overlapping time rangesDynamoDB 如何查询重叠的时间范围
【发布时间】:2020-04-21 05:25:34
【问题描述】:

考虑一个 DynamoDB 表,该表由一个主键和两个描述开始日期和结束日期的属性组成。如何在不扫描整个表的情况下查询一个时间范围是否与表中的时间范围重叠?

示例: 发电机表有两条记录

PK  Start        End
A   2019-01-01   2019-10-01
B   2019-06-01   2019-08-01

查询哪些记录与时间范围 2018-02-01 到 2019-03-01 重叠。

【问题讨论】:

  • 到目前为止我所读到的所有内容都表明这是不可能的。并且为此的索引需要使用二进制空间分区(间隔分区),而这对于 b-tree 是不可能的。 ??????

标签: amazon-dynamodb


【解决方案1】:

免责声明:这个答案是有缺陷的,并且没有考虑从查询范围内开始但在查询范围外结束的范围,或者大于查询范围的范围。

您无疑知道,DynamoDB 无法在查询中使用多个索引。
在大多数数据库中,您可以在“开始”和“结束”列上放置索引,数据库引擎将能够相当快速地确定匹配记录的交集。

我们需要一种将范围信息编码为单个可索引字段的方法来代替此功能。

这样做的方法是利用“Z 顺序索引”。
Z-order indexing是一种编码多维信息的方式。

Z 顺序索引以及如何将其应用于 DynamoDB,在这篇亚马逊博文part onepart two 中有详细描述。

基本上它的工作方式是通过交错来自您要查询的字段的数据,您可以在二进制级别执行此操作,也可以在字符串级别执行此操作。
它可以应用于日期范围字符串的一种基本方法是将范围“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"

请注意,单独使用交错索引仍然是近似值,您仍然需要为开始和结束范围定义明确的条件。
但是,这种方法避免了扫描整个表。
当然,如果你查询一个很大的日期范围,无论如何它可能最终会查询整个表,范围越小索引效率越高。

【讨论】:

  • 这简直太棒了
  • 我认为这个查询将很好地解释包含在查询范围内的范围。但是,您如何解释从查询范围内开始但在查询范围外结束的范围?甚至比查询范围更大的范围? @马格努斯
  • 我想您可以对查询的开始位置或结束位置进行位掩码,然后将其插入公式query.start &lt; item.end and item.start &lt; query.end
  • @david_adler 好问题,我没有弄清楚那个问题的答案,最终在我调查这个问题时最终没有使用 Z 顺序索引,如果你发现我很想知道的好解决方案。现在我已经在答案前面添加了关于这种方法的局限性的免责声明。
  • 我的用例比原始问题更受限制。我正在日历中搜索事件。大多数事件只发生在一天,我只需要按天、按周或按月查询。我将每个事件都表示为Year + MonthInYear + WeekInMonth + DayInWeek。如果一个事件是多天的,我会创建多行。如果一个事件发生在跨越两个月的一周,我会为该事件创建两行。然后我可以使用 query+beginsWith 搜索。例如按月查询2021-07、按周查询2021-07-4(7 月第4 周)、按天查询2021-07-4-1(7 月第4 周第2 天与2021-08-0-1 相同)。
【解决方案2】:

老实说,我不确定 DynamoDB 是否是此类用例的正确解决方案

【讨论】:

  • 我同意在关系数据库中执行此操作要容易得多。但从 aws reinvent 关于 Dynamodb 的高级设计模式 (youtube.com/watch?v=6yqfmXiZTlM) 的演讲中,他们一直在说,仅仅因为这不是关系数据库并不意味着您不能在其上运行关系工作负载。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多