用于调度任务的数据库表设计

时间:2012-08-23 10:15:28

标签: database-design database-schema

我希望能够创建可以根据固定日期执行的日程表,每天重复,在一周中的特定日期重复,在一年中的特定月份重复,在每年的特定日期重复,并在一天的特定时间重复。

请问我该如何为这个问题构建数据库表?

编辑#1

基本上,我正在编写一个应用程序,允许用户安排在各种预先配置的时间发送预先配置的问候语。我知道我需要一个存储有关时间表信息的表格(例如圣诞节,营销一,... |以及时间表应该运行)。然后是另一个表,用于记录已运行的计划,发送的问候语,人员和电子邮件;基本上是一个交易表。

我的问题是设计Schedule表,因为我希望允许用户在特定日期,特定日期(周期性),每个月的特定日期,每天的特定时间运行计划,每年特定的日/月(例如25/12)。

如何为计划创建一组表格,以灵活的方式处理这些输入?

7 个答案:

答案 0 :(得分:14)

答案 1 :(得分:12)

这是我提出的表格结构;

Schedule
 - ScheduleName
 - ScheduleTypeId (Daily, Weekly, Monthly, Yearly, Specific)
 - StartDate
 - IntervalInDays
 - Frequency
 - FrequencyCounter

ScheduleDaily
 - ScheduleDailyId 
 - ScheduleId
 - TimeOfDay
 - StartDate
 - EndDate

ScheduleMonthly
 - ScheduleMonthlyId
 - ScheduleId
 - DayOfMonth
 - StartDate
 - EndDate

ScheduleSpecific
 - ScheduleSpecificId
 - ScheduleId
 - SpecificDate
 - StartDate

...

ScheduleJob
 - ScheduleJobId
 - ScheduleId
 - ScheduleTypeId
 - RunDate
 - ScheduleStatusId

答案 2 :(得分:1)

由于您在谈论计划,我假设您要构建一个批处理应用程序来管理和执行作业。

您可以查看spring batch meta data design以获取参考实施。但是,确切的设计取决于您的要求。这只是一个指针。

答案 3 :(得分:1)

我认为公认的答案比需要的要复杂得多。可以使用这样的单个表完成此操作:

Schedules

 - Id :int
 - Greetingid :int
 - Startdate :date
 - Frequencytype :char(1)
 - Frequencyinterval :int
 - Timeofday :time

频率类型将是以下值之一

  • 'O'=一次
  • 'D'=每日
  • 'W'=每周
  • 'M'=每月
  • 'A'=每年

频率间隔为数字,值的含义取决于频率类型的值

  • 如果type ='Once',则值= 0(无间隔)计划将在开始日期执行
  • 如果类型=“每日”,则值=天数间隔
  • 如果type ='Weekly',则一周中的某天为1到7
  • 如果type ='Monthly',则表示当月的1到31
  • 如果type ='Annually',则表示一年中的1到365

答案 4 :(得分:0)

为使您的工作更轻松,您可以将现有的计划程序用于计划部分。在Java中,例如有Quartz或我自己写的库db-scheduler

<div id="Team1PlayerScores"> @for (int i = 0; i < Model.Team1.Players.Count; i++) { @Html.DisplayFor(m => Model.Team1.Players[i].Name) @Html.EditorFor(m => Model.Team1.Players[i].GoalsForCurrentGame, new { htmlAttributes = new { min = Model.MinimumGoals, max = Model.MaximumGoals, onchange = "updateTeamScore('Team1PlayerScores', 'Team1_GoalsForCurrentGame')" } }) } </div> <div id="Team2PlayerScores"> @for (int i = 0; i < Model.Team2.Players.Count; i++) { @Html.DisplayFor(m => Model.Team2.Players[i].Name) @Html.EditorFor(m => Model.Team2.Players[i].GoalsForCurrentGame, new { htmlAttributes = new { min = Model.MinimumGoals, max = Model.MaximumGoals, onchange = "updateTeamScore('Team2PlayerScores', 'Team2_GoalsForCurrentGame')" } }) } </div> 易于嵌入,并且对定期执行的任务(固定工期,每天等)具有开箱即用的支持。执行时间保存在单个数据库表中,因此它可以在重新启动后幸免。

答案 5 :(得分:0)

我已经阅读了上面的答案,我认为很多事情都是不必要的,如果我错了,请纠正我。

这是我认为应该做的:

计划


  • Id

  • 类型(每日,每月,每周,固定,每年)-枚举

  • 频率(可以是1-7 [一周中的天],1-30(或28)[一个月中的天],1-365 [一年中的天]或为null(对于每日,固定)-ArrayField (以整数为单位)-[1,7]或[23]或[235]或null

  • 时间(UTC中的一天中的时间)-ArrayField(Char字符串-['9:00','13:30']

  • 日期(用于固定类型)-datetime-2009-03-21

  • is_active(布尔值)-用于启用,禁用计划

  • 名称(CharField)-如果要命名时间表

其余字段将需要您所构建的内容的上下文。

现在,为此,我正在考虑每30分钟运行一次cronjob(我花的时间输入间隔为30分钟),它运行一个脚本(在我的情况下为django管理命令),该脚本从该表中筛选出需要运行:

查询将是这样的:

current_day_of_week = 3
current_day_of_month = 24
current_day_of_year = 114
current_time = 13:30
current_date = 2019-04-24

Filter records that match the below query(not even psuedo code)(I'm using Q objects(https://docs.djangoproject.com/en/2.2/topics/db/queries/#complex-lookups-with-q-objects)

Q(daily AND current_time) OR
Q(weekly AND current_day_of_week AND current_time) OR
Q(monthly AND current_day_of_month AND current_time) OR
Q(yearly AND current_day_of_year AND current_time) OR
Q(fixed AND current_date AND current_time)

答案 6 :(得分:0)

您可以从一个简单的表开始,该表具有以下用于存储日程表的通用模式(PostgreSQL)。考虑调度运行的每个实例,称为“作业”。

CREATE TABLE Schedule (
    id SERIAL UNIQUE,                      -- unique identifier for the job
    name varchar(64) NOT NULL,             -- human readable name for the job
    description text,                      -- details about the job
    schedule varchar(64) NOT NULL,         -- valid CRON expression for the job schedule
    handler varchar(64) NOT NULL,          -- string representing handler for the job
    args text NOT NULL,                    -- arguments for the job handler
    enabled boolean NOT NULL DEFAULT TRUE, -- whether the job should be run
    created_at timestamp NOT NULL,         -- when was the job created
    updated_at timestamp NOT NULL,         -- when was the job updated
    start_date timestamp,                  -- job should not run until this time
    end_date timestamp,                    -- job should not run after this time
    last_triggered_at timestamp,           -- when was the job last triggered
    meta json                              -- additional metadata for the job 
);