Как далеко добиться нормализации в дизайне базы данных?

У меня есть следующие таблицы:

Projects(projectID, CreatedByID)
Employees(empID,depID)
Departments(depID,OfficeID)
Offices(officeID)

( "CreatedByID" - это внешний ключ для сотрудников.)

И у меня есть запрос, который мне нужно запустить почти для каждого запроса веб-приложения, которое захватывает все проекты в офисе. Неправильная практика заключается в том, чтобы просто добавить избыточный столбец "OfficeID" в проекты для устранения трех соединений? Или я должен сделать следующее?

SELECT * 
FROM Projects P
JOIN Employees E ON P.CreatedBY = E.EmpID
JOIN Departments D on E.DepID = D.DepID
JOIN Offices O on D.officeID = O.officeID
WHERE O.officeID = @SomeOfficeID

Пока я не вижу проблемы с производительностью?

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

Ответ 1

Денормализация имеет преимущество быстрого SELECT при больших запросах.

Недостатки:

  • Требуется больше кодирования и времени для обеспечения целостности (что наиболее важно в вашем случае)

  • Это медленнее на DML (INSERT/UPDATE/DELETE)

  • Требуется больше места

Что касается оптимизации, вы можете оптимизировать либо для более быстрого запроса, либо для более быстрого DML (как правило, эти два являются антагонистами).

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

В случае индексов RDBMS делает это за вас, но в случае денормализации вам нужно будет сам его закодировать. Что делать, если Department перемещается в другой Office? Вам нужно будет исправить это в трех таблицах вместо одного.

Итак, как я вижу из имен ваших таблиц, там не будет миллионов записей. Таким образом, вам лучше нормализовать ваши данные, будет проще управлять.

Ответ 2

Нормализовать, пока это не повредит, затем денормализовать, пока он не будет работать

Ответ 3

Всегда нормализуйте, насколько это необходимо, чтобы устранить проблемы с целостностью базы данных (т.е. потенциальные дублированные или отсутствующие данные).

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

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

Кроме того, как упоминал Джон, если вы в конечном итоге нуждаетесь в денормализованных данных (для скорости/отчетности/etc), создайте его в отдельной таблице, сохраняя необработанные данные.

Ответ 4

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

Я буду больше беспокоиться о влиянии на код, который вызывает это. Нормализованные базы данных намного проще программировать и почти всегда приводят к повышению эффективности внутри самого приложения.

Тем не менее, не нормализуйтесь за пределами разума. Я видел нормализацию для нормализации, которая обычно заканчивается в базе данных с одной или двумя таблицами фактических данных и 20 таблицами, заполненными только внешними ключами. Это явно переборщило. Обычно я использую правило: если данные в столбце в противном случае были бы дублированы, это должно быть нормализовано.

Ответ 5

Администратор базы данных должен быть обеспокоен, если ваш db не был правильно нормализован для начала. После тщательной оценки производительности и определения узких мест вы можете начать денормализацию, но я был бы крайне осторожен.

Ответ 6

Лучше сохранить эту схему в третьей нормальной форме и позволить вашему администратору базы данных жаловаться на стоимость соединений.

Ответ 7

Меня больше всего беспокоят администраторы баз данных, которые предупреждают вас о стоимости объединений, если вы не находитесь в очень патологической ситуации.

Ответ 8

Вы не должны смотреть на денормализацию, прежде чем пробовали все остальное.

Является ли производительность этого действительно проблемой? У вашей базы данных есть какие-либо функции, которые вы можете использовать для ускорения работы без ущерба для целостности? Можете ли вы увеличить производительность за счет кэширования?

Ответ 9

Если вы используете Integer (или BIGINT) в качестве идентификатора, и они являются кластеризованным первичным ключом, вы должны быть в порядке.

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

Если вы когда-нибудь найдете необходимость денормализовать данные, вы можете создать таблицу кеша по расписанию или триггеру.

Ответ 10

Нормализовать, чтобы моделировать концепции в вашем дизайне и их отношения. Подумайте, какие отношения могут измениться, и что такое изменение будет означать с точки зрения вашего дизайна.

В схеме, которую вы опубликовали, есть то, что выглядит для меня как вопиющая ошибка (которая может быть не ошибкой, если у вас есть специальный случай с точки зрения организации вашей организации) - подразумевается неявное предположение, что каждый отдел находится в точно одном офисе и что все сотрудники, находящиеся в одном отделе, работают в этом офисе.

