我正在构建一个需要存储/管理不同类型事件的系统。为简单起见,我将专注于设计日历(我在构建一些稍有不同的日历,但是日历是一个很好的类比,并且很容易推理)。我想听听有关数据库/架构设计的想法。
问题描述
我有一个包含不同类型事件的日历(为简单起见,假设只有一种类型的事件:任务)。用户可以为特定日期添加新事件,进行编辑(更改某些详细信息,例如标题或移至其他日期)或删除。可以有一次性事件和重复事件(重复的类型不同:每月X天,每月每15日,星期一每周;有点像简单的cron)。当用户移动重复事件时,此事件的所有其他实例都以相同的方式移动(例如:+3天)。重要部分:重复发生的事件可能会有异常。例如,假设我有一个重复发生的事件A,每7天重复一次。但是我想将其日期更改为下周,因此将其分配给星期五,而不是星期二,此后它仍会在星期二发生。这个“例外”
此外,每个重复发生的事件都可以具有仅与1个特定实例有关的其他信息,例如:我具有相同的重复发生事件A,每7天重复一次,我想在本周实例上添加一个注释,写上“ X”,并且我想为下个月的活动“ Y”添加另一个注释-这些字段仅对单个实例可见。
主意
具有定期的一次性事件的系统非常简单,因此我将不进行讨论,而只关注重复发生的事件。
1. 一个可能的解决方案是一个类似于OOP:我可以有一个Event“类”包含字段,例如start_date,end_date(可null), recurrence_type(有点像用的可能值枚举EVERY_X_DAYS,DAY_OF_WEEK,DAY_OF_MONTH)和recurrence_value(说7)。当用户添加新的重复事件时,我只是Event在数据库中创建这样的事件。当用户想改变1次出现此事件,我添加新条目类型的DB /类MovedEvent,从“继承”Event与不同的日期,并且具有附加字段related_to指向ID(或者UUID,如果你愿意)的Event,它的相关。但是同时,我需要跟踪所有MovedEventS(否则我有2个事件显示在同一个星期),所以我需要有一个数组moved_events的IDs表示点所有MovedEvent秒。 缺点 :每次我要显示日历时,都需要从中获取Event并选择所有事件moved_events,如果我要移动的事件很多,这不是最佳选择。
Event
start_date
end_date
null
recurrence_type
EVERY_X_DAYS
DAY_OF_WEEK
DAY_OF_MONTH
recurrence_value
7
MovedEvent
related_to
ID
UUID
moved_events
2. 另一个想法是将每个事件存储为单独的记录。海事组织这是一个糟糕的主意,但我只是提到它,因为这是可能的。 缺点 :每次我要编辑主要事件时(例如:我想将事件从“每7天”更改为“每9天”),我需要更改事件的每个单次发生。但是,“异常”(更改单个实例)更容易。
SQL / NoSQL? 比例尺细节
我在项目中使用的是PostgreSQL,但是我对NoSQL数据库有基本的了解,如果它们更适合解决此类问题,则可以使用它。
规模:假设我有5k用户,每个用户平均每周将有150个事件,其中40%可以是“例外”。因此,我想将此系统设计为高效的。
类似问题和其他资源
我刚刚开始阅读Martin Fowler的“日历重复事件”(http://martinfowler.com/apsupp/recurring.pdf),但是我不确定它是否适用于我的问题,如果适用,如何设计数据库根据本文档的架构(建议)。
有类似的问题,但是我没有提到“例外”(更改1个事件实例而不影响其他实例),但是也许有人会发现这些链接有用:
设计问题:您将如何设计重复事件系统?
具有重复事件的数据库的优化设计
“重复任务”的设计选项
日历重复/重复事件-最佳存储方法
在数据库中表示“重复发生的事件”的最佳方法是什么?
很长的问题很抱歉,我想很好地描述这个问题。但是,我觉得这很混乱,因此,如果您还有其他问题,我会很乐意提供更多详细信息。同样,我想听听有关数据库/架构设计的想法以及其他建议。谢谢!
使用iCalendar规则和过期日期
如果是重复发生的事件,则只需存储该事件的开始/结束日期时间以及RRules和ExDates。
使用实例化视图来预先计算即将发生的实际事件,例如未来30天或365天。
当您使用Postgres时,可以在pg函数中使用现有的python,perl或javascript RRule库(例如dateutil)来根据rrule和exdates计算将来的事件
更新:检查pg_rrule扩展名:https : //github.com/petropavel13/pg_rrule