web-dev-qa-db-ja.com

タスクをスケジュールするためのデータベーステーブルの設計

決まった日に基づいて実行できる、毎日繰り返される、特定の曜日に繰り返される、特定の月に繰り返される、毎年特定の日に繰り返される、および次の日に繰り返されるスケジュールを作成できるようにしたいその日の特定の時間。

この問題のデータベーステーブルを構築するにはどうすればよいですか?

編集#1

基本的に、私はユーザーが事前構成された挨拶を事前構成されたさまざまな時間に送信されるようにスケジュールできるアプリケーションを作成しています。スケジュールに関する情報(クリスマス、Marketing Oneなど)を保存するテーブルが必要なことを知っています。次に、実行されたスケジュール、それが送信した挨拶、誰に、どのメールを送信したかを記録する別のテーブル。基本的にトランザクションテーブル。

ユーザーが特定の日付、特定の曜日(繰り返し)、毎月の特定の日、毎日の特定の時間、および毎年特定の日/月(例:25/12)。

これらの入力を柔軟に処理するスケジュールのテーブルセットを作成するにはどうすればよいですか?

16
Tebo

これは私が思いついたテーブル構造です。

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
20
Tebo

Microsoft SQL Serverは、効率的で柔軟な設計になっています: https://msdn.Microsoft.com/en-us/library/ms178644.aspx?f=255&MSPPError=-2147217396

18
Rob Kraft

上記の回答を読みましたが、多くのことは不要だと思います。間違っていた場合は修正してください。

これが私がすべきだと思うことです:

スケジュール


  • Id

  • タイプ(毎日、毎月、毎週、固定、毎年)-列挙型

  • 頻度(1〜7 [曜日]、1〜30(または28)[月の日]、1〜365 [日]、またはnull(毎日、固定)-ArrayField(of ints)-[ 1、7] OR [23] OR [235] OR null

  • 時間(UTCでの時刻)-ArrayField(Char文字列-['9:00'、'13:30 ']

  • 日付(固定型の場合)-datetime-2009-03-21

  • is_active(boolean)-スケジュールを有効または無効にする

  • name(CharField)-スケジュールに名前を付ける場合

残りのフィールドでは、構築しているものにコンテキストが必要です。

ここで、このために、実行する必要があるこのテーブルからスケジュールをフィルターするスクリプト(私の場合はDjango管理コマンド)を実行する30分ごとにcronjobを実行することを考えています(30分ごとに時間を入力しています)。

クエリは次のようになります。

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)
3
Gourav Chawla

受け入れられた答えは必要以上に複雑だと思います。これは、次のような単一のテーブルで実行できます。

Schedules

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

Frequencytypeは次のいずれかの値になります

  • 'O' = 1回
  • 'D' =毎日
  • 'W' =毎週
  • 「M」=月次
  • 'A' =毎年

Frequencyintervalは数値であり、値の意味はfrequencytypeの値に依存します

  • Type = 'Once'の場合、value = 0(間隔なし)のスケジュールはstartdateに実行されます
  • Type = 'Daily'の場合、value =#日間隔
  • Type = 'Weekly'の場合、曜日は1〜7
  • Type = 'Monthly'の場合、月の1から31まで
  • Type = 'Annually'の場合、年間通算日で1〜365
1
Vincent

あなたはスケジュールについて話しているので、ジョブの管理と実行のためのバッチアプリケーションを構築したいと思います。

リファレンス実装については、 spring batch meta data design を確認できます。ただし、正確な設計は要件によって異なります。これは単なるポインタです。

1

ジョブをより簡単にするために、既存のスケジューラーをスケジューリング部分に使用できます。 Javaには、たとえばQuartzまたは私が自分で作成したライブラリ db-scheduler があります。

db-schedulerは簡単に埋め込むことができ、繰り返しスケジュール(固定期間、毎日など)のタスクをすぐに使用できます。実行時間は単一のデータベーステーブルに保持されるため、再起動後も存続します。

0
Gustav Karlsson

スケジュールを格納するための次の一般的なスキーマを持つ単純なテーブルから始めることができます(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 
);
0
aayushsarva