为日历应用程序布置数据库模式

我想写一个日历应用程序。 这是真正反复出现的项目,在数据库模式的作品中引发了一场风波。 我会喜欢一些关于如何组织这个的input。

如果用户创build一个事件,并input它重复每个星期一,永远? 我怎么能把所有的数据存储在数据库中? 我无法创造无限的事件。 我只是简单地把一张桌子放在那里,有相关的信息,所以我可以计算出所有事件发生的地方? 如果是这样,每次用户查看日历的新部分,我将不得不计算它们。 如果他们翻阅了几个月,但他们有很多经常性的项目呢?

此外,模式需要处理,当用户点击一个项目,并说“编辑序列中的这一个”不是序列中的所有项目。 然后我把这个项目从序列中分离出来吗?

更新1

我还没有看过iCal。 为了清楚起见,我认为保存可以计算重复项目的信息,并且将不同于顺序的项目分开是一种很好的方式来存储它,以便能够传输它。 但是我认为,在一个应用程序中,这太慢了,要把date算到所有的地方。

我最近创build了一个日历应用程序,这是我面临的众多挑战之一。

我最终提出了一个半黑客解决scheme。 我创build了一个event_type列。 在那一栏中,我有:“每日”,“每周”,“每月”或“年”。 我也有一个start_date和end_date列。 其他的一切都是在实际的后端代码中处理的。

如果用户只编辑一个事件,我从来没有尝试过分割一个事件。 这种情况没有必要。 但是,您可以通过更改第一个事件的end_date来分割事件,使用新的开始date和原始的end_date创build一个新事件,最后为您刚才select编辑的事件创build一个新事件。 这个过程最终会创build3个事件。

哈哈,我知道。 当时我想不出一个聪明的办法来解决这个问题。

我一直在为同样的问题而苦苦挣扎,实际上我正在玩弄上面提到的“caching表”的想法,但后来我遇到了一个似乎还没有被代表的替代scheme( 在这里build议 )。

build立一个包含所有事件的表格

EventID (primary key) Description StartDate PeriodType - days, weeks, months, years PeriodFreq - # of days, weeks, etc between events EndDate ... other attributes that can be modified 

然后为这些事件的例外添加一个表。 此表使用由映射到事件表的EventID组成的组合键和用于select系列中特定事件的实例ID。

 EventID (key) InstanceID (key) InstanceDate - the modified date of the exception IsCancelled - a flag to skip this date when traversing the series ... other attributes that can be modified 

它似乎保持事件表正常化,并避免分裂系列来处理exception。

为什么不使用Google日历的API来存储和检索日历事件呢?

Calendar API是可以通过显式HTTP调用访问的REST API; 该API公开了Google日历Web界面中的大部分function,因此您的日历应用程序可以像Google日历一样具有很多function(很多function!!!)。

您的应用程序只需要为Google API实施OAuth 2.0,使用Auth0等单点login服务即可轻松提供适当的访问令牌。 然后,日历应用程序可以将这些令牌与Calendar API结合使用,以JSON格式提供日历事件的无缝存储和检索。

用户在自己的“新日历”中创build事件。 这个日历以专用于此应用程序的gmail帐户的forms与您共享 – 该应用程序的gmail帐户

基本上,Google日历成为您的数据库,您可以让应用程序的Gmail帐户不仅存储您的应用程序的所有事件,而且还允许您用直观的界面查看和编辑这些事件。

按正常情况保留事件表中的重复项目,但标记为具有适当的开始/结束date的重复项目。

如果用户修改了一个约会的单个实例,只需创build一个新的事件,或许使用与重复事件的ID相等的“parentId”。

构build导致日程表使用匹配父ID的事件覆盖特定date的任何周期性事件的逻辑。

你关于性能的问题基本上是旧的速度与存储问题。 我真的不认为所需的计算会超过存储这么多预约的空间要求。 只是阅读数据库优化索引等

你能用“caching”表来连接这两个世界吗?在这个表中,你预先计算了下一个X天的事件?

所以三个表:

 recurring_event_specs one_time_events cached_recurring_events 

对于今天X日内的日历的任何部分,您的查询将UNION one_time_eventscached_recurring_events

那么如果用户在将来试图查看超过X天的部分日历,则只需要进行即时date计算。 我想你可以find一个理智的X将覆盖大部分正常使用。

每当用户通过cron-job / scheduled-task添加新的定期事件(可能每天脱机一次)时,都需要更新cached_recurring_events表。 但只有在没有新的经常性事件产生的日子里。

要做到这一点,最好的方法是存储一个基于标准的重复模式string(iCal)..并保留空白,如果它是一个单一的事件。 有几个API可以parsing重复模式,并创build可以绑定到UI元素的事件对象….没有一个事件需要永远存储在数据库中,只有初始事件(发生)..

你能不能每天用开始和结束时间存储事件? 它会为每天发生的事件生成大量的数据(也许这是非关系的),但这样会使查询变得更容易,并且可能会出现exception情况(事件地点被烧毁或者员工非常惊讶)。 为了生成这个事件的日子,我会build议在ICal-ish模式的前端实现。