Как мне (как бы вы) сохранять графики в базе данных - PullRequest
2 голосов
/ 16 марта 2011

У меня есть приложение, в котором пользователи могут устанавливать расписания для определенного объекта в пределах определенного диапазона дат. Редактирование расписания будет похоже на ввод календарных встреч:

  • когда оно начинается и когда оно заканчивается (часы)
  • дата начала и установить еженедельные дни повторения (т. Е. Каждую субботу и воскресенье или только каждый Модай)
  • дата окончания повторения - устанавливает дату окончания повторения

Пример

Я бы хотел установить расписание выходных на январь 2011 года с 7:00 до 17:00. * 10101 *

  1. Я установил дату начала как 1.1.2011
  2. Установить дату окончания 31.1.2011
  3. Я начинаю в 7:00 и заканчиваю в 17: 00
  4. включить понедельник для маски еженедельного повторения

Тогда я бы также ввел новое расписание, которое перекрывает существующее, но только на первую половину января:

  1. Установить дату начала 1.1.2011
  2. Установить дату окончания 14.1.2011
  3. Установить время с 9:00 до 15:00
  4. Включить понедельник.

Вопрос

Я мог бы хранить расписание на каждый день в виде таблицы:

create table EntitySchedule (
    EntityID int not null
        references Entity(EntityID),
    ForDay date not null,
    StartAt time not null,
    EndAt time not null
)

Но я получу много записей в этой таблице:

Количество записей в расписании = (Количество записей сущностей) * (количество дней в диапазоне расписания)

Или я мог бы хранить данные, аналогичные введенным данным:

create table EntitySchedule (
    EntityID int not null
        references Entity(EntityID),
    StartRange date not null,
    EndRange date not null,
    StartAt time not null,
    EndAt time not null,
    WeekdayMask tinyint not null -- bitmask of days (7 bits)
        default (0)
)

В этой таблице будет намного меньше записей, чем в предыдущей.

Сравнение

Каждый из них (за день и за день) имеет свои преимущества и недостатки:

  1. Для таблицы на день было бы легко получить расписание на определенный день
  2. В дневном расписании не будет возможности редактировать повторяющиеся данные, вы всегда будете вводить новое расписание, перекрывая существующие данные
  3. Через несколько лет ежедневная таблица будет содержать огромное количество записей, которые нужно будет уменьшить
  4. В случае получения таблицы по расписанию расписание на определенный день невозможно без расчета
  5. Таблица по расписанию позволяет копировать расписание из одного диапазона дат в другой, что было бы очень кстати, что упростило бы создание расписаний, просто импортировав данные расписания из другого диапазона дат и применив их к новому диапазону дат.

Сценарий использования

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

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

Но в случае таблицы по расписанию это усложняется:

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

Первый подход кажется более подходящим.Но запрос на получение графиков для диапазона дат становится довольно сложным и, вероятно, не очень быстрым.Представьте себе, что вы получите график организации на январь 2011 года. Чтение данных всегда должно давать результаты в виде ежедневной таблицы.

Вопрос

Существует ли какой-либо стандарт способ сохранения данных расписания?Как бы вы посоветовали мне сохранить эти данные?

Ответы [ 2 ]

0 голосов
/ 16 марта 2011

Я не знаю ни одного стандартного способа хранения данных расписания.

Я бы пошел с вашим вторым подходом - хранить данные, необходимые для создания вашего расписания, так как это то, что было определено пользователем (например, рассмотрим, как вы будете загружать из таблицы «за день», чтобы разрешить пользователю редактировать свое расписание - это было бы сложно!).

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

РЕДАКТИРОВАТЬ : Теперь, когда вы прояснили вопрос о часах работы (что-то, где вам нужно было бы составить список будущих событий расписания), а не о том, что я предположил в планировщике задач, где все, что вам нужно, это время «следующего запуска», поле «Следующий запуск» менее полезно.

Тем не менее, я бы по-прежнему пошел с сохранением данных расписания, так как на самом деле это то, что магазин определил (они скажут «мы хотим открыть между 9-5 в будние дни», а не «мы»). открою 9-5 следующий понедельник, вторник, четверг, четверг, четверг ... »). Хотя я понимаю, что это усложняет некоторые вещи, более точно хранить их и извлекать фактические повседневные данные. Вы все еще можете использовать хранимую процедуру или основанную на таблице пользовательскую функцию, чтобы иметь возможность выбирать повседневные данные. Реализация этого снова будет зависеть от вашего сценария использования - вы когда-нибудь захотите перечислить только часы работы магазина или вы хотите иметь функцию «получить все магазины, которые открыты в XX?»

0 голосов
/ 16 марта 2011

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...