54

我想写一个日历应用程序。确实是反复出现的项目对 DB 模式的工作造成了影响。我很想就如何组织这个问题提供一些意见。

如果用户创建一个事件,并输入它在星期一每个人都重复,永远?我如何将所有这些存储在数据库中?我无法创建无限事件。我是否只是在其中放置一个包含相关信息的表格,以便我可以计算所有事件的去向?如果是这样,每次用户查看日历的新部分时,我都必须计算它们。如果他们浏览了几个月,但他们有大量的经常性项目怎么办?

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

更新 1

我根本没有看过 iCal。需要明确的是,我认为保存允许您计算重复项目的信息,并拆分任何与序列不同的信息是存储它以便能够传输它的好方法。但我认为在应用程序中,这太慢了,无法在所有地方进行日期数学运算。

4

7 回答 7

24

我一直在努力解决同样的问题,实际上我是在玩弄上面建议的“缓存表”想法,但后来我遇到了一个似乎还没有被代表的替代方案(这里建议)。

建立一个包含所有事件的表

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

它似乎保持事件表规范化,并避免拆分系列来处理异常。

于 2012-05-19T11:05:07.490 回答
15

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

我最终想出了一个半黑客式的解决方案。我创建了一个event_type专栏。在该专栏中,我有:dailyweeklymonthlyyearly。我也有一个start_date和一个end_date专栏。其他一切都在实际的后端代码中处理。

如果用户只编辑了一个事件,我从不尝试拆分事件。在这种情况下没有必要。start_date但是,您可以通过更改第一个事件的 end_date 来拆分事件,使用新事件和原始事件创建一个新事件end_date,最后为您刚刚选择编辑的事件创建一个新事件。这个过程最终会创建 3 个事件。

我知道。当时我想不出一个聪明的方法来处理这个问题。

于 2009-06-03T21:15:37.740 回答
4

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

如果用户修改了约会的单个实例,只需创建一个新事件,其“parentId”可能等于重复事件的 id。

构建逻辑,使日历使用具有匹配父 ID 的事件覆盖特定日期的任何重复事件。

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

于 2009-06-03T21:21:07.637 回答
3

你能用一个“缓存”表来连接这两个世界,你可以在其中预先计算接下来 X 天的事件价值吗?

所以三个表:

recurring_event_specs
one_time_events
cached_recurring_events

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

然后,如果用户试图在未来 X 天以上查看日历的一部分,那么您只需进行即时日期计算。我想你可以找到一个理智的 X 来覆盖大部分的正常使用。

cached_recurring_events每当用户添加新的重复事件时,都需要更新该表 - 并且可能每天通过 cron-job/scheduled-task 离线一次。但仅限于没有创建新的重复事件的日子。

于 2009-06-03T21:24:57.800 回答
3

为什么不使用 Google 日历作为此日历应用程序的数据库,依靠Google 日历的 API来存储和检索日历事件?

Calendar API 是一个 REST API,可以通过显式 HTTP 调用进行访问;该 API 公开了 Google 日历 Web 界面中可用的大部分功能,因此您的日历应用程序可以提供与 Google 日历一样多的功能(很多功能!!!)。

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

用户在他们自己的“新日历”中创建事件。此日历以专用于此应用程序的 gmail 帐户(应用程序的 gmail 帐户)的形式与您共享。

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

于 2016-07-05T10:31:44.787 回答
1

最好的方法是存储基于标准的重复模式字符串 (iCal).. 如果它是单个事件,则留空。有一些 API 可以解析重复模式并创建可以绑定到 UI 元素的事件对象......所有事件都不需要存储在数据库中,只有初始事件(发生)......

于 2010-09-16T05:33:59.353 回答
0

你不能用开始和结束时间存储每天的事件吗?它将为每天发生的事件生成大量数据(可能与此无关),但它会使查询更容易,并且可能会出现异常(例如事件地点被烧毁或员工罢工)。为了生成事件的日期,我建议在前端实现它,该前端源自一些 ICal-ish 模式。

于 2014-05-23T09:05:12.090 回答