一尘不染

设计不重叠的日期时间事件

sql

我有以下问题:

事件有一个“开始”和“结束”时间以及一个数量。我两者都使用MySQL DATETIME。

现在,如果我有一个约束条件说“没有重叠的事件”,我需要进行一些检查等,但是如何设计呢?用户只需要5分钟左右的精度,但是我想用几秒钟来进行计算,因为那是“更简单”
/“更清洁”

如果我有一个事件(A),其起始端为“ YYYY-MM-DD 12:00:00”-“ YYYY-MM-DD 14:00:00”

还有一个

(B)“ YYYY-MM-DD 14:00:00”-“ YYYY-MM-DD 16:15:00”->即使它们都包含14:00:00,它们也不重叠。

为了确定它们确实不重叠,我应该使用

A.end <B.begin等

或者

A.end <= B.begin等,然后进行“修改”,使所有结束时间均为“ DATE HH:MM:00(减去一秒)”,而不是“ DATE
HH:MM:00”,即A.end则应为“ YYYY-MM-DD 13:59:59”,而不是“ YYYY-MM-DD 14:00:00”

第一种是最简单的方法,但是如果我有很多不同的事件并且需要检查我没有“超额预定”,即事件的单个金额没有超过总数(例如:如果每个事件,则它将丢失所有重叠)是预订人数最多的桌子,在任何给定时间我都不能超过桌子总数)


阅读 175

收藏
2021-05-05

共1个答案

一尘不染

在处理日期时间范围时,通常使用开始时包含一个范围,而结束时使用一个不包含范围。例如:

(using ISO8601 formatting)

Start                  End
2013-04-29T01:00:00Z - 2013-04-29T02:00:00Z
2013-04-29T02:00:00Z - 2013-04-29T03:00:00Z

小于或等于开始且大于(但不等于)结束时,该值在范围内。在上面的示例中,02:00属于第二个范围,而不是第一个范围。换一种说法:

Start <= value < End

或等效地,

Start <= value  AND  End > value

在数学中,使用间隔符号,这称为“半开”间隔。

[Start, End)

这总是比使用诸如这样的值的想法更好的方法01:59:59。考虑一下我是否减去End - Start以获得持续时间。我希望答案是一个小时,而不是59分59秒。

大多数示例都使用这些术语Start/End,但有时您会看到Begin/EndStart/Stop。就个人而言,我认为当您具有包含范围/排除范围时,最好使用的一组术语是Start/Until。它具有两个术语均为5个字符,按字母顺序排列并明确表示结束日期是排他性的优点。

另外,在谈论不同事件时,应将时间记录为UTC,以防止在时区周围造成混乱。这对于本地应用程序甚至很重要,因为许多时区都经过夏时制转换。您不希望您在数据库中记录的值是模棱两可的。在MySQL中,您可以使用TIMESTAMP数据类型来确保值存储为UTC,或者,DATETIME如果可以确保在应用程序代码中使用UTC值,则可以使用数据类型。

2021-05-05