2009-01-09 28 views
6

我需要存储一次,每天,每周,每周,每周的某几天,每月的某几天可能是数字还是符号,比如每个月的第一个星期一,等等。您将如何存储可能的经常性时间?

有什么建议吗?任何代码,数据结构或模式来看?

回答

1

这听起来像 “复发事件”,如在Outlook中。我会使用一个名为RecurrenceType的表来存储每个时间段(每天,每周等)。另一个名为Event woud的表通过RecurrenceType的键引用。然后可以使用标准日期函数计算大多数重复类型的未来日期。

8

有复杂的解决方案和简单的解决方案。最简单的两个解决方案:

  1. 扇出重复事件多达某个常数许多情况下,或最多在未来的某个固定日期范围。存储FK recurrence_id,每个实例指向重复的描述,并允许批量编辑和取消。

    预定义扇出方法的优点是它可以非常容易地执行重复异常,这几乎肯定会成为您获得的第一个功能请求。

  2. 在显示时间计算。计算机速度很快,取决于您希望能够回答您的数据的问题,计算日期范围内的所有事件通常会非常容易。在进行重复计算之前,您可以很聪明并尝试快速将日期范围括起来,或者可以从发病日期开始蛮力。

除此之外,您只需要一个解决方案来存储重复规则,该规则适用于计算重复出现的任何内容。 (例如,如果您使用的是iCalendar启用库,则您的模式为varchar(255),其中包含RRULE值)

如果您不得不推出自己的重复计算器,并且希望保持简单,您每天,每周,每月或每年的重现率覆盖您的第一个80%用例,并且非常容易计算。

此时你的潜在复发的架构看起来像:

id 
recurrence_start 
recurrence_end 
type (daily|weekly|monthly|yearly) 
day_of_week (for weekly) 
month 
day_of_month 

而与此同时,复杂的解决方案可能是不值得的:)

+0

嘿kellan,您将如何使用您提供的重复模式来实现事件的范围(开始和结束日期)?有任何想法吗?我在设计这样的东西时遇到了很多麻烦。谢谢! – Tom 2014-08-12 03:42:17

1

的问题是,有指定这样的无限可能间隔。例如 - “每隔一个月的第一个星期一,如果日期是偶数,但不是4,并且这个月不是漫长的一年的二月”。你愿意走多远?最终你只需要让用户键入一个布尔表达式,在事件重新发生的日子里,这个布尔表达式的值为TRUE。从用户界面角度看,这不太好。

您应该为您的系统决定一些限制。一旦你知道了这些,其余的应该很容易 - 或者至少在SO上负责。 :)

3

Martin Fowler对此写了a really great paper。您可以在runt中找到许多与他讨论的相同的想法,这是一个用于处理时态表达式的Ruby库。

+1

Fowler的论文清晰易读,但它并不涉及规则的例外情况,IMO是这种设计模式中的一个棘手问题...... – 2009-05-20 11:31:38

0

它提到的a related, useful SO thread,但如果你碰巧使用Ruby是ice_cube一个很好的,积极维护替代小个子。你没有提到你的存储后端需求是什么,但对于数据库模式,@ kellan和上述线程中的一些是好的开始。

相关问题