我应该商店的日期或复发的规则在我的数据库当建立一个日历的应用程序?

StackOverflow https://stackoverflow.com/questions/4239871

我建立一个日历的网站(ASP.NET MVC)应用程序(为简单的版本,展望)并且我想开始支持日历的事件的经常性(每月、每年,等等)

现在我是保存实际日期在我的但我要找出如果再次发生,它是有意义的继续存储的日期(有一些显而易见的截止),或者我应该商店的重复选项,并生成的日期。

这让我思考如何展望,谷歌邮件等做这个或任何其他服务,支持经常性日历的项目。

是否有任何建议呢?

有帮助吗?

解决方案

(;从再生只读一边产生的日期)的“规范”的数据(重复规则)和“服务”:

分离数据分成两个部分。如果规范数据的变化,在这一点上重新生成“服务”的数据。对于无限复发,保持实例的一些数和产生更如果用完(例如,如果用户查看他们的日历为2020)。

如果你有无限的处理器速度,你只需要标准数据 - 但在现实中,做所有的日期/时间处理所有复发规则的每一个的页面视图可能是太费时间......所以你权衡一些存储(和复杂性),以保存重复计算。存储通常是相当便宜的,与大量的事件所需要的计算比较。如果你的只有的需要存储的事件,这真的很便宜的日期 - 你可以很容易地使用一个4字节整数来表示一个日期,然后生成一个完整的日期/时间,假设你复发是基于所有日期。对于基于时间的复发(如“每三个小时”),你可以充分UTC时刻 - 8个字节将代表降到一个非常精细的分辨率,只要你很可能需要

您需要小心维护的有效性,但 - 如果重复会议修改的今天的,这并没有改变时,它的的过去发生的事情......所以你可能想的的有无规范只读约复发时实际发生的数据。显然,你不希望这样的保持永远的过去,所以你可能想“垃圾回收”事件超过几岁,根据您的存储限制。

您可能还需要对每个个案进行说明和添加例外(如“会议今天不发生因公共假日”或“移动到下午4点”)的能力。变成的真正的,当你改变复发的乐趣 - 如果你“每周一”改为“每星期二”你保持异常或没有?你怎么连当你从“天天向上”,以“每周”更换匹配的异常?这些都不是,它们可直接有关存储的问题 - 但存储决策将影响是多么容易实现你决定什么政策

其他提示

你会需要处理的单独事件和事件。

事件明智的:对活动,你会需要存储recurence规则(它可以是一个rrule样的规定通过rfc5545但也是一个明确的日期,如rdate在rfc5545)但也有例外情况(见exdate的rfc5545和可能exrule为在rfc2445).你也需要跟踪变化的那些规则:变化rdate,exdate都没有问题,当他们在未来发生和被忽略过去的日期。变化rrule更加棘手,因为影响以前出现.我个人喜好是添加一个特定财产对旧的和新的rrule指定他们各自的开始和结束日期的有效性。

如果事件具有有限的时间跨度(说最或直到的财产是本)你应该存储其开始和结束在你的表许更容易查询的活动(特别是当寻找出现的外部预先计算的时间窗口(见下文),它可以有助于减少事件的数量用于其中的计算是可以重复).

出现明智的:对于出现你应该储存的实例,在预定的窗口,围绕本(说+/-6个月或12个月以及计算的定期)和保留记录的这种允许重新计算,如果你的用户希望看到在未来进一步(演出的问题)。你也应该考虑计算的指标(再次发生-ID),以帮助更容易找到的下一个发生。

较小的后端,但更多关于前端,你也应该跟踪tzid变化的要求的用户,如果一个事件被安排在一定tzid如果它的目的是留在当前的时区,它需要更新(认为某人在萨摩亚岛已安排一次会议上星期五,Dec.30 2011年之前,该国决定这一天将不存在),同样可以问,如果一个事件发生在夏令时是意味着"永远不会发生"或"发生两次"(更多关于这一主题 在这里,)

