カレンダー アプリを構築するときに、日付や繰り返しルールをデータベースに保存する必要がありますか?

StackOverflow https://stackoverflow.com/questions/4239871

質問

カレンダーのウェブサイトを構築しています (ASP.NET MVC)アプリケーション(Outlookのシンプルなバージョンを考えてください)と、定期的なカレンダーイベント(毎月、毎年など)のサポートを開始したいと考えています

現在、実際の日付を に保存していますが、繰り返しの場合、(明確なカットオフを設けて)日付を保存し続けることに意味があるのか​​、それとも繰り返しのオプションを保存してその場で日付を生成する必要があるのか​​を判断したいと思いました。 。

Outlook や Google メールなど、定期的な予定表アイテムをサポートするその他のサービスがどのように機能するかを考えさせられました。

これに関して何か提案はありますか?

役に立ちましたか?

解決

二つの部分にあなたのデータを区切り:「標準的な」データ(繰り返しルール)及び(生成された日付、読み取り専用の脇回生から)「サービス提供」。正規のデータが変更された場合、その時点で、「サービス提供」のデータを再生成します。無限の再発のために、インスタンスのいくつかの数を維持し、あなたが不足した場合より生成(例えば、2020年のための彼らのカレンダーのユーザーに見える場合)。

あなたは無限のプロセッサ速度を持っていた場合、あなたは標準的なデータのみを必要とするだろう - しかし、現実には、すべての日付/時刻をやって、のすべてののページビューが可能性が高いとされる上のすべての再発ルールの処理あまりにも時間がかかり...あなたには、いくつかのストレージ(と複雑さ)をトレードオフするように繰り返し計算を保存します。ストレージは、多数のイベントのために必要な計算と比較して、かなり安い通常です。イベントの日付を格納する場合、ののみの必要性、それは非常に安い本当にだ - 簡単にあなたを想定し、日付を表すために4バイトの整数を使用して、そこから完全な日付/時刻を生成することがありました再発がベースのすべての日付です。時間ベースの再発(例えば「三時間ごと」)のためには、完全なUTCの瞬間には、可能性 - 8つのバイトは、あなたが必要になりそうだ限りのためのかなり細かい解像度へのダウンを表します。

あなたはかかわらず、有効性を維持することに注意する必要がある - それはを持っている時には変更されません定期的な会議の変更今日の、ある場合には、そう...過去に起こりましたあなたはおそらく、のもは再発が実際に発生したときについての標準的な読み取り専用のデータを持っている。欲しいですあなたはおそらく数年前よりも多くの「ごみ収集」にイベントをしたいので、もちろん、あなたのストレージの制約に応じて、それは永遠に過去を残しておきたいことはありません。

またごとの出現毎に(例えば「会議が原因祝日に今日発生していない」または「午後4時に移動」)ノートや例外を追加する機能が必要な場合があります。あなたは「毎週火曜日」に「毎週月曜日」を変更する場合は、例外を維持するか、しないでください - それは、<全角>本当には再発を変更楽しみになり?あなたが「毎週」に「毎日」から変更したときにどのようにしても、例外を一致させるのですか?これらは、ストレージについて直接質問しているではありません - 。しかし、ストレージの決定は、それはあなたが決めるどんなポリシーを実装することがいかに簡単であるかに影響します。

他のヒント

イベントと出来事を個別に処理する必要があります。

イベントについて:イベントの場合、反復ルール (rfc5545 で指定されているようなルールだけでなく、rfc5545 の rdate のような明示的な日付セットも可能) だけでなく、例外 (rfc5545 の exdate を参照、場合によっては rfc2445 の exrule を参照) も保存する必要があります。また、これらのルールの変更を追跡する必要もあります。rdate、exdate の変更は、将来発生する場合には問題なく、過去の日付については無視されます。ルールの変更は、以前の出来事に影響を与えるため、さらに注意が必要です。私の個人的な好みは、古いルールと新しいルールに特定のプロパティを追加して、それぞれの有効期間の開始日と終了日を指定することです。

イベントの期間が限られている場合 (たとえば、COUNT または UNTIL プロパティが存在する場合)、イベントのクエリを容易にするために、その開始と終了をテーブルに保存する必要があります (特に、事前に計算された時間枠外の発生を探す場合 (以下を参照)。計算をやり直すイベントの数を減らすのに役立ちます)。

賢明な出来事:発生した場合は、現在前後の事前定義されたウィンドウ (たとえば +/- 6 か月または 12 か月で定期的に計算) 内にインスタンスを保存し、ユーザーがさらに将来を見たい場合に再計算できるようにこれを記録しておく必要があります (たとえば、パフォーマンスの問題)。次の出現箇所を見つけやすくするために、インデックス (RECURRENCE-ID) を計算することも考慮する必要があります。

バックエンドではなくフロントエンドで、tzid の変更を追跡して、特定の tzid にスケジュールされたイベントが現在のタイムゾーンに留まる必要があるかどうかをユーザーに尋ねる必要があります。更新されました (12 月 2 日金曜日に会議を予定していたサモア島の人のことを考えてください)国がこの日は存在しないと決定する前の 2011 年 30 日)、同様に、夏時間中に発生するイベントが「決して起こらない」のか「2 回起こる」のかを尋ねることができます(このトピックについて詳しく説明します) ここ)

