【问题标题】:Laying out a database schema for a calendar application为日历应用程序布置数据库模式
【发布时间】:2011-06-06 21:27:21
【问题描述】:

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

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

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

更新 1

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

【问题讨论】:

  • “然后我是否将一个项目从序列中拆分出来?”我相信这就是 iCal 文件格式处理它的方式。你研究过那种格式吗?
  • 多么好的问题,前几天我自己也在想这个问题。

标签: database schema calendar normalization


【解决方案1】:

我一直在为同样的问题苦苦挣扎,实际上我在玩弄上面建议的“缓存表”想法,但后来我遇到了一个似乎还没有出现的替代方案 (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

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

【讨论】:

  • 你能发布/分享你最新的架构吗
【解决方案2】:

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

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

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

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

【讨论】:

  • 是的,这或多或少是我的想法,但你不会因为所有这些日期计算而受到性能影响吗?
  • 是的,但我认为有必要。如果没有大量后端代码,我无法想出一个干净的方法来处理数据库。
  • 我可以获得日历事件调度程序数据库架构,它可以让我知道我可以使用哪些表吗?
  • @Tejinder 请参考此链接:vertabelo.com/blog/technical-articles/…
【解决方案3】:

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

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

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

用户在自己的“新日历”中创建活动。此日历以专用于此应用程序的 gmail 帐户的形式与您共享 - 应用程序的 gmail 帐户

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

【讨论】:

  • 虽然这可能是一个解决方案,但 OP 专门寻求帮助设计数据库架构。
【解决方案4】:

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

【讨论】:

  • OP 的问题是你如何处理无限的结束日期。
【解决方案5】:

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

【讨论】:

  • 使用此方法,如何在不完整解析每个项目的字符串的情况下,选择指定时间内所有发生的事件?
【解决方案6】:

您能否使用“缓存”表连接两个世界,在其中预先计算接下来 X 天的事件价值?

所以三个表:

recurring_event_specs
one_time_events
cached_recurring_events

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

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

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

【讨论】:

    【解决方案7】:

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

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

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

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

    【讨论】:

    • 我担心的不是数据库性能。它是做日期数学的后端代码。所以如果我说,这个活动是每个第三个星期一,从 08 年开始,永无止境,现在是 2010 年,你必须弄清楚它在你的日历上的哪个位置。也许这并不像我想象的那么激烈。
    • 你只需要在可见的日期范围内计算出来。就像我正在查看三个月一样,您只需计算这些月。您只需要检索每天的每条记录,然后检索每条重复记录(只需一次),并找出每个记录适用于可见范围内的哪一天。我看不出它太严重了。
    猜你喜欢
    • 2013-07-23
    • 2012-06-12
    • 2010-12-03
    • 2012-10-13
    • 2018-01-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多