Kaer_Morchen
@Kaer_Morchen
Разрабатываю web-приложения.

Как хранить интервальное расписание в БД?

Всем привет.

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

Это могут быть платежи, напоминания или возьмем для наглядного пример расписание тренировок.
Есть тренер, он создал расписание тренировок, например во вторник, четверг и субботу. И вот это расписание "отмасштабировалось" на его календаре. Но в новогодние праздники тренер не работает, и c 1.01 по 10.01 расписание должно быть пустым.

Прошу поделиться опытом или ссылками.
  • Вопрос задан
  • 5220 просмотров
Пригласить эксперта
Ответы на вопрос 4
@alex_ak1
Простой способ это линуксовый крон, в нем с помощью достаточно простой грамматики можно задать интервалы в достаточно широких правилах. Там задается все так:
минута час день_недели день_месяца месяц команда
Каждое из чисел это или (*), или число (5) или несколько чисел (2,3,5, 7-10), либо пропуск (что_то/интервал).
Поэтому можно легко задавать события типо каждый второй вторник
* * 2/2 * * команда
или первое число мая
0 0 * 1 4 команда 2
На основании этого можно строить регулярные события. На них накладывать расписание праздников (и то не всегда, к примеру оплата домашних счетов не зависит от праздников). Как вариант - можно сдвигать событие, если оно попало на праздник.
Ответ написан
petermzg
@petermzg
Самый лучший программист
Одна таблица для дней исключений, т.е. праздников. Дата начала праздника и дата завершения.
Вторая для самих событий, которые бывают:
- Разовые - конкретный день.
- Повторяющиеся. Тут нужны настройки.
* День начала периода когда активны события (можно разделять поле с конкретным днем разовой)
* День окончания периода или null для безсрочной
* Тип повтора:
1. Конкретный день недели (число от 1 до 7)
2. Через определенное число дней (число)
- ID тренировки
- ID группы (для того чтобы делать сложные варианты указанного вами типа "вторник, четверг и субботу")
Ответ написан
Комментировать
1. Прежде всего, расписание можно задавать естественным языком, или хранить в JSON придумав какой-нибудь DSL, - вне зависимости от базы данных. Превосходная библиотека для этого: https://github.com/kvh/recurrent (хотя поддерживает только английский). Если вам нужно, например, делать рассылки, - вы пробегаете по всем активным расписаниям в цикле, проверяете, соответствует ли текущая дата расписанию, и выполняете действие.
2. Если такую выборку делать хочется очень быстро и средствами БД, тогда при вводе вышеупомянутого высокоуровневого расписания можно заполнять все даты в некоем кэше (или в отдельной таблице в БД), выставляя флаг для пары (дата, id расписания). При изменении расписания эта матрица для него перевычисляется.
3. Как быть с исключаемыми днями? Можно в каждом из объектов предлагать два поля: "Расписание" (например: every friday) и "Исключая" (например: 1 Jan - 10 Jan).
Ответ написан
Комментировать
@BigGate
Битовая строка один бит - один интервал.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы