カレンダーアプリを書きたいのですが。 DBスキーマの作業でレンチを投げるのは、本当に定期的なアイテムです。これを整理する方法について、私はいくつかの情報が欲しいです。
ユーザーがイベントを作成し、月曜日に全員に永久に繰り返されると入力するとどうなるでしょうか。それをデータベースに保存するにはどうすればよいですか?無限のイベントは作成できません。すべてのイベントの行き先を計算できるように、関連情報を保持するテーブルをそこに置くだけですか?その場合、ユーザーがカレンダーの新しい部分を表示するたびにそれらを計算する必要があります。何ヶ月もページをめくっていても、定期的なアイテムがたくさんある場合はどうでしょうか。
また、スキーマは、ユーザーがアイテムをクリックし、シーケンス内のすべてのアイテムではなく「シーケンス内でこれを編集する」と言ったときに処理する必要があります。次に、1つのアイテムをシーケンスから分割しますか?
更新1
ICalはまったく見ていません。明確にするために、繰り返し発生するアイテムを計算できる情報を保存し、シーケンスと異なるものを分割することは、転送できるように保存するための優れた方法だと思います。しかし、アプリケーションでは、これは遅すぎて、あらゆる場所で日付の計算を行うことができないと思います。
最近カレンダーアプリケーションを作成しましたが、これは私が直面した多くの課題の1つでした。
私は最終的にセミハックのようなソリューションを思いつきました。 event_type
列を作成しました。その列には、daily
、weekly
、monthly
、またはyearly
のいずれかがありました。 start_date
列とend_date
列もありました。それ以外はすべて実際のバックエンドコードで処理されました。
ユーザーが1つのイベントのみを編集した場合、イベントを分割しようとしませんでした。その状況では必要ありませんでした。ただし、最初のend_dateを変更してイベントを分割し、元のstart_date
とend_date
を使用して新しいイベントを作成し、最後に、選択したイベントの新しいイベントを作成することができます。編集します。このプロセスでは、最終的に3つのイベントが作成されます。
ハックっぽいね。当時、私はこの問題を処理するための賢い方法を考えることができませんでした。
私は同じ問題に苦労していて、実際には上記の「キャッシュテーブル」のアイデアをいじっていましたが、それから、別の方法( ここで提案 )に出会いました。まだ代表。
すべてのイベントを含むテーブルを作成する
EventID (primary key)
Description
StartDate
PeriodType - days, weeks, months, years
PeriodFreq - # of days, weeks, etc between events
EndDate
... other attributes that can be modified
次に、これらのイベントにexceptionsのテーブルを追加します。このテーブルは、イベントテーブルにマップするEventIDで構成される複合キーと、シリーズの特定のイベントを選択するインスタンスIDを使用します。
EventID (key)
InstanceID (key)
InstanceDate - the modified date of the exception
IsCancelled - a flag to skip this date when traversing the series
... other attributes that can be modified
これは、イベントテーブルを正規化した状態に保ち、例外を処理するためにシリーズを分割することを避けます。
Google CalendarのAPI を使用して、カレンダーイベントの保存と取得を行い、このカレンダーアプリケーションのデータベースとしてGoogleカレンダーを使用してみませんか?
Calendar APIは、REST明示的なHTTP呼び出しを介してアクセスできるAPIです。このAPIは、Google Calendar Webインターフェイスで利用可能なほとんどの機能を公開しているため、カレンダーアプリケーションはGoogleと同じくらい多くの機能を利用できますカレンダーにはあります(多くの機能!!!)。
アプリケーションで実装する必要があるのはOAuth 2.0 for Google APIのみです。これは Auth のようなシングルサインオンサービスを使用して簡単に行うことができ、適切なアクセストークンを提供します。次に、カレンダーアプリケーションは、これらのトークンをCalendar APIと組み合わせて使用して、JSON形式でカレンダーイベントをシームレスに保存および取得できます。
ユーザーは自分の「新しいカレンダー」内でイベントを作成します。このカレンダーは、このアプリケーション専用のGmailアカウントの形式であなたと共有されます-アプリケーションのGmailアカウント。
基本的に、Googleカレンダーがデータベースになります。これにより、アプリケーションのGmailアカウントにアプリケーションのすべてのイベントを保存できるだけでなく、表示したり、これらのイベントを直感的なインターフェースで編集します。
イベントテーブルの定期的なアイテムを通常どおりに保持しますが、適切な開始日/終了日で定期的なアイテムとしてフラグを立てます。
ユーザーが予定の単一のインスタンスを変更する場合は、おそらく「parentId」が定期的なイベントのIDと等しい新しいイベントを作成します。
カレンダーが特定の日の繰り返しイベントを、親IDが一致するイベントで上書きするようにするロジックを構築します。
パフォーマンスについてのあなたの質問は、基本的に古い速度とストレージの問題です。必要な計算が非常に多くの予定を保存するためのスペース要件を超えるとは思いません。データベースの最適化-インデックス作成などを読んでください。
次のX日分のイベントを事前計算する「キャッシュ」テーブルで2つの世界を橋渡しできますか?
したがって、3つのテーブル:
recurring_event_specs
one_time_events
cached_recurring_events
今日からX日以内のカレンダーのどの部分でも、クエリはUNION one_time_events
およびcached_recurring_events
。
次に、ユーザーがカレンダーの一部を将来X日より長く見ようとした場合にのみ、その場で日付を計算する必要があります。私はあなたが通常の使用の大部分をカバーする正気なXを見つけることができると思います。
cached_recurring_events
テーブルは、ユーザーが新しい定期的なイベントを追加するたびに更新する必要があります。おそらく1日1回、オフラインでcron-job/scheduled-taskを使用します。ただし、新しい定期的な予定が作成されていない日のみ。
これを行う最良の方法は、標準ベースの繰り返しパターン文字列(iCal)を格納し、それが単一のイベントの場合は空白のままにすることです。繰り返しパターンを解析して、UI要素にバインドできるイベントオブジェクトを作成できるAPIがいくつかあります。発生をデータベースに保存する必要はなく、初期イベント(発生)のみを保存できます。
1日のイベントを開始時刻と終了時刻で保存できませんか?毎日発生するイベントの多くのデータを生成します(このためにリレーショナルでない可能性があります)が、クエリが容易になり、例外を発生させることができます(つまり、イベントの場所が焼失した、または従業員が攻撃している)。イベントの日数を生成するために、ICalっぽいパターンで派生したフロントエンドでそれを実装することをお勧めします。