В настоящее время я работаю над проектом по управлению окнами обслуживания в базе данных серверов и т. д. По сути, мне нужно быть точным с точностью до часа, но разрешить или запретить их устанавливать на каждый день. недели.
У меня было несколько идей, как это сделать, но, поскольку я работаю один, я не хочу брать на себя какие-либо обязательства без какой-либо обратной связи.
Чтобы визуализировать это, это что-то вроде плавного «графика».
| Sun | Mon | Tue | Wed | Thu | Fri | Sat |
-------------------------------------------
5AM |allow|allow|allow|deny |deny |allow|allow|
-------------------------------------------
6AM |allow|deny |deny |deny |deny |deny |allow|
-------------------------------------------
7AM |allow|deny |deny |deny |deny |deny |allow|
-------------------------------------------
8AM |allow|deny |deny |deny |deny |deny |allow|
-------------------------------------------
9AM |allow|deny |deny |deny |deny |deny |allow|
-------------------------------------------
... etc...
Есть ли стандартный способ сделать это или ресурс, который может дать мне некоторые идеи ...
[Обновлять]
Стоит упомянуть, что день может, даже если это маловероятно, быть установлен как «разрешить, запретить, разрешить, запретить ... и т. д...». Не гарантируется, что промежуток будет единственным на весь день.
Это также не единственное расписание, будут сотни устройств, каждое со своим расписанием, так что это будет волосатым ... lol ??
Роб спросил, нужно ли каждую неделю отслеживать - нет. Это общий график, который будет применяться на весь год (регулярное плановое обслуживание).
По-моему, вам нужно повернуть эту таблицу, потому что, если вы хотите получить все часы за определенный день, вам нужно будет вернуть 24 строки без простого способа ГДЕ данные. Мне кажется, что наличие 7 строк с 24 столбцами имеет больше смысла, 1 строка дает вам все часы для данного дня.

