Как лучше всего представлять повторяющиеся события в базе данных?

Я пытаюсь разработать приложение для событий, зависящее от планировщика и календаря, на C #, для которого критически важным требованием является представление повторяющихся событий в базе данных. Как лучше всего представлять повторяющиеся события в базе данных?

Подробнее:

При создании события я также отправляю приглашения определенным пользователям, и приглашенным должно быть разрешено входить на собрание только в течение указанного окна (длительности собрания) или может быть отказано в входе, когда приглашенный пытается войти, скажем, за 5 минут до этого. запланированное начало встречи.


person Varma    schedule 16.10.2009    source источник
comment
Как повторяется? Каждого 2 января? Каждый понедельник? Каждый второй четверг марта? Все вышеперечисленное?   -  person Svish    schedule 16.10.2009


Ответы (6)


sysjobs, sysjobsschedule и sysschedules в SQL Server неплохо справляются с этой задачей. Я бы не стал изобретать велосипед, я бы просто скопировал их дизайн.

Вот некоторые из важных полей из sysschedules

freq_type

Как часто выполняется задание по этому расписанию.

1 = только один раз

4 = Ежедневно

8 = Еженедельно

16 = ежемесячно

32 = Ежемесячно относительно freq_interval

64 = запускается при запуске службы агента SQL Server

128 = Работает, когда компьютер бездействует

интервал_частоты

Дни выполнения задания. Зависит от значения freq_type. Значение по умолчанию - 0, что означает, что freq_interval не используется. Значение freq_type Влияние на freq_interval

1 (один раз) freq_interval не используется (0)

4 (ежедневно) Каждые freq_interval дн.

8 (еженедельно) freq_interval может быть одним или несколькими из следующих: 1 = воскресенье 2 = понедельник 4 = вторник 8 = среда 16 = четверг 32 = пятница 64 = суббота

16 (ежемесячно) Freq_interval день месяца

32 (ежемесячный, относительный) freq_interval может быть одним из следующих: 1 = воскресенье 2 = понедельник 3 = вторник 4 = среда 5 = четверг 6 = пятница 7 = суббота 8 = день 9 = будний день 10 = выходной день

64 (запускается при запуске службы агента SQL Server) freq_interval не используется (0)

128 (запускается, когда компьютер бездействует) freq_interval не используется (0)

freq_subday_type

Единицы измерения для freq_subday_interval. Может принимать одно из следующих значений: Значение Описание (единица измерения)

1 В указанное время

2 секунды

4 минуты

8 часов

freq_subday_interval

Количество периодов freq_subday_type между каждым выполнением задания.

freq_relative_interval

Когда freq_interval встречается в каждом месяце, если freq_interval равно 32 (относительный месяц). Может быть одним из следующих значений:

0 = freq_relative_interval не используется

1 = Первый

2 = второй

4 = Третий

8 = Четвертый

16 = Последний

freq_recurrence_factor

Количество недель или месяцев между запланированным выполнением задания. freq_recurrence_factor используется, только если freq_type равно 8, 16 или 32. Если этот столбец содержит 0, freq_recurrence_factor не используется.

person Bob    schedule 16.10.2009
comment
Любопытно, можем ли мы заменить некоторые из этих полей строкой в ​​стиле cron? Единственный недостаток - вам придется его проанализировать, но это не должно быть слишком сложно, я видел код для этого в SO. - person pixelfreak; 24.07.2012
comment
@bob не могли бы вы включить какой-нибудь запрос на выбор, например, какие события происходят в определенный день, неделю, месяц - person Saroj Shrestha; 17.05.2019
comment
Этот ответ, кажется, неверно интерпретирует вопрос, он относится к расписаниям выполнения в стиле cron для планирования рабочей нагрузки и периодических заданий, а не к календарю повторяющихся человеческих событий и встреч, указанных в вопросе. Модель предметной области, необходимые возможности и результаты у них кардинально отличаются. - person inopinatus; 10.07.2020

Что ж, чтобы сохранить само правило повторения, вы можете использовать урезанную версию RFC 5545 (и я действительно предлагаю вам сильно сократить его). Помимо всего прочего, это упростит экспорт в другие приложения, если вы захотите.

После того, как вы приняли это решение, для стороны базы данных вам нужно решить, хотите ли вы хранить каждое вхождение события или только одну запись для повторяющегося события, расширяя ее по мере того, как вы нужно. Очевидно, что гораздо проще запрашивать базу данных, когда вы уже все расширили, но это усложняет обслуживание.

Если вам не нравится писать довольно сложный SQL, который может быть трудно протестировать (и вам понадобится много модульных тестов для всех видов угловых случаев), я бы посоветовал вам сделать саму базу данных относительно " тупой »и напишите большую часть бизнес-логики на таком языке, как Java или C # - любой из которых, конечно, может быть встроен в хранимые процедуры, в зависимости от вашей базы данных.

