database-design - 由两个 ISO 8061 日期组成的复合排序键的 DynamoDB 查询是否返回正确的结果(使用 BETWEEN)?
问题描述
在 DynamoDB 中处理排序键日期对象(ISO 8061 格式)的共识似乎是使用 STRING 键类型,其中查询案例将使用 BETWEEN 比较来查找两个日期之间的结果(也是 ISO 8061),请参阅答案:
我的问题是启用上述功能的 DynamoDB 字符串比较“BETWEEN”的机制是否还允许您查询拼接在一起的两个日期对象(例如:2018-05-01-2018-05-10)作为单个排序键,其中第一个缝合日期总是在第二个缝合日期之前。
经过初步测试后,答案似乎是肯定的,只要您的 BETWEEN 查询也有两个连接的日期,这应该是可能的。
我希望有人可以帮助我弄清楚这是否可以安全/稳定地部署。
在我们进入背景之前,我想我会在这里发布我的测试用例,以明确我在问什么。
给定排序键:2018-05-01-2018-05-25
- 在 2018-05-01-2018-05-20 和 2018-05-01-2018-05-26 之间查询(返回项目)
- 在 2018-05-01-2018-05-20 和 2018-05-01-2018-05-24 之间查询(未找到数据)
- 在 2018-05-01-2018-05-20 和 2018-05-01-2018-05-25 之间查询(返回项目)
- 在 2018-05-02-2018-05-20 和 2018-05-02-2018-05-26 之间查询(未找到数据)
背景
我正在构建一个可查询的航班组合 DynamoDB 表,我希望查询检查出发航班日期是否在某个日期之后以及返回航班是否在某个日期之前。
基本上我的理解是,由于数字从左到右(年-月-日)级联的方式,DynamoDB 中对 ISO 8061 日期的 BETWEEN 查询起作用。如果是这种情况,那么(在我的情况下)将两个日期连接到一个排序键中应该是安全的。
排序键值的表示将是...
- 出发日期1-返回日期2
- 年月日年月日
我正在预先检查数据,以便可以假设出发航班(第一个串联日期)总是在返回航班之前(第二个串联日期),如果它在我们的表中,因此给定一个 BETWEEN 操作,我的假设是这应该成为可能。
我会在进行更多测试后回帖,但我希望有人对 DynamoDB BETWEEN Query 函数在这种情况下如何(以及为什么)工作有更多经验。
解决方案
发布此答案,因为我已经在生产中使用上述内容已有一段时间了。
简短的回答:
有点,取决于你的目标。您可以在 DynamoDB 上的排序键中链接多个 ISO 8061 日期并使用 Between 函数 - 但是第二个日期仍需要通过过滤器运行以确保完美遵守。
更长的例子回答
如果您的目标是使用复合排序键首先减少返回的记录数,然后对其进行过滤——那很好。它实现了限制您需要过滤的记录数量的目标(因为在许多情况下,Sort Key BETWEEN 查询实际上会过滤掉不匹配的垃圾)。
但是,它在所有情况下都不起作用/返回目标结果。
因此,对于 DyanmoDB 中的示例数据(排序键):2018-09-01_2018-09-07
我们的目标是仅返回开始日期(在示例中为 2018-09-01)和结束日期(在上述示例中为 2018-09-07)都在范围内的数据我们之间的查询。
返回上述数据对象的简单示例查询是:
Between 2018-08-15_2018-09-07 and 2018-09-05_2018-09-08
起初,查询似乎有效(如我原来的问题中所述),因为上述确实返回了示例数据。 问题是情况并非总是如此。
打破示例排序键
上述查询将返回但实际上不符合我们查询意图的目标开始/结束日期的复合 ISO 8061 排序键日期示例如下:
2018-09-04_2018-09-15
虽然初始开始日期在我们的目标范围内 - 开始日期小于开始日期最大值 (2018-09-05) 的事实导致结束日期允许超过我们理想的结束日期最大值 - 因为总数是仍然小于我们的最大值。
这是因为 DynamoDB 如何看待查询之间的......
DynamoDB 之间的逻辑注释
DynamoDB 基本上将 ISO 8061 日期视为同一日期的数字表示,不带破折号。所以 2018-09-01 = 20180901。由于 ISO 8061 日期从最大到最小级联,因此它们中的两个一起看起来(对于 Dynamo)如下所示:2018090120180907。
一旦它删除了彼此匹配的字符,它就会对大于/小于的数字进行简单的比较。
还是有用的?
因此,如前所述,您确实获得了您不希望从 Between 查询返回的数据,这些数据适用于将两个(或更多)ISO 8061 日期连接在一起的复合排序键。但是,如果您的目标是首先减少返回的记录数量以便更有效地过滤 - 那么这仍然是一件好事(取决于您的用例)。
您只需要计划还针对返回的查询数据运行过滤器,以确保所有日期都在范围内。
推荐阅读
- tensorflow - 简单自定义层无法在简单模型中构建
- html - 如何在投票按钮下方定位投票计数?
- ios - “if #available(iOS 13.0, *)”是如何实现的,对运行时有什么影响?
- javascript - 使用 JavaScript 在 Html 中动态添加单选和下拉列表并返回数据
- c++ - glew和glfw的opengl初始化问题
- angular - Firebase 云消息传递 fcm_options.link 网址在点击时未打开
- java - 在 Websphere 8.0.0.13 中设置 Oracle JDBC 提供程序
- javascript - Vue.js - 点击跨度也点击输入。如何防止?
- javascript - 使用动态 URL 查询参数提供静态目录
- django - Django:覆盖表单。如何缩短字段的映射?