PHP / MySQL:对数据库中的重复事件进行建模,但查询日期范围

Pez*_*kow 5 php mysql database

我正在开发一个(我打算成为)简单的PHP / MySQL应用程序。作为其一部分,我希望能够对重复事件进行建模,但是我需要能够查询两个日期之间发生的所有事件(包括重复事件)。事件只有一个日期,一天中的时间无关紧要。

我一直在对此进行研究,并研究了各种方法,包括 日历重复/重复事件-最佳存储方法重复日历事件以及一些最终的数学方法

但是,我在网上找到的任何支持此功能的数据库架构示例都似乎仅支持查询某天发生的事件。不支持在日期范围之间发生的事件。

作为一个抽象的例子

事件表(具有某种重复表示):

Event   | Start Date   |   Repeats
-------------------------------------
Meeting | 10/Dec/2012  |   Every 7 days
Lunch   | 10/Dec/2012  |   Every 1 days
Run Code Online (Sandbox Code Playgroud)

抽象查询的目标结果SELECT Events BETWEEN 09/Dec/2012 AND 20/Dec/2012

Event   |  Date        |   Repeats
-------------------------------------
Meeting | 10/Dec/2012  |   Every 7 days
Meeting | 17/Dec/2012  |   Every 7 days
Lunch   | 10/Dec/2012  |   Every 1 days
Lunch   | 11/Dec/2012  |   Every 1 days
Lunch   | 12/Dec/2012  |   Every 1 days
Lunch   | 13/Dec/2012  |   Every 1 days
etc...
Lunch   | 20/Dec/2012  |   Every 1 days
Run Code Online (Sandbox Code Playgroud)

是否有一个数据库模式可以支持这类查询?对于在两天内发生的任何事件(包括重复事件),我将如何围绕该模式进行查询?

还是用于重复事件的设计模式?

Hug*_*ing 5

我将创建一个仅包含一个col的理货表,id并将该表填充为0到500之间的数字。现在,我们可以轻松地使用它来进行选择,而无需使用while循环。

Id
-------------------------------------
0
1
2
etc...
Run Code Online (Sandbox Code Playgroud)

然后我会在事件存储在一个表Name as varcharstartdate as datetimerepeats as int

Name    | StartDate            |   Repeats
-------------------------------------
Meeting | 2012-12-10 00:00:00  |   7
Lunch   | 2012-12-10 00:00:00  |   1
Run Code Online (Sandbox Code Playgroud)

现在,我们可以使用统计表通过以下方式选择两个日期之间的所有日期:

Id
-------------------------------------
0
1
2
etc...
Run Code Online (Sandbox Code Playgroud)
ShowDate
-------------------------------------
2012-12-09 00:00:00
2012-12-10 00:00:00
2012-12-11 00:00:00
2012-12-12 00:00:00
2012-12-13 00:00:00
2012-12-14 00:00:00
2012-12-15 00:00:00
2012-12-16 00:00:00
2012-12-17 00:00:00
2012-12-18 00:00:00
2012-12-19 00:00:00
2012-12-20 00:00:00
Run Code Online (Sandbox Code Playgroud)

然后,将其加入事件表中,以计算开始日期和显示日期之间的差异。我们通过repeats列划分了结果,如果其余为0,则匹配。

全部合并为:

Name    | StartDate            |   Repeats
-------------------------------------
Meeting | 2012-12-10 00:00:00  |   7
Lunch   | 2012-12-10 00:00:00  |   1
Run Code Online (Sandbox Code Playgroud)

导致

Id  | Name       |StartDate             | Repeats   | ShowDate              | diff
---------------------------------------------------------------------------------
1   | Meeting    | 2012-12-10 00:00:00  | 7         | 2012-12-10 00:00:00   | 0
2   | Lunch      | 2012-12-10 00:00:00  | 1         | 2012-12-10 00:00:00   | 0
2   | Lunch      | 2012-12-10 00:00:00  | 1         | 2012-12-11 00:00:00   | -1
2   | Lunch      | 2012-12-10 00:00:00  | 1         | 2012-12-12 00:00:00   | -2
2   | Lunch      | 2012-12-10 00:00:00  | 1         | 2012-12-13 00:00:00   | -3
2   | Lunch      | 2012-12-10 00:00:00  | 1         | 2012-12-14 00:00:00   | -4
2   | Lunch      | 2012-12-10 00:00:00  | 1         | 2012-12-15 00:00:00   | -5
2   | Lunch      | 2012-12-10 00:00:00  | 1         | 2012-12-16 00:00:00   | -6
1   | Meeting    | 2012-12-10 00:00:00  | 7         | 2012-12-17 00:00:00   | -7
2   | Lunch      | 2012-12-10 00:00:00  | 1         | 2012-12-17 00:00:00   | -7
2   | Lunch      | 2012-12-10 00:00:00  | 1         | 2012-12-18 00:00:00   | -8
2   | Lunch      | 2012-12-10 00:00:00  | 1         | 2012-12-19 00:00:00   | -9
2   | Lunch      | 2012-12-10 00:00:00  | 1         | 2012-12-20 00:00:00   | -10
Run Code Online (Sandbox Code Playgroud)

现在您可以(并且应该!)加快处理速度。例如,通过将日期直接存储在表中,这样您就可以直接选择所有日期,而不是将日期表与dateadd一起使用。您可以缓存且无需再次计算的每件事都是好的。