Из-за относительно небольшого размера базы данных, подход с двумя таблицами кажется более подходящим , так как это структура, которая более нормализована и с большей вероятностью поддерживает возможные расширения. Будут ли проблемы с производительностью, мы будем склонны денормализовать, то есть использовать подход с одной таблицей.
В целом, при рассмотрении этого типа вопросов одним из соображений, возможно, наиболее важным, является типичные схемы использования для различных частей данных .
Правдоподобным предположением является то, что таблица Customer интенсивно используется [главным образом] только для чтения; такое использование может поддерживаться путем отдельного хранения обновленных (и не часто запрашиваемых) данных, таких как отметка времени последнего уведомления. Если информация из связанной таблицы будет чаще включаться в запросы, то может быть целесообразно вместо нее поместить эту информацию в основную таблицу.
О проблемах с редким использованием столбца меток времени обновления
(безмолвие, так как подход с двумя таблицами, скорее всего, будет выбран, но в целом ...)
Тот факт, что только 10% записей будут содержать некоторую информацию в столбце метки времени, намекает на некоторую «расточительность», если бы мы выбрали вариант 1. На самом деле редкое использование этого столбца мало влияет на размер базы данных и производительность в целом. Например, если таблица легко включает столбец переменной длины, накладные расходы по размеру фактически равны нулю; если это первый обнуляемый столбец или столбец переменной длины, будет взиматься налог на минимальный размер, но он не должен иметь большого значения. (В более поздних версиях SQL Server 2005, я думаю, можно использовать разреженный столбец, хотя это вряд ли стоит для базы данных размером в тысячи или даже десятки тысяч записей.)
В столбце "sendudpate"
Также неплохо было бы удалить логический столбец sendupdate из главной таблицы, поместив всю связанную с обновлением информацию в связанную таблицу. Тем не менее, я полагаю, что тот факт, что клиент получает обновления, не должен подразумеваться для базового клиента, имеющего запись в соответствующей таблице. Вместо этого введите столбец «sendupdate» в соответствующий, возможно, не просто логический, а, например, код частоты (например, 0 = нет обновлений, 1 = обновляйте ежедневно, 7 = обновляйте еженедельно и т. Д.). Я предлагаю, чтобы все клиенты имели запись в соответствующей таблице, но тот факт, что они имеют такую запись, является необходимым, но не достаточным условием, например, позволяет временно отключить обновления и т. Д. И т. Д.
О том, «ломается» ли подход одной таблицы и правила нормализации
Важно различать физический и логический дизайн базы данных. Вполне возможно иметь физическую схему, которая не нарушает никаких правил нормализации, но которая не является логически нормализованной. В общих чертах, одна основная мантра нормализации - хранить только один тип сущности на таблицу. Пока нет дублирования данных, можно поместить в одну и ту же таблицу в одной широкой записи информацию, фактически относящуюся к двум логическим объектам.
Иллюстрированный с базой данных клиентов в вопросе, можно решить, что физические записи будут включать дату последнего обновления, отправленного данному клиенту. Справедливо, физически правило нормализации не нарушено ... Однако логически можно утверждать, что «Административная информация клиента» (Имя, адрес ...) и «Информация обновления» (дата последнего отправленного обновления) - это две разные сущности, даже хотя они, кажется, находятся в отношении 1-1 на данный момент .
Следовательно, состояние нормализации логической модели, где сущности эффективно определены, часто находится в глазах наблюдателя, поскольку можно (иногда очень справедливо и разумно) утверждать, что элементы данных, которые все имеют 1-1 отношения принадлежат одному и тому же понятию (сущности).
Q: Что такое логическая и физическая нормализация? ... Разве не нормализуются правила нормализации? Я попытался объяснить это выше.
«Физическая нормализация» (или, скорее, нормальная форма физической схемы) рассматривает фактическую структуру таблиц и их взаимосвязей и применяет простые правила, чтобы узнать, какой нормальной форме удовлетворяет такая схема.
«логическая нормализация» (или, скорее, нормальная форма модели данных) рассматривает эффективные объекты, найденные в системе.
Таким образом, чтобы привести другой пример, при разработке простой базы данных о продаже домов для продажи можно решить, что единый концепт «ДОМА» будет храниться в одной таблице со столбцами, такими как «Адрес», «Кухня_Расположение», «Ливинг_Рум_Ареа» и т.д. И такая таблица будет «работать» и технически иметь определенную нормальную форму; это было бы несколько непрактично, не допуская перечисления домов с двумя кухнями и т. д. В качестве альтернативы можно было бы увидеть дом как «Местоположение» (адрес и, возможно, другую информацию администратора) и «Комнаты» (тип, поверхность, информация о настиле ...), где каждая концепция (местоположение, комната) хранится в отдельной таблице, причем одно местоположение связано с несколькими комнатами.
Таким образом, обе эти модели можно поместить в нормальную физическую схему, можно сказать, что первая модель денормализована (на логическом уровне) из-за того факта, что она не отражает должным образом действующие объекты.
Q: Не понимаю, как вы предлагаете явно отметить тот факт, что клиент получает обновления?
A:
SELECT whatever
FROM Customers
JOIN NotificationTable N on N.CustomerId = C.CustomerId
WHERE N.notificationFrequency > 0
В приведенном выше,
- JOIN фиксирует первое условие для клиента, которого нужно уведомить: должна быть соответствующая запись в таблице уведомлений.
- предикат WHERE N.notificationFrequency> 0 фиксирует очень явное условие, чтобы столбец notificaionFrequency был положительным.