Я занимаюсь именно этой проблемой, и у меня полностью разнесен iCalendar (rfc 2445) до прочтения этой ветки, поэтому я понятия не имею, насколько хорошо это будет или не будет интегрироваться с этим . В любом случае дизайн, который я придумал, выглядит примерно так:
- Вы не можете сохранить все экземпляры повторяющегося события, по крайней мере, до того, как они произойдут, поэтому у меня просто есть одна таблица, в которой первый экземпляр события хранится как фактическая дата, необязательный срок действия и поля repeat_unit и repeat_increment, допускающие значение NULL. описать повтор. Для отдельных экземпляров поля повторения равны нулю, в противном случае единицами измерения будут «день», «неделя», «месяц», «год», а приращение - это просто кратное количество единиц, которое нужно добавить к дате начала для следующего вхождения.
- Сохранение прошлых событий кажется преимуществом только в том случае, если вам нужно установить отношения с другими объектами в вашей модели, и даже в этом случае нет необходимости иметь явную таблицу «экземпляров событий» в каждом случае. Если у других сущностей уже есть данные "экземпляра" даты / времени, то, скорее всего, будет достаточно внешнего ключа для события (или таблицы соединения для "многие-ко-многим").
- Чтобы сделать «изменить этот экземпляр» / «изменить все будущие экземпляры», я планировал просто продублировать события и удалить устаревшие. Итак, чтобы изменить один экземпляр, вы должны истечь старый в его последнем появлении, сделать копию для нового, уникального экземпляра с изменениями и без каких-либо повторений, а еще одну копию оригинала в следующем экземпляре, который повторяется в будущее. Изменение всех будущих экземпляров аналогично, вы просто истечете срок действия оригинала и создадите новую копию с изменениями и деталями повторения.
На данный момент я вижу две проблемы с этим дизайном:
- Это затрудняет представление событий типа MWF. Это возможно, но вынуждает пользователя создавать три отдельных события, которые повторяются еженедельно в M, W, F индивидуально, и любые изменения, которые они хотят внести, также должны быть сделаны для каждого из них отдельно. Подобные события не особо полезны в моем приложении, но они оставляют бородавку на модели, что делает ее менее универсальной, чем хотелось бы.
- Копируя события для внесения изменений, вы нарушаете связь между ними, что может быть полезно в некоторых сценариях (или, может быть, это может быть просто иногда проблематично). Теоретически таблица событий может содержать поле идентификатора «copied_from», чтобы отслеживать, где находится событие возникло, но я не до конца продумал, насколько полезным может быть что-то подобное. С одной стороны, иерархические отношения родитель / потомок сложно запрашивать из SQL, поэтому преимущества должны быть довольно значительными, чтобы перевесить затраты на запрос этих данных. Полагаю, вы могли бы использовать вложенный набор вместо этого.
Наконец, я думаю, что возможно вычислять события для заданного промежутка времени с использованием прямого SQL, но я не проработал точных деталей и думаю, что запросы обычно оказываются слишком громоздкими, чтобы иметь смысл. Однако ради аргумента вы можете использовать следующее выражение для вычисления разницы в месяцах между заданным месяцем и годом события:
(:month + (:year * 12)) - (MONTH(occursOn) + (YEAR(occursOn) * 12))
Основываясь на последнем примере, вы можете использовать MOD, чтобы определить, является ли разница в месяцах правильным множителем:
MOD(:month + (:year * 12)) - (MONTH(occursOn) + (YEAR(occursOn) * 12), repeatIncrement) = 0
В любом случае это не идеально (не игнорируются просроченные события, не учитывается время начала / окончания события и т. Д.), Поэтому это только как мотивирующий пример. Вообще говоря, я думаю, что большинство запросов окажутся слишком сложными. Вероятно, вам лучше запрашивать события, которые происходят в заданном диапазоне или не истекают раньше диапазона, и вычислять сами экземпляры в коде, а не в SQL. Если вы действительно хотите, чтобы база данных выполняла обработку, хранимая процедура, вероятно, значительно облегчила бы вашу жизнь.
person
Matt S.
schedule
22.08.2008