具有异常的重复事件的数据库设计
Database design for recurring events with exceptions
我正在构建一个需要 store/manage 不同类型事件的系统。为简单起见,我将专注于设计日历(我构建的东西略有不同,但日历是一个很好的类比,而且很容易推理)。我想听听可能的 database/schema 设计想法。
问题描述
我有一个包含不同类型事件的日历(为简单起见,假设只有一种类型的事件:任务)。用户可以为特定日期添加新事件、编辑(更改一些细节,如标题或移至另一个日期)或删除。可以有 one-time 事件和重复事件(具有不同类型的重复:每 X 天、每月的第 15 天、每周的星期一;有点像简单的 cron)。当用户移动重复事件时,此事件的所有其他实例都以相同的方式移动(例如:+3 天)。重要部分:重复发生的事件可以有例外。因此,例如,假设我有一个每 7 天重复一次的重复事件 A。但我想将它的日期更改为下周,所以它被分配到星期五而不是星期二,之后它仍然会在星期二发生。 "exception" 事件在移动 "parent" 事件时不应受到影响。
此外,每个重复发生的事件都可以有额外的信息,仅与 1 个特定实例相关,例如:我有相同的重复发生事件 A 每 7 天重复一次,我想为本周实例添加一条注释,上面写着"X",我想为下个月的事件 A 添加另一个注释,上面写着 "Y" - 这些字段仅对单个实例可见。
想法
具有常规 one-time 事件的系统非常简单,所以我不会讨论它,只关注重复发生的事件。
1. 一种可能的解决方案是类似于 OOP 的解决方案:我可以有一个 Event
"class" 字段,例如 start_date
、end_date
(可以是 null
)、recurrence_type
(类似于枚举,可能的值为 EVERY_X_DAYS
、DAY_OF_WEEK
、DAY_OF_MONTH
)和 recurrence_value
(比如 7
)。当用户添加新的重复事件时,我只是在数据库中创建这样的 Event
。当用户想要更改此事件的 1 次发生时,我将新条目添加到 type/class MovedEvent
的数据库中,"inherits" 来自 Event
且日期不同,并且具有附加字段 related_to
指向与其相关的 Event
的 ID
(或 UUID
,如果你愿意的话)。但与此同时,我需要跟踪所有 MovedEvent
s(否则我会在同一周显示 2 个事件),所以我需要有一个数组 moved_events
of ID
s 指向所有 MovedEvent
s。
缺点:每次我想显示日历时,我需要从 moved_events
获取 Event
和 select 所有事件,如果我会有很多感动的事件。
2. 另一个想法是将每个事件存储为单独的记录。 IMO 这是一个糟糕的想法,但我只是提到它是因为它有可能。 缺点:每次我想编辑主要事件(例如:我想将事件从发生"every 7 days"更改为"every 9 days")我需要更改每一个事件的发生。不过,"Exceptions"(更改单个实例)更容易。
SQL/NoSQL?比例详情
我在我的项目中使用 PostgreSQL,但我对 NoSQL 数据库有基本的了解,如果它们更适合解决此类问题,我可以使用它。
规模:假设我有 5000 个用户,每个用户平均有 150 个 events/week,其中 40% 可以是 "exceptions"。因此我想把这个系统设计得高效。
类似问题和其他资源
我刚刚开始阅读 Martin Fowler 的 "Recurring Events for Calendars" (http://martinfowler.com/apsupp/recurring.pdf) 但我不确定它是否适用于我的问题,如果适用,如何根据此设计数据库模式文件(欢迎提出建议)。
有类似的问题,但我没有看到任何提及 "exceptions"(更改 1 个事件实例而不影响其他),但也许有人会发现这些链接有用:
Design question: How would you design a recurring event system?
Optimal design for a Database with recurring event
Design option for 'recurring tasks'
Calendar Recurring/Repeating Events - Best Storage Method
What is the best way to represent "Recurring Events" in database?
抱歉,问题很长,我想把问题描述清楚。然而,我觉得这很混乱,所以如果你有其他问题,我很乐意提供更多细节。同样,我想听听可能的 database/schema 设计想法以及任何其他建议。谢谢!
使用 iCalendar 规则和 ExDates
如果它是重复发生的事件,只需存储 start/end 事件的日期时间以及 RRules 和 ExDates。
使用物化视图预先计算即将发生的实际事件,比如接下来的 30 天或 365 天。
由于您使用的是 Postgres,您可以在 pg 函数中使用现有的 python、perl 或 javascript RRule 库(例如 dateutil)来计算未来事件规则和日期
更新:查看 pg_rrule 扩展名:https://github.com/petropavel13/pg_rrule
我正在构建一个需要 store/manage 不同类型事件的系统。为简单起见,我将专注于设计日历(我构建的东西略有不同,但日历是一个很好的类比,而且很容易推理)。我想听听可能的 database/schema 设计想法。
问题描述
我有一个包含不同类型事件的日历(为简单起见,假设只有一种类型的事件:任务)。用户可以为特定日期添加新事件、编辑(更改一些细节,如标题或移至另一个日期)或删除。可以有 one-time 事件和重复事件(具有不同类型的重复:每 X 天、每月的第 15 天、每周的星期一;有点像简单的 cron)。当用户移动重复事件时,此事件的所有其他实例都以相同的方式移动(例如:+3 天)。重要部分:重复发生的事件可以有例外。因此,例如,假设我有一个每 7 天重复一次的重复事件 A。但我想将它的日期更改为下周,所以它被分配到星期五而不是星期二,之后它仍然会在星期二发生。 "exception" 事件在移动 "parent" 事件时不应受到影响。
此外,每个重复发生的事件都可以有额外的信息,仅与 1 个特定实例相关,例如:我有相同的重复发生事件 A 每 7 天重复一次,我想为本周实例添加一条注释,上面写着"X",我想为下个月的事件 A 添加另一个注释,上面写着 "Y" - 这些字段仅对单个实例可见。
想法
具有常规 one-time 事件的系统非常简单,所以我不会讨论它,只关注重复发生的事件。
1. 一种可能的解决方案是类似于 OOP 的解决方案:我可以有一个 Event
"class" 字段,例如 start_date
、end_date
(可以是 null
)、recurrence_type
(类似于枚举,可能的值为 EVERY_X_DAYS
、DAY_OF_WEEK
、DAY_OF_MONTH
)和 recurrence_value
(比如 7
)。当用户添加新的重复事件时,我只是在数据库中创建这样的 Event
。当用户想要更改此事件的 1 次发生时,我将新条目添加到 type/class MovedEvent
的数据库中,"inherits" 来自 Event
且日期不同,并且具有附加字段 related_to
指向与其相关的 Event
的 ID
(或 UUID
,如果你愿意的话)。但与此同时,我需要跟踪所有 MovedEvent
s(否则我会在同一周显示 2 个事件),所以我需要有一个数组 moved_events
of ID
s 指向所有 MovedEvent
s。
缺点:每次我想显示日历时,我需要从 moved_events
获取 Event
和 select 所有事件,如果我会有很多感动的事件。
2. 另一个想法是将每个事件存储为单独的记录。 IMO 这是一个糟糕的想法,但我只是提到它是因为它有可能。 缺点:每次我想编辑主要事件(例如:我想将事件从发生"every 7 days"更改为"every 9 days")我需要更改每一个事件的发生。不过,"Exceptions"(更改单个实例)更容易。
SQL/NoSQL?比例详情
我在我的项目中使用 PostgreSQL,但我对 NoSQL 数据库有基本的了解,如果它们更适合解决此类问题,我可以使用它。
规模:假设我有 5000 个用户,每个用户平均有 150 个 events/week,其中 40% 可以是 "exceptions"。因此我想把这个系统设计得高效。
类似问题和其他资源
我刚刚开始阅读 Martin Fowler 的 "Recurring Events for Calendars" (http://martinfowler.com/apsupp/recurring.pdf) 但我不确定它是否适用于我的问题,如果适用,如何根据此设计数据库模式文件(欢迎提出建议)。
有类似的问题,但我没有看到任何提及 "exceptions"(更改 1 个事件实例而不影响其他),但也许有人会发现这些链接有用:
Design question: How would you design a recurring event system?
Optimal design for a Database with recurring event
Design option for 'recurring tasks'
Calendar Recurring/Repeating Events - Best Storage Method
What is the best way to represent "Recurring Events" in database?
抱歉,问题很长,我想把问题描述清楚。然而,我觉得这很混乱,所以如果你有其他问题,我很乐意提供更多细节。同样,我想听听可能的 database/schema 设计想法以及任何其他建议。谢谢!
使用 iCalendar 规则和 ExDates
如果它是重复发生的事件,只需存储 start/end 事件的日期时间以及 RRules 和 ExDates。
使用物化视图预先计算即将发生的实际事件,比如接下来的 30 天或 365 天。
由于您使用的是 Postgres,您可以在 pg 函数中使用现有的 python、perl 或 javascript RRule 库(例如 dateutil)来计算未来事件规则和日期
更新:查看 pg_rrule 扩展名:https://github.com/petropavel13/pg_rrule