我正在处理这个问题,并且我已经完全分开了iCalendar(rfc 2445)直到阅读此主题,所以我不知道这将如何以及将不会与其整合。无论如何,我现在提出的设计看起来像这样:
- 你不可能存储所有的循环事件的实例,至少不会发生之前,所以我只有一个表将事件的第一个实例存储为实际日期,可选过期以及可以为空的repeat_unit和repeat_increment字段来描述重复。对于单个实例,重复字段为空,否则单位将是“日”,“周”,“月”,“年”,增量仅仅是要添加到下一次出现的开始日期的单位的倍数。
- 如果您需要与模型中的其他实体建立关系,则存储过去的事件似乎很有用,即使这样,在每种情况下都不需要有明确的“事件实例”表。如果其他实体已经有日期/时间“实例”数据,那么该事件的外键(或多对多连接表)最有可能就足够了。
- 要做“改变这个实例”/“改变所有未来实例”,我打算重复这些事件并过期。因此,要更改单个实例,您将在最后一次出现时过期旧的副本,为更改后的新发生的独特副本复制副本,并在下列情况下重复发送原始副本未来。更改所有未来的实例是相似的,您只需要将原始文件过期,并根据更改和授权详细信息制作新的副本。
这两个问题我有这样的设计见到目前为止是:
- 它使MWF类型的事件很难代表。这是可能的,但是迫使用户创建三个单独的事件,每个事件每周重复M,W,F,并且他们想要作出的任何更改都必须单独完成。这些事件在我的应用程序中并不是特别有用,但它确实给模型留下了一个瑕疵,使得它不如我想要的那么普遍。
- 通过复制事件进行更改,可以中断它们之间的关联,这在某些情况下可能很有用(或者,也可能偶尔会出现问题)。事件表理论上可以包含一个“copied_from”id字段,用于跟踪一个事件发生的地方,但我还没有完全想到这样的事情会有多么有用。首先,父/子层次关系对于从SQL进行查询是一种痛苦,所以好处将需要相当大的重量才能超过查询数据的成本。我想可以使用nested-set。
最后,我认为这是可能计算采用直板SQL对于给定的时间跨度的事件,但我还没有制定出具体细节,我想查询通常最终会过于麻烦是值得的。然而,对于论证起见,你可以使用下面的表达式来计算的差异月给出的年份和月份之间的事件:
(:month + (:year * 12)) - (MONTH(occursOn) + (YEAR(occursOn) * 12))
大厦的最后一个例子,你可以使用MOD以确定是否差异月是正确的多:
MOD(:month + (:year * 12)) - (MONTH(occursOn) + (YEAR(occursOn) * 12), repeatIncrement) = 0
反正这是不完美(它不会忽略过期事件,在开始/结束时间为事件等不因子),所以它仅作为一个激励的例子。一般来说,尽管我认为大多数查询最终会变得太复杂。您最好查询在给定范围内发生的事件,或者不要在范围之前过期,并使用代码而不是SQL来计算实例本身。如果你真的想要数据库进行处理,那么存储过程可能会让你的生活变得更容易。