【发布时间】:2011-03-16 16:37:03
【问题描述】:
我有一个应用程序,用户可以在其中为特定日期范围内的特定实体设置时间表。日程编辑类似于输入日历约会:
- 开始时间和结束时间(小时)
- 开始日期并设置每周重复日期(即每周六和周日或仅每周一)
- 重复结束日期 - 设置重复结束的日期
示例
我想将 2011 年 1 月的周末日程安排为早上 7 点到下午 5 点。
- 我将开始日期设置为 1.1.2011
- 将结束日期设置为 31.1.2011
- 我设置在 7:00 开始,在 17:00 结束
- 在每周重复掩码中启用星期一
然后我还会输入一个与现有时间表重叠但仅针对 1 月上半月的新时间表:
- 设置开始日期 1.1.2011
- 设置结束日期 14.1.2011
- 设置时间从 9:00 到 15:00
- 启用星期一。
问题
我可以将每天的时间表存储在如下表格中:
create table EntitySchedule (
EntityID int not null
references Entity(EntityID),
ForDay date not null,
StartAt time not null,
EndAt time not null
)
但是我会在这个表中得到很多记录:
每个计划的记录数 =(实体记录数)*(计划范围内的天数)
或者我可以存储类似于输入数据的数据:
create table EntitySchedule (
EntityID int not null
references Entity(EntityID),
StartRange date not null,
EndRange date not null,
StartAt time not null,
EndAt time not null,
WeekdayMask tinyint not null -- bitmask of days (7 bits)
default (0)
)
这张表的记录会比前一张少很多。
比较
它们中的每一个(按日表和按时间表)都有其优点和缺点:
- 每天的表格很容易获得特定日期的时间表
- 每日计划无法编辑重复数据,您总是会输入一个覆盖现有数据的新计划
- 几年后,每天的表将有大量记录,必须加以缓解
- 如果按计划表在不计算的情况下获取特定日期的计划是不可能的
- 按计划表允许将计划从一个日期范围复制到另一个日期范围,这将是一项非常受欢迎的功能,只需从不同的日期范围导入计划数据并将其应用于新的日期范围,即可轻松创建计划。
使用场景
不要将此视为我们从个人日历中得知的常规日历约会。而是将其视为非常灵活的商店/商店(实体)营业时间(时间表)。因此,我的数据库将包含许多商店,并且它们的营业时间非常灵活,通常每周重复一次。
编辑时间表通常会覆盖现有数据,因此当定义日期范围内的营业时间已经存在时,我们不会真正更新现有时间表定义,而是创建一个新的时间表定义来覆盖现有数据。如果有每天的时间表,这非常简单。我将覆盖适用于新计划日期范围的那些日子。
但在按计划表的情况下,这变得更加复杂:
- 我可以在表中插入一条新记录,然后在读取特定日期的时间表时最新记录获胜(一种 LIFO 方法)。这意味着每个计划读取(选择)都将包含一个更复杂的查询,我必须返回与特定实体相关的所有记录,这些记录在正确范围内定义日期,然后返回最后一个。这对于获取特定日期的日程安排很好,但是当我想要某个日期范围的日程安排时,我的生活会很艰难......
- 定义的计划范围不重叠,我何时插入新的计划范围也可能意味着应该更改现有计划定义(或其中许多),甚至将其拆分为两个。
第一个似乎是更好的方法。但是查询获取日期范围的时间表变得相当复杂并且可能不是很快。想象一下获取 2011 年 1 月的实体计划。读取数据应始终以每日表的形式产生结果。
问题
是否有任何标准方法来保存计划数据?您建议我如何保存这些数据?
【问题讨论】:
标签: tsql scheduling sql-server-2008-r2