繰り返し発生するイベントは、定義上、一定の間隔で繰り返されるイベントです。定期的なイベントとも呼ばれます。ユーザーが定期的なイベントを設定できるようにするアプリケーションはたくさんあります。データベースシステムは定期的なイベントをどのように管理しますか?この記事では、それらが処理される1つの方法について説明します。
アプリケーションが処理するのは簡単ではありません。これはハリケーンの課題になる可能性があります。特に、隔週または四半期ごとのイベントの作成や、将来のすべてのイベントインスタンスの再スケジュールの許可など、考えられるすべての繰り返しシナリオをカバーする場合はそうです。
定期的なイベントを管理する2つの方法
データモデルで定期的なタスクを処理するには、少なくとも2つの方法が考えられます。それらについて説明する前に、このタスクの要件について簡単に説明しましょう。一言で言えば、効果的な管理とは次のことを意味します。
- ユーザーは定期的および定期的なイベントを作成できます。
- 毎日、毎週、隔週、毎月、四半期ごと、隔年、毎年のイベントを、終了日の制限なしで作成できます。
- ユーザーは、イベントのインスタンスまたはイベントの今後のすべてのインスタンスを再スケジュールまたはキャンセルできます。
これらのパラメータを考慮すると、データモデルで繰り返し発生するイベントを管理する2つの方法が思い浮かびます。それらを素朴な方法と専門家の方法と呼びます。
素朴な方法: イベントのすべての可能な繰り返しインスタンスをテーブルの個別の行として保存します。このソリューションでは、必要なテーブルは1つだけです。つまり、event
。このテーブルには、event_title
のような列があります 、start_date
、end_date
、is_full_day_event
、など。start_date
およびend_date
列はタイムスタンプデータ型です。このようにして、一日中続かないイベントに対応できます。
長所: これは非常に単純なアプローチであり、実装が最も簡単です。
短所: 素朴な方法には、次のようないくつかの重大な欠点があります。
- イベントのすべての可能なインスタンスを保存する必要があります。大規模なユーザーベースのニーズを考慮に入れる場合は、大量のスペースが必要になります。ただし、スペースはかなり安いので、この点は大きな影響はありません。
- 非常に面倒な更新プロセス。 イベントが再スケジュールされたとします。その場合、誰かがそのすべてのインスタンスを更新する必要があります。スケジュールを変更するときは、膨大な数のDML操作を実行する必要があり、アプリケーションのパフォーマンスに悪影響を及ぼします。
- 例外の処理。 特に、例外を作成した後で元の予定に戻って編集する必要がある場合は、すべての例外を適切に処理する必要があります。たとえば、定期的なイベントの3番目のインスタンスを1日進めるとします。その後、元のイベントの時刻を編集するとどうなりますか?元の日に別のイベントを再挿入し、前に持ってきたイベントを残しますか?例外のリンクを解除しますか?適切に変更してみますか?
-
Event_id
–この列はevent
テーブルであり、このテーブルの主キーとして機能します。event
およびrecurring_pattern
テーブル。この列では、イベントごとに最大1つの繰り返しパターンが存在することも確認されます。 -
Recurring_type_id
–この列は、毎日、毎週、毎月、または毎年の再発の種類を示します。 -
Max_num_of_occurrances
–イベントの正確な終了日がわからない場合がありますが、イベントを完了するために必要なオカレンス(会議)の数はわかっています。この列には、イベントの論理的な終了を定義する任意の数値が格納されます。 -
Separation_count
–可能な再発タイプの値が4つしかない場合(日次、週次、月次、年次)、隔週または隔年のイベントをどのように構成できるか疑問に思われるかもしれません。答えはseparation_count
です 桁。この列は、次のイベントインスタンスが許可されるまでの間隔(日、週、または月)を示します。たとえば、イベントを1週間おきに設定する必要がある場合、 Separation_count =“ 1” この要件を満たすために。この列のデフォルト値は「0」です。 -
recurring_type_id
「毎週」になります。 -
Separation_count
「1」になります。 -
day_of_week
「2」になります。 -
Week_of_month
–この列は、その月の特定の週にスケジュールされているイベント用です。つまり、最初、2番目、最後、最後から2番目などです。これらの値は1、2、3、4、..として保存できます。月の初め)または-1、-2、-3、...(月末から数えて) -
Day_of_month
–イベントがその月の特定の日、たとえば25日にスケジュールされる場合があります。この列はこの要件を満たしています。week_of_month
のように 、正の数(月の初めから7日目は「7」)または負の数(月末から7日目は「-7」)を入力できます。 -
recurring_type_id
「毎月」になります。 -
Separation_count
「2」になります。 -
day_of_month
「11」になります。 - 残りのすべての列はnullになります。
- 休日に発生するイベント。 イベントの特定のインスタンスが祝日に発生した場合、そのイベントは休日の直後の営業日に自動的に移動する必要がありますか?それとも自動的にキャンセルする必要がありますか?これらのいずれかがどのような状況に当てはまりますか?
- イベント間の競合。 特定のイベント(相互に排他的)が同じ日に発生した場合はどうなりますか?
エキスパートウェイ: 繰り返しパターンを保存し、プログラムで過去および将来のイベントインスタンスを生成します。このソリューションは、単純なソリューションの欠点に対処します。この記事では、エキスパートソリューションについて詳しく説明します。
提案されたモデル
イベントの作成
スケジュールされたすべてのイベントは、定期的または定期的な性質に関係なく、event
テーブル。すべてのイベントが定期的なイベントであるとは限らないため、フラグ列is_recurring
が必要になります 、このテーブルで、定期的なイベントを明示的に指定します。 event_title
およびevent_description
列には、件名とイベントの簡単な要約が格納されます。イベントの説明はオプションであるため、この列はnull許容です。
その名前が示すように、start_date
およびend_date
列は、イベントの開始日と終了日を保持します。通常のイベントの場合、これらの列には実際の開始日と終了日が格納されます。ただし、定期的なイベントの最初と最後の発生日も保存されます。 end_date
を保持します ユーザーは終了日なしで定期的なイベントを構成できるため、列はNULL可能として。この場合、仮想の終了日(たとえば、1年間)までの将来の発生がUIに表示されます。
is_full_date_event
列は、イベントが終日のイベントであるかどうかを示します。終日のイベントの場合、start_time
およびend_time
列はnullになります。これが、これらの列の両方をnull許容に保つ理由です。
created_by
およびcreated_date
列には、イベントを作成したユーザーとそのイベントが作成された日付が格納されます。
次に、parent_event_id
があります 桁。これは、データモデルで主要な役割を果たします。その重要性については後で説明します。
再発の管理
ここで、主な問題ステートメントに直接到達します。event
テーブル–つまり、is_recurring
イベントのフラグは「Y」ですか?
前に説明したように、イベントの繰り返しパターンを保存して、将来発生するすべてのイベントを作成できるようにします。 recurring_pattern
テーブル。このテーブルには次の列があります:
さまざまな種類の再発の観点から、残りの列の重要性を考えてみましょう。
毎日の再発
毎日繰り返されるイベントのパターンをキャプチャする必要が本当にありますか?いいえ、毎日の再発パターンを生成するために必要なすべての詳細は、すでにevent
テーブル。
パターンを必要とする唯一のシナリオは、イベントが1日おきまたはX日ごとにスケジュールされる場合です。この場合、Separation_count
列は、再発パターンを理解し、さらにインスタンスを導き出すのに役立ちます。
毎週の再発
追加の列は、day_of_week
の1つだけです。 、このイベントが行われる曜日を保存します。月曜日が週の最初の日であり、日曜日が最後であると仮定すると、可能な値は1、2、3、4、5、6、および7になります。個々のイベントの発生を生成するコードを適切に変更する必要があります。毎週のイベントでは、残りのすべての列がnullになります。
古典的なタイプの毎週のイベント、つまり隔週のイベントを取り上げましょう。この場合、隔週の火曜日、つまり週の2日目に発生すると言います。だから:
毎月の再発
day_of_week
の他に 、毎月の再発シナリオを満たすには、さらに2つの列が必要です。簡単に言うと、これらの列は次のとおりです。
次に、より複雑な例、つまり四半期ごとのイベントについて考えてみましょう。会社が四半期ごとの結果予測イベントを各四半期の最初の月の11日間(通常は1月、4月、7月、および10月)にスケジュールするとします。したがって、この場合:
上記の例では、ユーザーが1月に四半期ごとの結果予測を作成していると想定しています。 この分離ロジックは、イベントが作成された月、週、または日からカウントを開始することに注意してください。
同様の行で、半年ごとのイベントは、
毎年の再発は非常に簡単です。特定の曜日と月の列があるため、月に1つの追加の列のみが必要です。この列に
それでは、例外について見ていきましょう。定期的なイベントの特定のインスタンスがキャンセルまたは再スケジュールされた場合はどうなりますか?このようなインスタンスはすべて、
これらの2つの列を除いて、残りのすべての列は
ユーザーが定期的なイベントの将来のすべてのインスタンスを再スケジュールできるようにするアプリケーションがあります。このような場合、2つのオプションがあります。今後のすべてのインスタンスを
このソリューションを使用すると、再発パターンが変更された場合でも、過去に発生したすべてのイベントを取得できます。
繰り返し発生するイベントの周りには、まだ説明していない、より複雑な領域がいくつかあります。 2つあります:
これらの機能を組み込むには、どのような変更を加える必要がありますか?コメント欄でご意見をお聞かせください。separation_count
を使用して月次イベントとしてログに記録できます。 「5」の。年次再発
month_of_year
という名前を付けました 。定期的なイベントの例外の処理
event_instance_exception
テーブル。 Is_rescheduled
という2つの列を見てみましょう。 およびis_cancelled
。これらの列は、このインスタンスが後の日時に再スケジュールされるか、完全にキャンセルされるかを示します。なぜこれに2つの別々の列があるのですか?さて、最初にスケジュールが変更され、その後完全にキャンセルされたイベントについて考えてみてください。これが発生し、これらの列を使用して記録する方法があります。 event
テーブル。
parent_event_id
を使用して2つのイベントをリンクする理由 ?event_instance_exception
に保存できます (ヒント:許容できる解決策ではありません)。または、event
テーブルを作成し、id_parent_event
を使用して以前のイベント(親イベント)にリンクします 桁。 定期的なイベント処理を改善する方法