具有重复特征的议程应用的数据库模型

时间:2013-01-25 17:00:52

标签: database-design architecture

我正在寻找一个简单的议程应用程序的数据库模型,但我找不到任何。 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来获取约会结束时间。
  • 约会可以持续一整天,IsAllDayEvent = 1。在这种情况下,不需要字段StartTime和DurationInMinutes。
  • 重复功能将由应用程序代码计算。即使预约是经常性的,它也只在数据库中注册一次,并且应用程序负责计算重复约会的日期,然后在日历中显示这些日期。为了帮助应用程序更好地执行,应用程序可以在仅在日历中显示的时间段内进行数学运算。通过在某处缓存这些计算可以实现进一步的性能,当用户更改重复设置或删除约会时将其逐出。
  • 通过查看RecurrenceCountRecurrenceEndDate字段来确定重复约会的次数。其中只有一个应该一次包含一个值。
  • 此模型支持编辑系列中的一个或多个约会。这就是ParentAppointmentId的用途。假设有一个名为“示例约会”的周期性约会,配置为每天重复5次。然后假设用户选择仅编辑该系列的第三个约会,将其名称更改为“更新的约会”。这将导致应用程序复制数据库中的原始约会记录,但使用新名称,并使其引用原始约会(父级)。应用程序有责任检测到系列中有不同属性的约会,并在计算日历中显示的重现时将其考虑在内,如前所述。
  • 仍然关于ParentAppointmentId功能:用户可以取消系列中的一个或多个约会。例如。 “我希望这个事件发生在所有星期四,但不是在那个具体的星期四”。这将再次进行上述复制过程,但将子约会IsCancelled字段设置为1(true)。然后,应用程序应在日历中显示系列时“隐藏”此特定约会。
  • 仍然关于ParentAppointmentId功能:为了简化应用程序逻辑,并遵循Outlook模型,当用户更改原始约会的重复周期设置(导致重新计算整个系列)时,子约会将丢失。

嗯,我认为就是这样。请告诉我,如果您同意这种方法,或者如果您不同意,如果不采取完全不同的方法,您会改变什么。

提前致谢。

2 个答案:

答案 0 :(得分:1)

我不确定你在做什么可怕的事......

一个想法是完全打破parentAppointmentId并构造一个新的关联表,它只链接两个任意的appointements。然后,您可能会添加一些角色或类型列来确定正在定义的关系类型。

通过这种方式,您可以灵活地允许系列中更多的复杂关联(例如跳过 - 重命名等)以及允许一个约会可能是结果或可能跟随许多其他约会的可能性 - 不是只有一个。

当只考虑规范化时 - 重复信息也不是约会本身的一部分。或许可以考虑将重复信息提取到新表并仅关联到相关约会。

答案 1 :(得分:1)

晚会:)但我喜欢这个设计和考虑因素。对于未来的任何人, WeeklyRecurrenceDays 的一个建议是使用整数,然后将您的日期定义为位字段; 1 =星期日,2 =星期一,4 =星期二,8 =星期三,16 =星期四,32 =星期五,64 =星期六

使用简单的AND功能,客户端应用程序可以确定选择了哪些天数,而无需解析字段中包含的文本。

示例:5 = sunday&星期二; 127 =将是所有日子; 62 =工作日; 65 =周末