注:你可能想要考虑的支持超出了什么样的定义在rfc5545在recurence的规则和也增加支持的宗教经常性的规则( 见u.s.no介绍日历 或印刷"历法计算"(第三版)从 E.Reingol和N.切磋牌).

因为你问的关于现有的实现,可以很容易地检查了数据库模式的太阳鸟(源码)或 苹果开放源的日历和联络服务器, 更完整的清单的现有开放源码项目的犹豫服务器(这可能是一个子集,你在找什么)提供 在这里,)

我必须建立一个与日程安排配合使用的系统,我们两者都做到了。这就是我们所拥有的

  • 一组跟踪日程表的表。
  • 一个跟踪计划的先前实例(当它们实际发生时)的表
  • 一个跟踪最后一个和下一个实例的表(当下一个项目基于上次发生时)您不需要这个表,但我们使用了它,因为否则您将不断计算一个项目是否应该发生现在正在发生

对于日程安排,事情可能会变得非常棘手,因为您必须记住,日程安排在任何时间点都可能发生变化。此外,当您的应用程序未运行时,某个项目可能会到期,当应用程序再次启动时,您需要知道如何识别逾期项目。

此外,我们还确保跟踪实际时间表的表格是独立的。原因是这些是系统中最复杂的表集,我们希望能够重用它们,以便它们可以用于需要调度的不同事物。例如发送管理电子邮件、发送通知以及清理日志文件等服务器维护。

我肯定会用你的第二个选项。使用不同的频率选项,分别计算和存储它的飞行。存储所有这些日期将是没有必要的数据的一大堆。

下面是一个很好的答案恭维你的问题。结果 数据结构,用于存储定期事件?

此外,作为一个方面说明。我已经开始储存一切作为UTC时间,让你有一个共同的基准,如果你需要使用多个时区。

我在一个Web应用程序类似的问题,我几年前做(有可能是一个更好的办法现在:))。我想包括调度器有重复事件,处理时间,日,周,月,年,和异常的所有功能,这样我就可以有这样的规则:

1)在每天的上午10点除外星期三

2)每2小时用每天最多4次迭代

3)在每月的第一个星期一

等。

存放重复日期/时间是可能的,但不灵活。您的活动每次迭代变化的时候,“最大”是。而如何遥遥领先你看?

在结束我写了一个自定义调度类,可以读取和写入到一个字符串。这是这是存储在数据库中,然后简单的函数可以被调用以找出当下一个出现的字符串。

您需要存储其中的一些是肯定的。该事件的用户可以编辑一个,留下其他不变。(你很可能遇到了一个问题:“是否要修改所有重复事件或仅此一件”的一些日历,即Windows移动)

您也可能希望存储过去的事件,而不是删除它们,当用户删除了重复事件。

如果您存储所有其他人或生成它们是一个实现细节。我宁愿生成它们,如果可能的话。

在任何情况下,你会希望有存储与每个事件的重复事件的一些ID,再加上一些标志告诉你,如果该事件后来被修改。或更复杂的方法,对每个事件属性讲述一个标志,如果它的默认值(从重复事件),或者如果它被修改为这个特定实例。当用户决定编辑反复出现的事件,你会需要这个。

请注意,大多数的答复向保存生成的数据倾斜。但要确保你考虑你的使用情况。

早在天我的服务器受到了IO用大量的CPU无所事事的限制。现在你已经SSD(如果你能买得起的,否则你留下一个老纺纱HD),但需要注意的是内核数量增加了。

有关这几样计算的好处是,你可以轻松地将它们分割,交给你的许多核心或甚至在本地网络中的一些廉价的服务器。往往比建立nosql的群集或去完整数据库集群方式更便宜。

和替代也可能是一个缓存,只是缓存您的日历视图,没有必要做所有的计算,每次当一切都没有改变。

但正如说,这取决于你的使用情况。不要只是按照上面的答案,但做自己的计算,如果你有时间,比作出决定。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top