Может что-то вроде
TABLE:
StartTime DATETIME PrimaryKey,
EndTime DATETIME PrimaryKey, /*if you are positive it will be in one hour incerments then you might want to omit this one*/
Monday BIT,
TuesDay BIT,
Wednesday BIT,
Thursday BIT,
Friday BIT,
Saturday BIT,
Sunday BIT
Я бы рассмотрел для (1) использование формата, который включает время начала и окончания, а также целочисленное поле для дня недели. Я знаю, что вы заявили, что блоки всегда будут длиться один час, но это может быть обеспечено вашим кодом. Кроме того, если в один прекрасный день ваши требования изменятся, вам будет гораздо меньше беспокоиться на шаге (2), чем если бы все ваши операторы БД были написаны с учетом 1-часовых блоков.
CREATE TABLE maintWindow (
maintWindowId int primary key auto_increment not null,
startTime Time,
endTime Time,
dayOfWeek int,
...
Для (2), если с каждой записью связано время начала и окончания, то очень легко проверить наличие окон в любой момент времени:
SELECT maintWindowId
FROM maintWindow
WHERE $time >= TIME(startTime) AND $time <= TIME(endTime) AND DAYOFWEEK($time) = dayOfWeek
(где $time представляет дату и время, которые вы хотите проверить).
Разрешение или запрет на каждый день недели будет обрабатываться отдельными записями. ИМХО, это более гибко, чем жесткое кодирование для каждого дня недели, поскольку в этом случае вы будете использовать какой-то оператор case или переключатель if-else для проверки правильного столбца БД для интересующего вас дня.
Примечание: Убедитесь, что вы знаете, какой стандарт использует ваша БД для целого дня недели, и постарайтесь сделать свой код независимым от него (всегда спрашивайте БД). Мы очень повеселились с разными стандартами для начала недели (воскресенье или понедельник) и начального индекса (0 или 1).
Это определенно тот подход, который я бы использовал.
Если каждую неделю он будет изменяться, то установите стол следующим образом;
TABLE:
StartTime DATETIME PrimaryKey
Если установлено время начала для определенной даты / часа, тогда предположите, что это разрешено, в противном случае - запретите.
Если это общая конфигурация для общей недели, которая не меняется, попробуйте следующее;
TABLE:
Hour INT,
Day INT,
Allow BIT
Затем добавьте строки для каждой комбинации часа / дня.
Я фактически использовал этот дизайн раньше, в основном создавая растровое изображение для периода времени, который вы хотите регулярно планировать, разделенного на количество периодов, которое вы хотите. Итак, в вашем примере вам нужен недельный график с почасовыми периодами, поэтому у вас будет 168-битное растровое изображение, длина которого составляет всего 21 байт. Пара значений времени составляет 16 байтов вместе, и вам понадобится несколько их строк, чтобы представить возможные расписания на данную неделю, поэтому, если вас вообще волнует размер, я не думаю, что вы сможете его превзойти.
Я признаю, что это немного сложнее и менее гибко, чем предыдущие предложения. Подумайте, если вы вдруг захотели использовать периоды в полчаса, вам нужно будет перекодировать все существующие данные в новое 336-битное растровое изображение и распределить значения.
Если вы используете SQL, вы можете сохранить его в виде двоичного блога и выполнить бит-тиддлинг, чтобы сравнить, включен ли бит или нет, или вы можете сохранить каждый бит как столбец. MS SQL Server поддерживает до 1024 для стандартных или 30 КБ для широких таблиц, так что вы можете легко снизить степень детализации до 10 минут для любого или намного более тонкого для таблицы 30 КБ.
Я надеюсь, что это добавляет немного иной взгляд на то, как это можно сделать. Это действительно необходимо только в том случае, если вы беспокоитесь о пространстве / размере или если у вас их десятки или сотни миллионов.
Вы можете легко записать "разрешенное" время в таблицу. Таким образом, если его там нет, это не разрешено. Если вам нужно иметь более изменчивое «расписание», вы можете легко добавить поле года и месяца.
TABLE DBMaintSched
ID int PK
ServerID varchar(30) (indexed)
Day int
Month char(3)
DayOfWeek char(3)
Year int
StartDT DateTime
EndDT DateTime
На декабрь 2008 г .:
SELECT * FROM DBMaintSched WHERE ServerID = 'SQLSERVER01' AND Month = 'DEC' AND Year = 2008 ORDER BY DAY ASC
У вас есть все дни на декабрь 2008 г., в которые можно проводить техническое обслуживание. Отображайте как хотите.
Каждое предложенное решение мне подходит, в любом случае я бы рассмотрел это, если вы столкнетесь с проблемами производительности и / или размера таблицы. Поскольку вы, вероятно, установили бы связь между временем и вашей сущностью (то есть сервером), размер увеличится на entity_number * entity_times. Если у вас есть строка для каждого временного интервала, это может быть проблемой.
Это предложение немного уродливее с точки зрения структуры таблиц, но более эффективно, когда дело касается дискового пространства и скорости сканирования таблиц.
TABLE times
entityFK int -- your entity foreign key
day INT -- 0-7 day identifier
bit time0 -- ON if the time 00:00 - 00:59 is being covered
bit time1
bit time2
-- more columns
bit time23
Рассмотрим пример, в котором вы хотите назначить серверу время безотказной работы с 16:00 до 20:00 в воскресенье и понедельник, у вас будет только две строки, например
entityFK | day | time16 | time17 | time18 | time19 | -- other bits are set to 0
server1 0 1 1 1 1
server1 1 1 1 1 1
Вы предположите, что каждая отсутствующая строка означает, что сервер не работает.
Если вам это нужно, вы можете рассмотреть возможность использования формата DATE для столбца дня, чтобы установить определенные даты (т.е. время работы только 2013/10/02 с 16:00 до 20:00).
Надеюсь, поможет
Написанный на Python, такой модуль может работать - https://github.com/AndrewPashkin/pytempo
Вам нужно отслеживать каждую неделю в году, или это всего лишь одна таблица конфигурации для общей недели?