Есть сложные решения и простые решения. Два самых простых решения:
Разнесение повторяющихся событий до некоторого постоянного числа экземпляров или до некоторого фиксированного диапазона дат в будущем. Сохраняйте FK recurrence_id с каждым экземпляром, который указывает на описание повторения, и допускает массовое редактирование и отмену.
Преимущество подхода предварительно рассчитанного разветвления состоит в том, что он позволяет очень легко реализовать исключения повторения, что почти наверняка будет первым запросом функции, который вы получите.
Расчет во время отображения. Компьютеры работают быстро, в зависимости от вопросов, на которые вы хотите ответить о ваших данных, часто будет легко вычислить все случаи в диапазоне дат. Вы можете быть умным и попытаться быстро заключить в скобки свой диапазон дат перед выполнением вычисления повторения, или вы можете перебором его с начальной даты.
Кроме того, вам просто нужно решение для хранения правила повторения, которое работает со всем, что вы используете для вычисления повторений. (например, если вы используете библиотеку включения iCalendar, ваша схема будет varchar (255) со значениями RRULE в ней)
Если вам нужно развернуть свой собственный калькулятор повторений, и вы хотите, чтобы он был простым, ограничение ваших повторений ежедневными, еженедельными, ежемесячными или ежегодными, покрывает ваш первый 80% сценарий использования и легко вычисляется.
В этот момент ваша потенциальная схема повторения выглядит примерно так:
id
recurrence_start
recurrence_end
type (daily|weekly|monthly|yearly)
day_of_week (for weekly)
month
day_of_month
И, честно говоря, комплексные решения, вероятно, не стоят того:)