決まった日に基づいて実行できる、毎日繰り返される、特定の曜日に繰り返される、特定の月に繰り返される、毎年特定の日に繰り返される、および次の日に繰り返されるスケジュールを作成できるようにしたいその日の特定の時間。
この問題のデータベーステーブルを構築するにはどうすればよいですか?
編集#1
基本的に、私はユーザーが事前構成された挨拶を事前構成されたさまざまな時間に送信されるようにスケジュールできるアプリケーションを作成しています。スケジュールに関する情報(クリスマス、Marketing Oneなど)を保存するテーブルが必要なことを知っています。次に、実行されたスケジュール、それが送信した挨拶、誰に、どのメールを送信したかを記録する別のテーブル。基本的にトランザクションテーブル。
ユーザーが特定の日付、特定の曜日(繰り返し)、毎月の特定の日、毎日の特定の時間、および毎年特定の日/月(例:25/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
Microsoft SQL Serverは、効率的で柔軟な設計になっています: https://msdn.Microsoft.com/en-us/library/ms178644.aspx?f=255&MSPPError=-2147217396
上記の回答を読みましたが、多くのことは不要だと思います。間違っていた場合は修正してください。
これが私がすべきだと思うことです:
スケジュール
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)
受け入れられた答えは必要以上に複雑だと思います。これは、次のような単一のテーブルで実行できます。
Schedules
- Id :int
- Greetingid :int
- Startdate :date
- Frequencytype :char(1)
- Frequencyinterval :int
- Timeofday :time
Frequencytypeは次のいずれかの値になります
Frequencyintervalは数値であり、値の意味はfrequencytypeの値に依存します
あなたはスケジュールについて話しているので、ジョブの管理と実行のためのバッチアプリケーションを構築したいと思います。
リファレンス実装については、 spring batch meta data design を確認できます。ただし、正確な設計は要件によって異なります。これは単なるポインタです。
ジョブをより簡単にするために、既存のスケジューラーをスケジューリング部分に使用できます。 Javaには、たとえばQuartzまたは私が自分で作成したライブラリ db-scheduler があります。
db-scheduler
は簡単に埋め込むことができ、繰り返しスケジュール(固定期間、毎日など)のタスクをすぐに使用できます。実行時間は単一のデータベーステーブルに保持されるため、再起動後も存続します。
スケジュールを格納するための次の一般的なスキーマを持つ単純なテーブルから始めることができます(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
);