重复事件数据库模型
Posted
技术标签:
【中文标题】重复事件数据库模型【英文标题】:Recurring Events Database Model 【发布时间】:2018-10-16 16:12:13 【问题描述】:我一直在寻找重复事件的解决方案,到目前为止,我找到了两种方法:
第一种方法:
为每个事件创建一个实例,因此如果用户有一年的每日事件,则表中需要 365 行。 对于固定的时间范围,这听起来似乎是合理的,但是如何处理没有结束日期的事件呢?
第二种方法:
创建一个循环模式表,使用某种时间表达式在运行时创建未来事件 (Martin Fowler)。
有什么理由不选择第一种方法而不是第二种方法吗? 第一种方法会过度填充数据库并可能影响性能,对吧?!
关于方法 1 的引述说:
“将重复事件存储为单独的行是灾难的根源。” (https://github.com/bmoeskau/Extensible/blob/master/recurrence-overview.md)
你们怎么看?我想了解一下为什么那会是一场灾难。
感谢您的帮助
【问题讨论】:
【参考方案1】:正确的答案确实是both,并且不是either or。
暂时不考虑重复没有结束日期的问题:您想要的是一个包含整个模式的重复规则的标题。这样,如果您需要更改模式,您可以在单个记录中捕获该模式,可以在不冒更新异常风险的情况下对其进行编辑。
现在,在 SQL 中加入某种重复模式将是一件令人头疼的事情。此外,如果您的规则允许您调整(编辑甚至删除)此重复模式的特定实例,该怎么办?
你如何处理这个问题?您必须创建一个实例表,其中每个重复实例具有一行,并带有一个链接(外键)返回用于创建它的单个规则。这让您可以修改单个子元素,而不会忘记它的来源,以防您需要编辑(或删除)整个模式。
考虑使用 Outlook 或 Google 日历等日历工具。这些应用程序使用这种方法。您可以移动或编辑实例。您也可以更改整个系列。每当您进入编辑模式时,这些应用都会询问您打算做什么。
对此有一些限制。例如,如果您编辑一个实例然后编辑模式,您需要有一条规则,说明 (a) 新父级获胜或 (b) 修改后的子级总是获胜。我认为 Outlook 和 Google 日历使用方法 (a)。
至于为什么要明确记录每个实例,我能想到的唯一灾难性的事情是,如果您没有返回原始重复模式的链接,您将不得不一次取消整个系列的动作。
返回没有结束日期 - 这可能是一种谨慎的情况,它是勇气的更好部分,并使用某种经验法则,对你延伸到多远的未来施加实际限制这样的系列 - 或者您不能在模式中允许这种规则。强制终止该模式,让规则的创建者担心在将来需要的任何时候扩展它。
【讨论】:
no end date
是最简单的部分 - 上升到 2525-01-01 并使其成为 somebody else's problem.
@ArmandoBallaci,你能再检查一下吗?我看不到这种行为。它会在模式更新后覆盖对特定事件的所有更改。不会保留任何时间或标题更改。
@skovorodkin 我对它进行了测试,现在它似乎工作得更好了。当我正在开发一个日历应用程序时,这真的很痛苦
Google 日历使用@ZoharPeled 提到的方法。他们在 2100 年停止了所有重复发生的事件。未来的人们将不得不弄清楚如何回填这些数据,而不是他们。
有人对此评论有任何示例架构吗?我正在努力实现这一点,因为我不确定如何构建数据。另外,重复模式是否应该遵循 iCal 重复模式字符串?【参考方案2】:
将日历的事件存储为规则,而不仅仅是作为具体化事件。
将重复的事件作为一行具体化存储是灾难的根源,原因很明显,理想化的实现将是无限长的。由于无限长表是不可能的,因此开发人员将尝试使用一些聪明的、不全面的技巧来模仿这种行为 - 导致应用程序的行为不稳定。
我的建议:存储规则并将它们具体化并添加为行,仅在查询时 - 导致混合方法。
因此,您将有两个表来存储您的信息,第一个用于存储规则,第二个用于存储从规则表中的任何规则具体化的行。
一般准则可以是:
对于一次性事件,在第二个表中添加一行。 对于经常性事件,在第一个表中添加一行并将其中的一些具体化到第二个表中。 对于未来日期的查询,具体化规则并将它们保存在第二个表中。 对于重复事件的特定实例的修改,将事件具体化直到要修改的实例,然后修改最后一个实例并存储它。 此外,如果事件在未来太远,请不要实现它。而是将其另存为规则,并在时间到来时稍后执行。普通表不足以存储您要保存的内容。当存储过程支持访问和修改时,最好在数据库中保留此类信息。
【讨论】:
【参考方案3】:来自博文中的答案和此处的答案:
1- 吃掉这些重复的数据库存储和内存(不需要),极端情况是“没有结束日期”
2- 影响性能(查询/加入/更新/...)
3- 在更新的情况下(或者通常在任何情况下,您需要将重复集作为一个集合而不是单个事件来处理),您将需要更新所有行
【讨论】:
以上是关于重复事件数据库模型的主要内容,如果未能解决你的问题,请参考以下文章
我想要一个自定义的、可重复使用的子视图,它可以了解模型和生命周期事件