为日历应用程序设计数据库架构
我想写一个日历应用程序。确实是重复出现的项目给数据库模式的工作带来了麻烦。我希望得到一些关于如何组织这个的意见。
如果用户创建一个事件,并输入该事件在每个星期一重复,永远,该怎么办?我如何将所有这些存储在数据库中?我无法创造无限的事件。我是否只需在其中放置一个包含相关信息的表格,以便我可以计算所有事件的去向?如果是这样,每次用户查看日历的新部分时,我都必须计算它们。如果他们翻阅月份,但有大量重复出现的项目怎么办?
此外,当用户单击某个项目并显示“编辑序列中的此项”而不是序列中的所有项目时,架构需要进行处理。然后我是否要将一项从序列中分离出来?
更新 1
我根本没有看过 iCal。需要明确的是,我认为保存允许您计算重复项目的信息,并拆分任何与序列不同的信息是存储它以便能够传输它的好方法。但我认为在应用程序中,这太慢了,无法在各处进行日期数学计算。
I want to write a calendar application. It is really recurring items that throw a wrench in the works for the DB schema. I would love some input on how to organize this.
What if a user creates an event, and inputs that it repeats everyone Monday, forever? How could I store all that in the database? I can't create infinite events. Do I simply put a table in there that holds the relevant info so I can calculate where all the events go? If so, I would have to calculate them every time the user views a new part of the calendar. What if they page through the months, but they have a ton of recurring items?
Also, the schema needs to handle when a user clicks an item and says "Edit this one in the sequence" not all items in the sequence. Do I then split the one item off of the sequence?
Update 1
I have not looked at iCal at all. To be clear, I think saving the info that allows you to calculate the recurring items, and splitting off any that differ from the sequence is a great way to store it to be able to transfer it. But I think that in an application, this would be too slow, to do the date math all over the place.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
我一直在努力解决同样的问题,实际上我正在考虑上面建议的“缓存表”想法,但后来我遇到了另一种选择(此处建议),但似乎尚未得到体现。
构建一个包含所有事件的表
,然后为这些事件添加一个例外表。该表使用复合键,由映射到事件表的 EventID 和用于选择系列中特定事件的实例 ID 组成。
它似乎使事件表保持标准化,并避免分割系列来处理异常。
I have been struggling with the same problem, and I was actually toying with the "cache table" idea suggested above, but then I came across an alternative (suggested here) that doesn't seem to have been represented yet.
Build a table containing all events
Then add a table for exceptions to these events. This table uses a composite key, made up of the EventID that maps to the event table, and an instance ID to pick the particular event in the series.
It seems to keep the event table normalised, and avoids splitting up series to handle exceptions.
我最近创建了一个日历应用程序,这是我面临的众多挑战之一。
我最终想出了一个半黑客式的解决方案。我创建了一个
event_type
列。在那一栏中,我有:每日
、每周
、每月
或每年
。我还有一个start_date
和一个end_date
列。其他一切都在实际的后端代码中处理。如果用户只编辑一个事件,我从未尝试过拆分事件。在当时的情况下没有必要。但是,您可以通过更改第一个事件的结束日期来拆分事件,使用新的
start_date
和原始事件的end_date
创建一个新事件,最后创建一个新事件对于您刚刚选择编辑的那个。此过程最终将创建 3 个事件。黑客风格,我知道。我当时想不出一个巧妙的方法来处理这个问题。
I recently created a calendar application and this was one of the many challenges that I faced.
I eventually came up with a semi hack-ish solution. I created an
event_type
column. In that column, I had either:daily
,weekly
,monthly
, oryearly
. I also had astart_date
and anend_date
columns. Everything else was handled in the actual backend code.I never tried to split an event if a user edited only one event. It wasn't necessary in the situation. However, you could split an event by changing the end_date of the first, creating a new event with a new
start_date
and theend_date
of the original, and finally, a new event for the one you just chose to edit. This process would end up creating 3 events.Hack-ish, I know. I couldn't think of a clever way to handle this problem at the time.
像往常一样将重复项目保留在事件表中,但使用适当的开始/结束日期标记为重复项目。
如果用户修改约会的单个实例,只需创建一个新事件,其“parentId”可能等于重复事件的 ID。
构建逻辑,使日历用具有匹配父 ID 的事件覆盖特定日期的任何重复事件。
您关于性能的问题基本上是旧的速度与存储问题。我真的不认为所需的计算会超出存储这么多约会的空间要求。只需阅读数据库优化 - 索引等。
Hold the recurring item in the events table as normal, but flagged as recurring with the appropriate start/ end dates.
If the user modifies a single instance of the appointment, just create a new event, perhaps with a 'parentId' equal to the recurring event's id.
Build logic that causes the calendar to override any recurring events on a particular day with events with matching parent IDs.
Your question about performance is basically the old speed vs. storage issue. I really don't think the calculation required would exceed the space requirement for storing so many appointments. Just read up on database optimization- indexing etc.
您能否使用“缓存”表来桥接这两个世界,在该表中预先计算接下来 X 天的事件价值?
因此,三个表:
对于今天 X 天内日历的任何部分,您的查询将 UNION
one_time_events
和cached_recurring_events
。然后,如果用户尝试在未来 X 天以上查看日历的一部分,则只需进行动态日期计算。我想你可以找到一个可以满足大部分正常使用的健全的 X。
每当用户添加新的重复事件时,
cached_recurring_events
表就需要通过 cron-job/scheduled-task 进行更新,并且可能每天离线更新一次。但仅限于没有创建新的重复事件的日子。Could you bridge the two worlds with a "cache" table, in which you pre-compute the next X days worth of events?
So three tables:
For any part of the calendar within X days of today, your query will UNION
one_time_events
andcached_recurring_events
.Then you would only have to do on-the-fly date calculations if the user tried to look at a part of the calendar more than X days in the future. I imagine you could find a sane X that would cover the majority of normal use.
The
cached_recurring_events
table would need to be updated whenever a user adds a new recurring event -- and possibly once a day offline, by a cron-job/scheduled-task. But only on days when no new recurring event has been created.为什么不依靠 Google 日历的 API 用于存储和检索日历事件?
日历 API 是一个 REST API,可以通过显式 HTTP 调用进行访问; API 公开了 Google 日历 Web 界面中的大部分可用功能,因此您的日历应用程序可以提供与 Google 日历一样多的功能(很多功能!!!)。
您的应用程序只需为 Google API 实现 OAuth 2.0,这可以通过使用单点登录服务(如 Auth0)来轻松实现提供适当的访问令牌。然后,您的日历应用程序可以将这些令牌与日历 API 结合使用,以 JSON 格式提供日历事件的无缝存储和检索。
用户在自己的“新日历”中创建事件。此日历以专用于此应用程序的 Gmail 帐户(应用程序的 Gmail 帐户)的形式与您共享。
基本上,Google 日历成为您的数据库,您可以让应用程序的 Gmail 帐户不仅存储应用程序的所有事件,还允许您通过直观的界面查看和编辑这些事件。
Why not use Google Calendar as a database for this calendar application by relying on Google Calendar's API for storing and retrieving calendar events?
The Calendar API is a REST API that can be accessed through explicit HTTP calls; the API exposes most of the features available in the Google Calendar Web interface, so your calendar application can as much functionality as Google Calendar does (a lot of functionality!!!).
Your application need only implement OAuth 2.0 for Google APIs, which can be made easy using a single sign-on service like Auth0 to provide the appropriate access tokens. Then, your calendar application can use these tokens in conjunction with the Calendar API to provide seamless storage and retrieval of calendar events in a JSON format.
Users create events within their own "New Calendar." This calendar is shared with you in the form of a gmail account dedicated to this application - the application's gmail account.
Basically, Google Calendar becomes your database, whereby you can have the application's gmail account not only store all of your application's events, but also allow you to view and edit these events with an intuitive interface.
执行此操作的最佳方法是存储基于标准的重复模式字符串 (iCal)...如果是单个事件,则保留空白。有一些 API 可以解析重复模式并创建可以绑定到 UI 元素的事件对象......所有事件都不需要存储在数据库中,只需将初始事件(发生)存储在数据库中。
The best way to do this is to store a standards based recurrence pattern string (iCal).. and leave blank if it's a single event. There are a few APIs that can parse the recurrence pattern and create event objects that you can bind to UI elements.... none of the occurrences need ever be stored in the database, only the initial event (occurrence)..
您不能存储每天的事件以及开始和结束时间吗?它将为每天发生的事件生成大量数据(可能会变得非相关),但它将使查询变得更容易,并且可以做出例外(如果事件地点被烧毁,或者员工罢工)。为了生成事件的日期,我建议在基于某种 ICal 模式的前端中实现它。
Couldn't you store the events per day with start and end time? It will generate a lot of data for events that happen everyday (maybe go non-relational for this) but it will make querying easier and it will be possible to make exceptions (f.e. the event place burned down, or employees are striking). To generate the days for the event I would suggest to implement that in the front-end derived on some ICal-ish pattern.