Что делать, если отдел занимает два офиса?

Что делать, если сотрудник номинально принадлежит одному отделу, но работает из другого офиса (при условии, что вы имеете в виду физические офисы)?

Ответ 11

В приведенном примере приведенные индексы, правильно настроенные на таблицах, должны позволять соединениям встречаться очень быстро и хорошо масштабироваться до 100 000 строк. Обычно это подход, который я использую для решения проблемы.

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

Ответ 12

Не денормировать.

Создайте свои таблицы в соответствии с простыми и обоснованными принципами проектирования, которые упростят реализацию всей вашей системы. Простота сборки, заполнения, использования и администрирования базы данных. Легко и быстро запускать запросы и обновления. Легко пересматривать и расширять дизайн стола, когда ситуация требует его, и ненужно делать это по причинам света и временного характера.

Один набор принципов проектирования - это нормализация. Нормализация приводит к легко и быстро обновляемым таблицам (включая вставки и удаления). Нормализация устраняет аномалии обновлений и устраняет возможность использования базы данных, которая противоречит самой себе. Это предотвращает множество ошибок, делая их невозможными. Это также предотвращает множество узких мест обновления, делая их ненужными. Это хорошо.

Существуют и другие наборы принципов проектирования. Они приводят к разработке таблиц, которые полностью не нормализованы. Но это не "денормализация". Это просто другой дизайн, несколько несовместимый с нормализацией.

Один набор принципов проектирования, который приводит к радикально отличающейся конструкции от нормализации, - это схема звездной схемы. Звездная схема очень быстро подходит для запросов. Даже крупномасштабные объединения и агрегации могут быть выполнены в разумные сроки, учитывая хорошую СУБД, хороший физический дизайн и достаточное количество аппаратного обеспечения для выполнения работы. Как и следовало ожидать, звездная схема страдает аномалиями обновления. Вы должны программировать вокруг этих аномалий, когда вы держите базу данных в актуальном состоянии. Вам, как правило, потребуется тщательно контролируемый и тщательно построенный ETL-процесс, который обновляет схему звезд от других (возможно, нормализованных) источников данных.

Использование данных, хранящихся в схеме звезд, значительно упрощается. Это так просто, что, используя какой-то OLAP и механизм отчетности, вы можете получить всю необходимую информацию без написания кода и не жертвуя слишком высокой производительностью.

Для разработки хорошей нормированной схемы требуется хороший и несколько глубокий анализ данных. Ошибки и пропуски в анализе данных могут привести к неоткрытым функциональным зависимостям. Эти неоткрытые FDs приведут к невольным отклонениям от нормализации.

Он также принимает хороший и несколько глубокий анализ данных для разработки и построения хорошей звездной схемы. Ошибки и ошибки при анализе данных могут привести к неудачному выбору размеров и детализации. Это сделает почти невозможным создание ETL и/или сделает информацию, несущую способность звезды неадекватной для возникающих потребностей.

Хороший и несколько глубокий анализ данных не должен служить оправданием для анализа паралича. Анализ должен быть правильным и достаточно полным за короткий промежуток времени. Сокращение для небольших проектов. Дизайн и реализация должны быть способны выдержать некоторые поздние дополнения и исправления к анализу данных и требованиям, но не постоянный поток изменений требований.

Этот ответ расширяется по вашему первоначальному вопросу, но я думаю, что это важно для разработчика базы данных.

Ответ 13

Нормализация: - это решение о качестве.

Денормализация: - это решение производительности.

Вот почему он сказал -

Нормализовать, пока это не повредит, де-нормализуйте, пока он не работает.


В следующих решениях по качеству указывается, что является наименьшей нормальной формой, с которой вы можете жить:

  • Сколько избыточности важно для ваших таблиц?
  • Как быстро управление данными вы хотите?
  • Насколько ясен вам отношение между вашими таблицами?

В следующих решениях о производительности указано, что является самой высокой нормальной формой, приемлемой для ваших клиентов/клиентов/приложений:

  • Является ли мой запрос базы данных достаточно быстрым?
  • Слишком много объединений, вызывающих замедление?

После того, как вы исправили наименьшую и самую высокую нормальную форму, приемлемую в вашем случае, выберите нормальную форму где-нибудь между.