2

単純なアジェンダアプリケーションのデータベースモデルを探していましたが、見つかりませんでした。StackOverflowにはこの問題に関して多くの質問がありますが、具体的な答えを提供するものはありません。そこで私はさらに調査し、自分のモデルを考え出しました。これをあなたに提示して、あなたがそれを評価し、改善するのを手伝ってくれるようにします。そして、これが将来これを探している人々のための参照として役立つかもしれません。

このモデルは、大幅に削減されましたが、Outlookによって提供される機能に触発されています。これは、かなりの量のアプリケーションコードによってサポートされることを目的としています。

CREATE TABLE dbo.Users (
    UserId UNIQUEIDENTIFIER NOT NULL,
    CONSTRAINT PK_Users PRIMARY KEY (UserId))

CREATE TABLE dbo.Appointments (
    -- Keys.
    AppointmentId INT IDENTITY NOT NULL,
    ParentAppointmentId INT NULL,
    UserId UNIQUEIDENTIFIER NOT NULL,
    -- General fields.
    EventDescription VARCHAR(500) NULL,
    EventName VARCHAR(50) NOT NULL,
    -- Schedule fields.
    IsCancelled BIT NOT NULL, /* To cancel only one appointment in a series of recurring appointments. */
    AppointmentDate DATE NOT NULL,
    IsAllDayEvent BIT NOT NULL,
    StartTime TIME NULL, /* This field is required in case IsAllDayEvent = false */
    DurationInMinutes INT NULL, /* This field is required in case IsAllDayEvent = false */
    RecurrenceCount SMALLINT NULL,
    RecurrenceEndDate DATE NULL,
    RecurrenceType TINYINT NULL, /* 1 = Daily, 2 = Weekly (other recurrence types are not supported by design) */
    WeeklyRecurrenceDays VARCHAR(13), /* 1,2,3,4,5,6,7 (each number represents a day of the week, where 1 = sunday) */
    -- Constraints.
    CONSTRAINT PK_Appointments PRIMARY KEY (AppointmentId),
    CONSTRAINT PK_Appointments_Appointments FOREIGN KEY (ParentAppointmentId) REFERENCES dbo.Appointments(AppointmentId),
    CONSTRAINT FK_Appointments_Users FOREIGN KEY (UserId) REFERENCES dbo.Users(UserId))

ハイライト:

  • DurationInMinutesの値をに加算することにより、予定の終了時刻を取得できますStartTime
  • 予定は1日続くことがありIsAllDayEvent = 1ます。その場合、フィールドStartTimeおよびDurationInMinutesは必要ありません。
  • 繰り返しの特徴は、アプリケーションコードによって計算されます。アポイントメントが繰り返し発生する場合でも、データベースに登録されるのは1回だけであり、アプリケーションは、アポイントメントが繰り返される日付を計算し、それらの日付をカレンダーに表示する責任があります。アプリケーションのパフォーマンスを向上させるために、アプリケーションはカレンダーにのみ表示される期間の計算を実行できます。これらの計算をどこかにキャッシュし、ユーザーが繰り返し設定を変更したり、予定を削除したりしたときに計算を削除することで、パフォーマンスをさらに向上させることができます。
  • 繰り返し予定が繰り返される回数は、RecurrenceCountまたはRecurrenceEndDateフィールドを調べることによって決定されます。一度に1つの値のみに値を含める必要があります。
  • このモデルは、シリーズ内の1つ以上の予定の編集をサポートします。それParentAppointmentIdが目的です。「例の予定」と呼ばれる定期的な予定があり、毎日5回繰り返されるように構成されているとします。次に、ユーザーがシリーズの3番目の予定のみを編集し、名前を「更新された予定」に変更することを選択したとします。これにより、アプリケーションはデータベース内の元の予定レコードを複製しますが、新しい名前を使用し、元の予定(親)を参照するようになります。前述したように、シリーズ内に異なるプロパティを持つ予定があることを検出し、カレンダーに表示する繰り返しを計算するときにそれを考慮に入れるのは、アプリケーションの責任です。
  • この機能についてはParentAppointmentId、ユーザーは一連の1つ以上の予定をキャンセルできます。例:「このイベントをすべての木曜日に発生させたいが、特定の木曜日には発生させたくない」。これにより、複製プロセスは上記のようになりますが、子の予定IsCancelledフィールドが1(true)に設定されます。アプリケーションは、カレンダーにシリーズを表示するときに、この特定の予定を「非表示」にする必要があります。
  • 機能については、ParentAppointmentIdアプリケーションロジックを簡素化し、Outlookモデルに従って、ユーザーが元の予定の繰り返し設定を変更すると、シリーズ全体が再計算されるため、子の予定は失われます。

まあ、これだと思います。このアプローチに同意するかどうか、または同意しない場合は、まったく異なるアプローチを採用しない場合、何を変更しますか。

前もって感謝します。

4

2 に答える 2

1

あなたがここでひどいことをしているとは思えません...

1 つの考えとしては、parentAppointmentId を完全に分割して、任意の 2 つの予定を単純にリンクする新しい連想テーブルを作成することです。次に、定義されている関係のタイプを識別するために、おそらく何らかのロールまたはタイプの列を配置します。

このようにして、シリーズ内のより複雑な関連付け (スキップ、名前の変更など) を許可する柔軟性が得られるだけでなく、1 つの予定が 1 つだけでなく、他の多くの予定の結果またはフォローオンになる可能性も考慮できます。

正規化だけを考えると、定期的な情報は厳密には予定自体の一部ではありません。おそらく、定期的な情報を新しいテーブルに引き出して、関連する予定にのみ関連付けることを検討してください。

于 2013-01-25T17:09:18.863 に答える