用于存储计划/cron 作业的数据库结构?

Posted

技术标签:

【中文标题】用于存储计划/cron 作业的数据库结构?【英文标题】:Database structure for storing schedules/cron job? 【发布时间】:2018-10-03 01:13:17 【问题描述】:

我遇到了一个问题。在应用程序的数据库中,我有一个schedule 表,它将存储用户提供的时间表。例如

每天 每周 每周两次 每周第三天(或任何用户选择) 每月 每月两次 每月 x 天 每年的每个 x 月

等等。然后,这些时间表将提供参考点来安排不同的任务或识别它们的重复性。

我想不出合适的数据库结构。我能得到的最好的结果是有一个包含以下列的表格:

天 周 月 年份 类型

然后将指定的时间表存储在相关列中并提供类型。 例如,每周可以像周列中的 1 和 1(重复整体的指定值)或类似的东西。

这种方法的问题是该表将被非常频繁地使用,并且检索到的数据不会直接。它需要计算才能知道调度类型,因此需要复杂的数据库查询来获取每种类型的调度。

如果可以提供任何其他方法,我将在 Laravel 应用程序中实现它。这是一个 SAAS 应用程序,其中包含与日程表相关的大量数据。

任何帮助将不胜感激。谢谢

【问题讨论】:

我会对用于查找要执行的计划作业的查询非常感兴趣。我觉得它一定相当复杂。 @Namoshek 我想到的另一个解决方案是将其存储为 cron 作业字符串并使用帮助程序包进行查询和解析,例如 github.com/dragonmantank/cron-expression 采用这种方式的问题在于,您必须将所有计划的作业加载到内存中以检查它们是否需要运行 - 并且很可能每分钟运行一次。在这种情况下,你也可以只使用内置的 Laravel cron 调度程序而不是第三方包。但它对我来说似乎不是很好,而且很难在多个服务器上分发(如果这是一个要求的话)。 您还需要历史记录吗?例如,您是否需要知道用户的作业上次运行的时间,这样您就不会在一个月内运行两次每月一次的作业? (例如,由于服务器重启。) @MikeSherrill'CatRecall' 是的,我需要知道上次运行的时间,这样我就不会再次运行,但我会从与计划相关的作业表中获得该信息 【参考方案1】:

我建议你倒着处理这个问题。

制定几条规则。 在您的应用程序中编写规则,而不是在 SQL 中。插入事件时,在日历中预先填写未来 12 个月的所有事件。每个月,检查所有事件并将“预填充”延长一个月(此后 13 个月)。

现在SELECTs 既简单又快速。

SELECT ... WHERE date = '...'

有当天的所有事件(假设在 12 个月内)。

复杂性在于插入。但大概您插入的频率低于您选择的频率。

包含事件定义的表只会根据您的应用确定要执行的操作所需的复杂程度。也许

start_date DATE,
frequency ENUM('day', 'week', 'month', ...)
multiplier TINYINT, -- this lets you say "every second week"
offset TINYINT,   -- to get "15th of every month"

每周两次将是两个条目。

更好的是,有几个包(在 Perl、shell 等中)提供了一种非常丰富的语言来表达事件日期模式。此外,您可以简单地“调用”它来为您完成所有工作!

【讨论】:

以上是关于用于存储计划/cron 作业的数据库结构?的主要内容,如果未能解决你的问题,请参考以下文章

PHP:运行计划作业(cron 作业)

Cron 作业计划时间自动更改

GitHub Actions - 计划的 cron 作业的通知

cron 如何在内部调度作业?

ElasticBeanstalk worker cron 每分钟运行多次

用于日常数据库备份的bash shell文件-作为CRON作业运行