我想写一个日历应用程序。对于数据库架构来说,这是一个经常出现的问题。我想知道如何组织这个的一些意见。
如果用户创建了一个事件,并且输入它会在星期一重复所有人,那该怎么办?我怎么能将所有这些存储在数据库中?我不能创造无限的事件。我只是在那里放一张包含相关信息的表格,以便我可以计算所有事件的去向吗?如果是这样,我每次用户查看日历的新部分时都必须计算它们。如果他们在几个月内翻页,但他们有大量的经常性项目怎么办?
此外,架构需要处理用户单击某个项目并在序列中显示“在序列中编辑此项目”而不是序列中的所有项目。然后我将一个项目从序列中分离出来吗?
更新1
我根本没看过iCal。为了清楚起见,我认为保存允许您计算重复项目的信息,并将任何与序列不同的信息拆分是一种很好的方式来存储它以便能够传输它。但我认为在一个应用程序中,这将太慢,无法在整个地方进行日期数学运算。
答案 0 :(得分:14)
我一直在努力解决同样的问题,而我实际上是在玩弄上面提到的“缓存表”这个想法,但后来我遇到了一个似乎没有被代表的替代方案(suggested here)爱好。
构建包含所有事件的表
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和用于选择系列中特定事件的实例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
似乎保持事件表的规范化,并避免拆分系列来处理异常。
答案 1 :(得分:12)
我最近创建了一个日历应用程序,这是我遇到的众多挑战之一。
我最终想出了一个半黑客解决方案。我创建了一个event_type
列。在该列中,我有:daily
,weekly
,monthly
或yearly
。我还有start_date
和end_date
列。其他所有内容都在实际的后端代码中处理。
如果用户只编辑了一个事件,我从未尝试拆分事件。在这种情况下没有必要。但是,您可以通过更改第一个的end_date来分割事件,使用原始的start_date
和end_date
创建新事件,最后为您刚刚选择的事件创建一个新事件编辑。这个过程最终会创建3个事件。
答案 2 :(得分:3)
正常按住事件表中的定期项,但标记为具有相应的开始/结束日期的重复项。
如果用户修改了约会的单个实例,只需创建一个新事件,可能是'parentId'等于周期性事件的id。
构建逻辑,使日历覆盖特定日期的任何重复事件,并使用具有匹配父ID的事件。
关于性能的问题基本上是旧的速度与存储问题。我真的不认为所需的计算会超过存储这么多约会的空间要求。只需阅读数据库优化 - 索引等。
答案 3 :(得分:3)
依靠Google Calendar's API存储和检索日历活动,为什么不将Google日历用作此日历应用程序的数据库?
Calendar API是一个可以通过显式HTTP调用访问的REST API; API公开了Google Calendar Web界面中提供的大部分功能,因此您的日历应用程序可以提供与Google Calendar一样多的功能(很多功能!!!)。
您的应用程序只需要为Google API实施OAuth 2.0,使用Auth0等单点登录服务即可轻松实现,以提供相应的访问令牌。然后,您的日历应用程序可以将这些令牌与Calendar API结合使用,以JSON格式提供日历事件的无缝存储和检索。
用户在自己的“新日历”中创建活动。此日历将以专用于此应用程序的Gmail帐户的形式与您共享 - 应用程序的Gmail帐户。
基本上,Google日历会成为您的数据库,您可以应用程序的gmail帐户,不仅可以存储所有应用程序的事件,还可以使用直观的界面查看和编辑这些事件。
答案 4 :(得分:2)
你能用一个“缓存”表来桥接这两个世界,在这个表中你预先计算下一个X天的事件吗?
所以有三个表:
recurring_event_specs
one_time_events
cached_recurring_events
对于今天X天内日历的任何部分,您的查询将为UNION one_time_events
和cached_recurring_events
。
然后,如果用户试图在将来超过X天查看日历的一部分,那么您只需要进行即时日期计算。我想你可以找到一个能够覆盖大部分正常使用的理智X.
只要用户通过cron-job / scheduled-task添加新的周期性事件(可能每天一次离线),就需要更新cached_recurring_events
表。但仅限于没有创建新的重复活动的日子。
答案 5 :(得分:0)
执行此操作的最佳方法是存储基于标准的重复发生模式字符串(iCal)..如果是单个事件,则留空。有一些API可以解析重复发生模式并创建可以绑定到UI元素的事件对象....没有任何事件需要存储在数据库中,只有初始事件(发生)..
答案 6 :(得分:0)
您是否无法按开始和结束时间存储事件?它会为每天发生的事件生成大量数据(可能是非关系型的),但它会使查询更容易,并且可能会产生异常(例如,事件处被烧毁,或员工都很惊人)。为了生成事件的日子,我建议在前端实现一些ICal-ish模式。