注記:繰り返しルールに関して rfc5545 で定義されているものを超えるサポートを検討したり、宗教的な繰り返しルールのサポートを追加したりすることもできます ( USNO のカレンダーの紹介を参照 またはEからの印刷「カレンダー計算」(第3版)ラインゴルと N.ダーショウィッツ)。

既存の実装について質問するので、sunbird (sqlite) や Apple オープンソースのカレンダーおよび連絡先サーバー, 、caldav サーバー用の既存のオープンソース プロジェクトのより完全なリスト (おそらく、探しているもののサブセットです) が利用可能です。 ここ)

スケジューリングと連動するシステムを構築する必要があり、両方を実行しました。これが私たちが持っていたものです

  • スケジュールを追跡する一連のテーブル。
  • スケジュールの以前のインスタンス(実際に発生したとき)を追跡したテーブル
  • 前回と次のインスタンス (前回の時刻に基づいて次の項目がいつ発生するか) を追跡するテーブル このテーブルは必要ありませんが、これを使用しました。そうしないと、項目が発生するかどうかを常に計算することになるためです。今起こっている

スケジュールはいつでも変更される可能性があることを覚えておかなければならないため、スケジュール設定は非常に難しくなります。また、アプリケーションが実行されていないときに項目の期限が切れる可能性があり、アプリケーションが再び起動するときに、期限を過ぎた項目を特定する方法を知っておく必要があります。

また、実際のスケジュールを追跡するテーブルが独立していることも確認しました。その理由は、それらがシステム内で最も複雑なテーブルのセットであり、それらを再利用できるようにして、スケジューリングが必要なさまざまな用途に使用できるようにしたかったからです。管理者メールの送信、通知の送信、ログ ファイルのクリーンアップなどのサーバー メンテナンスなど。

私は間違いなくあなたの2番目のオプションを使用します。別の再発オプションを使用して、その場で別々に計算して保存します。すべてのこれらの日付を格納する必要はありませんデータの最大積載量になります。

ここにあなたの質問を補完するために良い答えです。
定期的なイベントを格納するためのデータ構造ですか

また、サイドノートとして。私はあなたが複数のタイムゾーンを使用する必要がある場合は、共通のベースラインを持っているように、UTC時間として、すべてを格納し始めました。

私は私が数年前に作られたウェブアプリケーション(だけでなく、今より良い方法があるかもしれません:))で同様の問題がありました。私は私のようなルールを持っている可能性があること、定期的なイベント、ハンドル時間、日、週、月、年、および例外のすべての機能を持っていたスケジューラを含めるたかっます:

午前10時、例外水曜日

1)毎日

2)1日4回の反復の最大値を有するすべての2時間

3)毎月第一月曜日

など。

定期的な日付/時刻の保存は可能ではなく、柔軟性に欠けました。 「最大」になるとき、あなたのイベントの各繰り返しは変化します。そして、どのようにはるか先、あなたが見ていますか?

最後に、私は、文字列から、書き込み読むことができる独自のスケジューリングクラスを書きました。これは、データベースに格納された後、簡単な関数は、次の発生があるときに見つけるために呼び出すことができる文字列だっます。

あなたは確かにそれらのいくつかを格納する必要があります。そのまま他の人を残して、イベントのユーザーかもしれない編集1は、(おそらく質問会った:「?編集するか、すべてのイベントのみ、このいずれかを定期的に」いくつかのカレンダーでは、すなわちのWindows Mobile。)

また、過去のイベントを保存すると、ユーザーが定期的なイベントを削除するときにそれらを削除しない場合があります。

あなたが他のすべてを保存したり、それらを生成した場合、

は、実装の詳細です。可能な場合、私は、それらを生成することを好むだろう。

いずれの場合では、各イベントに保存された定期的なイベントのいくつかのID、プラスイベントが後で変更された場合は、あなたを伝えるいくつかのフラグを持っているしたいと思います。以上の複雑なアプローチでは、各イベントプロパティ占いのためのフラグが、それのデフォルト値の場合(定期的なイベントから)、あるいは場合には、この特定のインスタンスのために変更されました。ユーザーは定期的なイベントを編集することを決定したときは、これが必要になります。

最も回答が生成されたデータを保存するに傾くことを

注。しかし、あなたはあなたのユースケースを検討することを確認してください。

私のサーバーは、CPUの多くは、何もしないでIOによって制限された日で戻ります。今では、コア数があまりにも増加していること。

SSD(あなたがそうでなければ、あなたの古いスピニングHDが残ったものを、余裕があれば)が、ノートを持っています

の計算のこれらの種類についての素晴らしい事は、あなたが簡単にそれらを分割して、多くのコアに、あるいはローカルネットワーク内のいくつかの安価なサーバにそれらを与えることができるということです。多くの場合、NoSQLのクラスタを設定するか、完全なデータベースクラスタの道を行くよりも安います。

や代替かもしれない、キャッシュも、ちょうどあなたのカレンダービューをキャッシュし、すべての計算には何も変わっていないすべての時間を行う必要はありません。

しかしとして、それはあなたのユースケースに依存しました。ただ上記の回答に従っていますが、時間とメイクよりも意思決定を持っている場合は、独自の計算をしないでください。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top