我正在构建一个需要存储/管理不同类型事件的系统。为简单起见,我将专注于设计一个日历(我正在构建一些稍微不同的东西,但日历是一个很好的比喻,很容易推理)。我想听听有关可能的数据库/架构设计的想法。
问题说明
我有一个包含不同类型事件的日历(为简单起见,假设只有一种类型的事件:任务)。用户可以为特定日期添加新事件,编辑(更改某些详细信息,如标题或移至其他日期)或删除。可能存在一次性事件和重复事件(具有不同类型的重复:每X天,每月的第15天,周一的每周;有点像简单的cron)。当用户移动重复事件时,此事件的所有其他实例都以相同的方式移动(例如:+3天)。重要部分:重复发生的事件可能有例外。因此,举例来说,假设我有一个每7天重复一次的重复事件A.但是我想改变下周的日期,所以不是星期二,而是分配到星期五,之后它仍然会在星期二发生。移动“父”事件时,不应影响此“异常”事件。
此外,每个周期性事件都可以有其他信息,仅与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
(例如{{ 1}})。当用户添加新的周期性事件时,我只是在数据库中创建这样的7
。当用户想要更改此事件的1次出现时,我将新条目添加到类型/类Event
的数据库中,该数据库/类MovedEvent
从Event
“继承”具有不同日期并具有其他字段related_to
指向与其相关的ID
的{{1}}(或UUID
,如果愿意)。但与此同时,我需要跟踪所有Event
(否则我在同一周显示2个事件),所以我需要MovedEvent
moved_events
个数组ID
1}}指向所有MovedEvent
s。
缺点:每当我想要显示日历时,我需要Event
并选择moved_events
中的所有事件,如果我有很多感动事件。
2. 另一个想法是将每个事件存储为单独的记录。 IMO这是一个可怕的想法,但我只是提到它,因为它是一种可能性。 缺点:每次我想编辑主要事件时(例如:我想将事件从“每7天”更改为“每9天”一次)我需要更改每次出现的事件事件。但是,“异常”(更改单个实例)更容易。
SQL / NoSQL的?比例详情
我在我的项目中使用PostgreSQL,但我对NoSQL数据库有基本的了解,如果它们更适合这类问题,我可以使用它。
比例:假设我有5k用户,每个人平均每周有150个事件,其中40%可以是“例外”。因此,我想设计这个系统是有效的。
类似的问题&其他资源
我刚刚开始阅读Martin Fowler的“日历重复事件”(http://martinfowler.com/apsupp/recurring.pdf),但我不确定它是否适用于我的问题,如果是,那么如何根据本文档设计数据库模式(建议欢迎)。
有类似的问题,但我没有看到任何提及“例外”(改变1个事件实例而不影响其他事件),但也许有人会发现这些链接有用:
Design question: How would you design a recurring event system?
What is the best way to represent "Recurring Events" in database?
很抱歉,我想很好地描述问题。然而,我觉得这很混乱,所以如果你有其他问题,我会很乐意提供更多细节。同样,我想了解可能的数据库/架构设计思想以及任何其他建议。谢谢!
答案 0 :(得分:6)
使用iCalendar RRules和ExDates
如果这是一个重复出现的事件,只需存储事件的开始/结束日期时间和RRules和ExDates。
使用物化视图预先计算即将发生的实际事件,例如接下来的30天或365天。
当您使用Postgres时,您可以在pg函数中使用现有的python,perl或javascript RRule库(例如dateutil)来根据rrules和exdates计算未来事件
更新:查看pg_rrule扩展名:https://github.com/petropavel13/pg_rrule