Еще одна вещь, которую вы должны спросить себя, - нужно ли вам справляться с исключениями для событий - одно событие в серии, меняющее время / местоположение и т. Д.

У меня есть некоторый опыт работы с календарями (большую часть прошлого года я работал над календарем в Google Sync через ActiveSync), и я должен вас предупредить, что все усложняется действительно быстро. Все, что вы считаете «выходящим за рамки», - это благословение. В частности, вам нужно работать в нескольких часовых поясах?

И, наконец, будьте очень, очень осторожны, когда выполняете арифметические операции с календарными операциями. Если вы собираетесь использовать Java, пожалуйста используйте Joda Time, а не встроенные _1 _ / _ 2_ классы. Они вам очень помогут.

person Jon Skeet    schedule 16.10.2009
comment
RFC 5545 заменен на RFC 2445, сентябрь 2009 г. - person Simen Echholt; 01.09.2010
comment
@JonSkeet Предлагаете ли вы развернуть каждое событие, если исключения из событий являются обычным явлением? - person Alexander Suraphel; 26.12.2014
comment
@AlexanderSuraphel: Это зависит от того, какое именно приложение вы создаете - в обоих случаях есть свои плюсы и минусы, но, по крайней мере, это стоит внимательно рассмотреть. - person Jon Skeet; 27.12.2014

Я тоже думал об этом, хотя еще не реализовал это, но это мои мысли о простом решении.

При настройке повторяющегося события попросите пользователя указать «дату окончания» и создать отдельные события для каждого из них (на основе повторяющихся параметров). Поскольку это повторяющееся событие, установите уникальный «повторяющийся идентификатор» для каждого из них. Затем этот идентификатор будет использоваться, чтобы пометить событие как повторяющееся, и если вы измените будущее событие, вы можете предложить пользователю применить его к остальным будущим событиям, удалив и воссоздав повторяющиеся события с новым «повторяющимся идентификатором», который также будет отличать это повторяющееся событие от ранее измененных.

Надеюсь, это имеет смысл, и хотелось бы получить какие-либо комментарии.

person Mark Redman    schedule 16.10.2009
comment
Я предполагаю, что вы спрашиваете об отдельных событиях, хранящихся в календаре, а не о различных типах повторяющихся правил, которые можно легко исследовать / дублировать? - person Mark Redman; 16.10.2009

Я бы записал повторяющиеся события как две отдельные вещи в базе данных. Прежде всего, в таблице событий запишите каждое происшествие события. Во-вторых, имейте таблицу повторений, в которой вы записываете детали, которые вы запрашиваете для настройки повторяющегося события. Дата начала, периодичность, количество повторов и т. Д.

Затем вы можете подумать о том, чтобы связать все это вместе, поместив PK повторений в каждую из записей событий как FK. Но лучшим дизайном было бы нормализовать таблицу событий в две таблицы, одна из которых представляет собой всего лишь базовые элементы события, а другая содержит детали, которые теперь могут относиться к нескольким событиям. Таким образом, каждая запись события, повторяющаяся или нет, будет иметь FK для PK таблицы eventdetails. Затем в деталях событий запишите PK повторений где-нибудь вместе с повесткой дня, приглашенными и т. Д. Запись повторений ничего не управляет. Например, если вам нужен список всех повторяющихся событий, вы просматриваете подробные сведения о всех событиях с ненулевым FK для повторений.

Вам нужно быть осторожным, чтобы синхронизировать все эти вещи, чтобы вы вставляли или удаляли события при изменении данных повторения.

person Michael Dillon    schedule 16.10.2009

"Помимо всего прочего"

включает ли это «самые требования»?

«это упростит экспорт в другие приложения, если вы захотите».

Включены ли в заявленные требования «должен быть простой экспорт календарей в другие приложения»? У меня сложилось впечатление, что проблема заключалась исключительно в создании ПЕРВОГО приложения.

Тем не менее, мой собственный ответ:

Вам необходимо ограничить себя / своего пользователя типами "повторения", которые ваша система сможет поддерживать. И «Все вышеперечисленное» или «Без ограничений» не будет правильным ответом, если вы / ваш пользователь хотите, чтобы в итоге получилось пригодное для использования приложение.

person Erwin Smout    schedule 16.10.2009

person    schedule
comment
@agapwlesu Один вопрос, а как насчет событий, которые повторяются в первую и последнюю пятницу месяца. Какая была бы комбинация - person Saroj Shrestha; 17.05.2019
comment
@agapwlesu, не могли бы вы добавить запрос выбора на один день, одну неделю или месяц? - person Saroj Shrestha; 17.05.2019