Подтвердить что ты не робот

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

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

Подробнее:

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

4b9b3361

Ответ 1

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

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

freq_type

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

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

4 = Ежедневно

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

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

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

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

128 = Выполняется, когда компьютер находится в режиме ожидания

freq_interval

Дни выполнения задания. Зависит от значения 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 не используется.

Ответ 2

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

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

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

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

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

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

Ответ 3

Принятый ответ здесь слишком запутан. Например, если событие происходит каждые 5 дней, 5 хранится в freq_interval, но если оно происходит каждые 5 недель, то 5 сохраняется в freq_recurrence. Самая большая проблема заключается в том, что freq_interval означает три разные вещи в зависимости от значения freq_type (количество дней между событиями для ежедневного повторения, день месяца для ежемесячного повторения или дни недели для еженедельного или месячного). Кроме того, последовательность типов 1,2,4,8... используется, когда она не нужна и менее полезной. Например, freq_relative_interval может быть "одним из" возможных значений. Это выровняется с выпадающим списком или входом типа переключателя, а не с типом ввода флажка, где можно выбрать несколько вариантов выбора. Для кодирования и для удобочитаемости человека эта последовательность мешает, и просто использование 1,2,3,4... проще, более эффективно, более уместно. Наконец, большинству приложений календаря не нужны промежуточные интервалы (события, происходящие несколько раз в день - каждые столько секунд, минут или часов). Но, сказав это, этот ответ помог мне уточнить мои мысли о том, как я это делаю. После смешивания и сопоставления с другими статьями и перехода от того, что я вижу в интерфейсе календаря Outlook и нескольких других источников, я придумал следующее:

рецидивирует
0 = отсутствие повторения 1 = ежедневно
2 = еженедельно
3 = ежемесячно

recurs_interval
это сколько периодов между повторениями. Если событие повторяется каждые 5 дней, у него будет 5 и recurs. 1. Если событие повторяется каждые 2 недели, у этого будет 2 и recurs. a 2.

recurs_day
Если пользователь выбрал ежемесячное повторение типа, в определенный день месяца (например, 10-й или 14-й). У этой даты. Значение равно 0, если пользователь не выбирает месячный или определенный месяц повторения месяца. В противном случае это значение равно 1 - 31.

recurs_ordinal
если пользователь выбрал повторение ежемесячного типа, но порядковый тип дня (например: первый понедельник, второй четверг, последний пятница). Это будет порядковый номер. Значение равно 0, если пользователь не выбрал этот тип повторения.
1 = первый
2 = вторая
3 = третий
4 = четвёртая
5 = последняя

recurs_weekdays
для еженедельного и ежемесячного порядкового повторения это хранит будние дни, где происходит повторение. 1 = воскресенье
2 = понедельник
4 = вторник
8 = среда
16 = четверг
32 = Пятница
64 = суббота
Таким образом, каждые 4 недели в субботу и воскресенье будут recurs = 2, recurs_interval = 4, recurs_weekdays = 65 (64 + 1)
Аналогично, каждые три месяца в первую пятницу месяца будет recurs = 3, recurs_interval = 3, recurs_ordinal = 1, recurs_weekdays = 32

Ничто из этого дела не имеет поля, которое означает три совершенно разные вещи в зависимости от значения другого поля.

На стороне пользовательского интерфейса я позволяю пользователю указывать дату, время начала, время окончания. Затем они могут указать, хотят ли они типа повторения, отличного от него. Если это так, приложение расширяет соответствующий раздел веб-страницы, чтобы предоставить пользователю параметры, необходимые для вышеперечисленного, много похожее на параметры Outlook, за исключением того, что каждый день не существует "каждодневного дня" при ежедневном повторении (это избыточно с еженедельное повторение в каждый пн-пт), и нет ежегодного повторения. Если есть повторение, я также требую, чтобы пользователь указал дату окончания, которая находится в течение одного года с сегодняшнего дня (пользователи этого хотят, и это упрощает мой код) - я не делаю бесконечную повторяемость или "заканчиваю после # # вхождения".

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

Мои пользователи все в КНТ, и я благодарю хорошего Господа за это. На данный момент это удобное упрощение, и если в будущем база пользователей будет расширяться дальше этого, тогда я смогу понять, как с этим бороться, как хорошо отделяемую задачу.

Поскольку я впервые написал это, я добавил ежедневное появление с "Every weekday". Наши пользователи немного усердно думали, что вы можете использовать Еженедельное повторение событий, происходящих с четверга одна неделя до вторника на следующей неделе и только в будние дни. Это было более интуитивно для них, чтобы иметь это, даже если бы было уже другой способ, которым они могли это сделать.

Ответ 4

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

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

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

Ответ 5

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

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

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

Ответ 6

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

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

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

В соответствии с указанными требованиями "нужно легко экспортировать календари в другие приложения"? Мое впечатление заключалось в том, что проблема заключалась исключительно в создании приложения FIRST.

который сказал, мой собственный ответ:

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