Ответ 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) как "только логические") - используйте прикладной уровень, чтобы заботиться о ссылочной целостности.
Надеюсь, это поможет.