我正在构建一个自定义事件系统,如果你有一个重复的事件,看起来像这样:
事件A从2011年3月3日开始每4天重复一次
or
赛事B从2011年3月1日开始,每两周在周二举行一次
我如何将其存储在数据库中,使其易于查找。如果有大量的事件,我不希望出现性能问题,而且在呈现日历时,我必须遍历每一个事件。
我正在构建一个自定义事件系统,如果你有一个重复的事件,看起来像这样:
事件A从2011年3月3日开始每4天重复一次
or
赛事B从2011年3月1日开始,每两周在周二举行一次
我如何将其存储在数据库中,使其易于查找。如果有大量的事件,我不希望出现性能问题,而且在呈现日历时,我必须遍历每一个事件。
当前回答
虽然建议的解决方案是可行的,但我试图用Full Calendar实现,它需要为每个视图调用超过90个数据库(因为它加载当前、以前和下个月),这让我不太兴奋。
我找到了一个递归库https://github.com/tplaner/When,您只需将规则存储在数据库中,并使用一个查询来提取所有相关规则。
希望这能帮助到其他人,因为我花了这么多小时试图找到一个好的解决方案。
编辑:这个库是PHP的
其他回答
你举的两个例子很简单;它们可以表示为一个简单的间隔(第一个是4天,第二个是14天)。如何建模完全取决于递归的复杂度。如果上面的内容真的很简单,那么就存储一个开始日期和重复间隔的天数。
然而,如果你需要支持一些事情,比如
事件A从2011年3月3日开始,每月3日重复发生
Or
事件A从2011年3月11日开始在每月的第二个星期五发生
这是一个更复杂的模式。
套@dat_ini = 2023-05-20’,@dat_fim = 2022-11-20’; 选择(DATEDIFF(@dat_fim,@dat_ini) % 60
这个< 10
它只在短时间内有效。
要做到这一点,请使用开始日期并更改屏幕上的月份并添加一年,然后从开始日期中减去它,然后就可以工作了。
增强:用日期替换时间戳
作为对公认答案的一个小改进,随后由ahoffner改进-可以使用日期格式而不是时间戳。优点是:
数据库中可读的日期 年份> 2038和时间戳没有问题 删除时需要小心基于季节性调整日期的时间戳,即在英国,6月28日比12月28日早一个小时开始,因此从日期中获得时间戳可能会破坏递归算法。
要做到这一点,将DB repeat_start更改为'date'类型,并且repeat_interval现在保存天数而不是秒。即重复7天。
修改SQL行:
WHERE (( 1370563200 - repeat_start) % repeat_interval = 0 )
to:
WHERE ( DATEDIFF( '2013-6-7', repeat_start ) % repeat_interval = 0)
其他一切都保持不变。简单的!
虽然建议的解决方案是可行的,但我试图用Full Calendar实现,它需要为每个视图调用超过90个数据库(因为它加载当前、以前和下个月),这让我不太兴奋。
我找到了一个递归库https://github.com/tplaner/When,您只需将规则存储在数据库中,并使用一个查询来提取所有相关规则。
希望这能帮助到其他人,因为我花了这么多小时试图找到一个好的解决方案。
编辑:这个库是PHP的
为什么不使用类似Apache cron作业的机制呢?http://en.wikipedia.org/wiki/Cron
对于日历调度,我将使用稍微不同的“位”值来适应标准的日历重复事件-而不是 [星期几(0 - 7),月(1 - 12),月(1 - 31),小时(0 - 23),分钟(0 - 59)]
——我会用 [年(每N年重复一次),月(1- 12),月中的第一天(1- 31),月中的第一周(1-5),周中的第一天(0 - 7)]
希望这能有所帮助。