Мы пишем продукт управления записями для школ, и одним из требований является возможность управлять расписанием курсов. Я не смотрел на код для того, как мы имеем дело с этим (я сейчас нахожусь в другом проекте), но, тем не менее, я начал задаваться вопросом, как лучше всего выполнить одну конкретную часть этого требования, а именно, как справиться с тем фактом, что Каждый курс может проводиться один или несколько дней недели, и как лучше всего хранить эту информацию в базе данных. Для обеспечения некоторого контекста таблица 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 бит будет означать, что класс проводится в соответствующий день недели.
Плюсы : Простота реализации (приложение может работать с битовыми манипуляциями), работает с любой базой данных.
Минусы : сложнее писать запросы, использующие столбец DaysOfWeek
(хотя вы могли бы справиться с этим на уровне приложения или создать представления и хранимые процедуры в базе данных, чтобы упростить это), нарушает реляционные модель базы данных.
Возможное решение № 2: Хранить DaysOfWeek в виде строки символов
По сути, это тот же подход, что и использование битового поля, но вместо обработки необработанных битов вы назначаете уникальную букву каждому дню недели, а в столбце DaysOfWeek
просто хранится последовательность букв, указывающая, какие дни курс проводится. Например, вы можете связать каждый день недели с односимвольным кодом следующим образом:
Weekday Letter
------- ------
Sunday S
Monday M
Tuesday T
Wednesday W
Thursday R
Friday F
Saturday U
В этом случае курс, проводимый в понедельник, вторник и пятницу, будет иметь значение 'MTF'
для DaysOfWeek
, тогда как курс, проводимый только по средам, будет иметь значение DaysOfWeek
'W'
.
Плюсы : проще справляться в запросах (т. Е. Вы можете использовать INSTR
или его эквивалент, чтобы определить, проводится ли класс в определенный день). Работает с любой базой данных, которая поддерживает INSTR или эквивалентную функцию (большинство, я бы предположил ...). Также удобнее для просмотра и с первого взгляда, что происходит в запросах, использующих столбец DaysOfWeek
.
Минусы : Единственное реальное «против» - это то, что, подобно подходу с битовыми полями, это нарушает реляционную модель, сохраняя переменное число значений в одном поле.
Возможное решение № 3: использовать таблицу поиска (безобразно)
Другая возможность - создать новую таблицу, в которой будут храниться все уникальные комбинации дней недели, а столбец Course.DaysOfWeek
будет просто внешним ключом этой таблицы поиска. Тем не менее, это решение кажется самым нелегким, и я рассматривал его только потому, что казалось, что Реляционный путь TM делает что-то.
Плюсы : Это единственное «чистое» решение с точки зрения реляционной базы данных.
Минусы : Это не элегантно и громоздко. Например, как бы вы разработали пользовательский интерфейс для назначения соответствующих дней недели для данного курса вокруг таблицы поиска? Я сомневаюсь, что пользователь хочет иметь дело с вариантами выбора «воскресенье», «воскресенье, понедельник», «воскресенье, понедельник, вторник», «воскресенье, понедельник, вторник, среда» и т. Д.
Другие идеи?
Итак, есть ли более элегантный способ обработки нескольких значений в одном столбце? Или одного предложенного решения будет достаточно? Что бы это ни стоило, я думаю, что мое второе решение является, вероятно, лучшим из трех возможных решений, которые я изложил здесь, но мне было бы любопытно посмотреть, есть ли у кого-то другое мнение (или вообще иной подход).