Как лучше всего хранить дни недели, в которые происходит событие, в реляционной базе данных?
Мы пишем продукт управления записями для школ, и одним из требований является возможность управлять расписанием курсов. Я не смотрел на код для того, как мы имеем дело с этим (я сейчас нахожусь в другом проекте), но, тем не менее, я начал задаваться вопросом, как лучше всего выполнить одну конкретную часть этого требования, а именно, как справиться с тем фактом, что Каждый курс может проводиться один или несколько дней недели, и как лучше всего хранить эту информацию в базе данных. Чтобы обеспечить некоторый контекст, голые костиCourse
таблица может содержать следующие столбцы:
Course Example Data
------ ------------
DeptPrefix ;MATH, ENG, CS, ...
Number ;101, 300, 450, ...
Title ;Algebra, Shakespeare, Advanced Data Structures, ...
Description ;...
DaysOfWeek ;Monday, Tuesday-Thursday, ...
StartTime
EndTime
Что мне интересно, так это лучший способ справиться сDaysOfWeek
столбец в этом (надуманном) примере? Проблема, с которой я столкнулся, заключается в том, что это многозначное поле: то есть вы можете пройти курс в любой день недели, и один и тот же курс может проходить более одного дня. Я знаю, что некоторые базы данных изначально поддерживают столбцы с несколькими значениями, но есть ли «лучший способ» справиться с этим, если база данных изначально не поддерживает это?
Пока что я нашел следующие возможные решения, но мне интересно, есть ли у кого-нибудь что-нибудь лучше:
Возможное решение № 1: Рассматривайте DaysOfWeek как битовое полеЭто было первое, что пришло мне в голову (я не уверен, хорошо это или нет ...). В этом решенииDaysOfWeek
будет определяться как байт, а первые 7 бит будут использоваться для представления дней недели (один бит на каждый день). 1 бит будет означать, что урок проводится в соответствующий день недели.
Pros: Простота реализации (приложение может справляться с битовыми манипуляциями), работает с любой базой данных.
Cons: Сложнее писать запросы, использующиеDaysOfWeek
столбец (хотя вы могли бы иметь дело с этим на уровне приложения или создать представления и хранимые процедуры в базе данных, чтобы упростить это), нарушает модель реляционной базы данных.
По сути, это тот же подход, что и использование битового поля, но вместо того, чтобы работать с необработанными битами, вы назначаете уникальную букву каждому дню недели, аDaysOfWeek
В столбце хранится последовательность букв, указывающая, в какие дни проводится курс. Например, вы можете связать каждый день недели с односимвольным кодом следующим образом:
Weekday Letter
------- ------
Sunday S
Monday M
Tuesday T
Wednesday W
Thursday R
Friday F
Saturday U
В этом случае курс, проводимый в понедельник, вторник и пятницу, будет иметь значение'MTF'
заDaysOfWeek
в то время как класс, проводимый только по средам, будет иметьDaysOfWeek
ценность'W'
.
Pros: Легче обрабатывать запросы (т. Е. Вы можете использоватьINSTR
или его эквивалент, чтобы определить, проводится ли класс в данный день). Работает с любой базой данных, которая поддерживает INSTR или эквивалентную функцию (большинство, я бы предположил ...). Также удобнее смотреть и легко увидеть, что происходит в запросах, использующихDaysOfWeek
колонка.
ConsЕдинственный реальный аргумент «против» заключается в том, что, подобно подходу с битовыми полями, это нарушает реляционную модель, сохраняя переменное число значений в одном поле.
Возможное решение № 3: использовать таблицу поиска (безобразно)Другая возможность - создать новую таблицу, в которой будут храниться все уникальные комбинации дней недели, и иметьCourse.DaysOfWeek
столбец просто будет внешним ключом в эту таблицу поиска. Тем не менее, это решение кажется самым не элегантным, и я рассматривал его только потому, что оно выглядело как «Реляционный путь».TM делать вещи.
ProsЭто единственное решение, «чистое» с точки зрения реляционной базы данных.
Cons: Это не элегантно и громоздко. Например, как бы вы разработали пользовательский интерфейс для назначения соответствующих дней недели для данного курса вокруг таблицы поиска? Я сомневаюсь, что пользователь хочет иметь дело с вариантами выбора «воскресенье», «воскресенье, понедельник», «воскресенье, понедельник, вторник», «воскресенье, понедельник, вторник, среда» и т. Д.
Другие идеи?Итак, есть ли более элегантный способ обработки нескольких значений в одном столбце? Или одного предложенного решения будет достаточно? Что бы это ни стоило, я думаю, что мое второе решение является, вероятно, лучшим из трех возможных решений, которые я изложил здесь, но мне было бы любопытно посмотреть, есть ли у кого-то другое мнение (или вообще другой подход).