我应该如何(如何)在数据库中保存计划

时间:2011-03-16 07:02:08

标签: tsql scheduling sql-server-2008-r2

我有一个应用程序,用户可以在特定日期范围内为某个实体设置日程安排。计划编辑与输入日历约会类似:

  • 开始时和结束时(小时)
  • 开始日期并设定每周复发天数(即每周六和周日或仅在每个Moday)
  • 重复日期结束 - 设置重复结束的日期

实施例

我想在2011年1月的上午7点到下午5点设定周末时间表。

  1. 我将开始日期设为1.1.2011
  2. 将结束日期设为31.1.2011
  3. 我在7:00开始,在17:00结束
  4. 在每周复发掩码上启用星期一
  5. 然后我还会输入一个新的时间表,与现有的时间表重叠,但仅限于1月的上半部分:

    1. 设定开始日期1.1.2011
    2. 设置结束日期14.1.2011
    3. 从9:00到15:00设置时间
    4. 启用星期一。
    5. 问题

      我可以在以下表格中存储每天的时间表:

      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)
      )
      

      此表的记录数比前一个记录少得多。

      比较

      每一个(每日表和每个时间表)都有其优点和缺点:

      1. 每天的表格很容易获得特定日期的时间表
      2. 每日时间表不可能编辑重复数据,您总是会输入覆盖现有数据的新时间表
      3. 每天使用几年后,表中会有大量的记录需要减轻
      4. 如果没有计算,则每个计划表无法在特定日期获取计划
      5. 每个计划表允许将计划从一个日期范围复制到另一个日期范围,这将是一个非常受欢迎的功能,通过简单地从不同的日期范围导入计划数据并将其应用于新的日期范围,可以简化创建计划。
      6. 使用场景

        不要将此视为我们通过个人日历了解的常规日历约会。而是将其视为非常灵活的商店/商店(实体)营业时间(时间表)。因此,我的数据库将拥有许多商店,并且他们的营业时间非常灵活,通常每周重复一次。

        编辑计划通常是对现有数据的覆盖,因此当在已定义的日期范围内的开放时间已经存在时,我们不会真正更新现有的计划定义,而是创建一个覆盖现有计划的新计划。如果有每日时间表,这很简单。我只是覆盖那些适用于新计划日期范围的日子。

        但是在每个计划表的情况下,这变得更加复杂:

        1. 我可以在表格中插入新记录,然后在阅读特定日期的最新记录获胜时(LIFO方式)。这意味着每个调度读取(选择)将包括更复杂的查询,其中我将必须返回与特定实体相关的所有记录,这些记录定义正确范围内的日期,然后返回最后一个。这对于获取特定日期的日程安排很好,但是当我想要日程范围的日程安排时,这会让我的生活变得艰难...
        2. 定义的计划范围不重叠,当我插入新的计划时,也可能意味着应该更改现有的计划定义(或许多计划定义),甚至拆分为两个。
        3. 第一个似乎是一个更好的方法。但是获取日期范围的时间表的查询变得相当复杂,可能不是很快。想象一下获得2011年1月的实体时间表。读取数据应始终以每日表的形式产生结果。

          问题

          是否有标准方法来保存计划数据?您如何建议我应该保存这些数据?

2 个答案:

答案 0 :(得分:0)

我曾几次与这个问题搏斗过。我认为最好的方法是将开始日期/时间和结束日期/时间存储为开始和结束的单个字段,或者按照建议将日期和单独的时间字段存储。

我认为这是最灵活的,虽然它需要在您的应用层进行更多计算以重复计划等,但它是所有备选方案中“最不好的”。我不确定它是一种标准方式。

PS。我曾经实现了一个系统,其中一年中的每一天都有一个表中的记录和一个单独的表存储了当天使用的所有时间表,但它只是变得比它的价值更麻烦,因为它需要在应用层上进行大量编码,但在不同的地方。使用日期/时间我认为是最好的解决方案。

答案 1 :(得分:0)

我不知道存储计划数据的任何标准方法。

我会选择第二种方法 - 存储创建日程所需的数据,因为这是用户定义的(例如,考虑如何从“每日”表加载以便允许用户编辑他们的日程安排 - 这将是棘手的!)。

我会在上面添加一个“上次运行”字段,然后根据你将如何使用它,“下一次运行”Computed Column将使用行中的其他信息计算下次应该发生此预定事件的时间。这将允许您从数据库中“执行今天发生的所有事件”。

编辑:现在你已经澄清了关于开放时间的问题(你需要能够列出日程安排的时间),而不是我假设的在任务调度程序中,您需要的是“下次运行”时间,“下次运行”字段不太有用。

然而,我仍然会存储计划数据,因为这实际上是商店将定义的内容(他们会说“我们希望在工作日的9-5之间打开”,而不是“我们” ll打开9-5下一个星期一,星期二,星期三,星期四,星期五然后下一个星期一......“)。虽然我很欣赏它使一些事情变得更复杂,但存储它并获得实际的日常数据会更准确。您仍然可以使用存储过程或基于表的用户定义函数,以便能够选择日常数据。此实施将再次取决于您的使用场景 - 您是否只想列出每个商店的营业时间,或者您是否希望具有“获取所有在XX上营业的商店?”的功能。