Планирование сотрудников - какую структуру данных использовать?

Вопрос

Я пытаюсь написать простой сотрудник, планирующий программное обеспечение для примерно 10-20 человек в моей компании по разработке программного обеспечения. После некоторого рассмотрения я решил написать веб-приложение в Python, Ruby или PHP + Postgres/MySQL DB. При разработке моделей баз данных я начал задаваться вопросом, какая структура данных будет действительно лучшей для такого типа приложений.

Как это будет выглядеть

Пример приложения, показывающего представление месяца, будет таким же:

 OCTOBER    1 2 3 4 5 6 7 8 9 ...
John Apple  M M A A N N O O O ...
Daisy Pear  O O O M M A A N N ...
Steve Cat   A A N N O O O M M ...
Maria Dog   N N O O O M M A A ...

где M → для утреннего сдвига; A → Дневной сдвиг и т.д. (Буквы могут быть изменены на коды)

Какая структура данных или дизайн базы данных будут лучшими для этого? Я думал о хранении строк (максимум 31 символ → 1 char, 1 день), аналогично → "MMAANNOOOAAMMNNAAOO..." для каждого пользователя; Таблица месяца содержит такие строки для каждого сотрудника.

Что бы вы предложили?

Ответ 1

Я бы выбрал звезду Кимбалла с тремя столами (Date, Employee, Schedule), потому что рано или поздно вас попросят создать (требующие) отчеты из этого. Кто работал большинство ночей? Кто работал большинство выходных? Кто никогда не работает по выходным? Почему я всегда намечен на пятницу? В какой день недели некоторые сотрудники, скорее всего, не будут появляться? И т.д., И т. Д...

Таблицы будут:

TABLE dimDate (
    KeyDate
  , FullDate
  , DayOfWeek
  , DayNumberInWeek
  , IsHoliday
  ,... more here
)

Вы можете предварительно заполнить таблицу dimDate на 10 лет или около того - может потребоваться время от времени изменять столбец "IsHoliday".

Таблица сотрудников также изменяется (относительно) редко.

TABLE dimEmployee (
    KeyEmployee
  , FirstName
  , LastName
  , Age
  , ... more here
)

В таблице расписаний вы должны будете заполнить график работы. Я также предложил "HoursOfWork" для каждой смены, чтобы было легко объединять часы в отчетах, например: "Сколько часов работал Джон Доу в прошлом году в праздники? "

TABLE
factSchedule (
    KeySchedule  -- surrogate PK
  , KeyDate      -- FK to dimDate table
  , KeyEmployee  -- FK to dimEmployee table
  , Shift        -- shift number (degenerate dimension)
  , HoursOfWork  -- number of work hours in that shift
)

Вместо суррогатного KeySchedule вы также можете объединить KeyDate, KeyEmployee и Shift в составной первичный ключ, чтобы убедиться, что вы не можете назначить одного человека на одну и ту же смену в тот же день. Проверьте это на прикладном уровне, если используется суррогатный ключ. При запросе объединяйте таблицы, например:

SELECT SUM(s.HoursOfWork)
 FROM factSchedule AS s
 JOIN dimDate      AS d ON s.KeyDate = d.KeyDate
 JOIN dimEmployee  AS e ON s.KeyEmployee = e.KeyEmployee
WHERE e.FirstName='John'
  AND e.LastName='Doe'
  AND d.Year = 2009
  AND d.IsHoliday ='Yes';

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

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


empschd_model_01

Ответ 2

Быстрый ответ:

  • EmployeeID
  • Дата
  • ShiftType

Тем не менее, лучший дизайн базы данных во многом зависит от того, что вы собираетесь делать с данными. Если все, что вам нужно сделать, это сохранить записи и отобразить их в таблице, подобной вашему примеру, ваш подход (хотя и не элегантный) будет работать.

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

Ответ 3

Я бы предложил более норамплированную базу данных, например. таблица для лиц и та, которая является продуктом информации о смене для perdon и даты.