Еженедельные графики - Как вы можете сохранить это в базе данных? - PullRequest
10 голосов
/ 23 декабря 2008

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

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

Чтобы визуализировать это, это что-то вроде плавного "графика"

    | 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... 

Есть ли стандартный способ сделать это или ресурс, который может дать мне некоторые идеи ...

  1. Создание формата, который можно легко сохранять и восстанавливать
  2. Сделать его доступным для поиска в базе данных (например, не нужно десериализовать его для поиска по времени)

[Update]

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

Это также не единственный график, будут сотни устройств, каждое из которых имеет свое расписание, так что оно станет волосатым ... lol ??

Роб спросил, нужно ли отслеживать каждую неделю - Это не так. Это общий график, который будет применяться на весь год (регулярное плановое обслуживание)

Ответы [ 7 ]

10 голосов
/ 23 декабря 2008

Я бы рассмотрел для (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 для проверки нужного столбца DB для дня, который вас интересует.

Примечание: Убедитесь, что вы знаете, какой стандарт использует ваша БД для целого дня недели, и постарайтесь сделать свой код независимым от него (всегда спрашивайте БД). Нам было очень весело с разными стандартами для начала недели (воскресенье или понедельник) и стартового индекса (0 или 1).

2 голосов
/ 23 декабря 2008

Если это будет меняться каждую неделю, тогда настройте таблицу следующим образом:

TABLE:
    StartTime DATETIME    PrimaryKey

Если установлено время начала для определенной даты / часа, то предположим, что оно разрешено, в противном случае отклоните.

Если это общая конфигурация для общей недели, которая не меняется, попробуйте это;

TABLE:
    Hour  INT,
    Day   INT,
    Allow BIT

Затем добавьте строки для каждой комбинации часа / дня.

1 голос
/ 02 октября 2013

Каждое предлагаемое решение хорошо для меня, в любом случае, я бы рассмотрел это, если вы столкнетесь с проблемами производительности и / или размера таблицы. Поскольку вы, вероятно, установили бы связь между временем и вашей сущностью (то есть сервером), размер увеличится на 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).

Надеюсь, это поможет

1 голос
/ 23 декабря 2008

Вы можете легко записать «разрешенные» времена в таблицу. Таким образом, если его там нет, это не разрешено. Если вам нужно более переменное «расписание», вы можете легко добавить поле года и месяца.

 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 года, в которые можно выполнить техническое обслуживание. Покажите как хотите.

1 голос
/ 23 декабря 2008

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

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

Если вы используете SQL, вы можете либо сохранить его в виде двоичного блога и выполнить битовую перестановку, чтобы сравнить, включен ли бит самостоятельно или нет, или вы можете сохранить каждый бит как столбец. MS SQL Server поддерживает до 1024 для стандартных или 30 КБ для широких таблиц, так что вы можете легко уменьшить детализацию до 10 минут для одной или значительно лучше для таблицы 30 КБ.

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

0 голосов
/ 29 июня 2015

Написано на Python, такой модуль может работать - https://github.com/AndrewPashkin/pytempo

0 голосов
/ 23 декабря 2008

Может быть, что-то вроде

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
...