Как далеко продвинуться нормализации? - PullRequest
19 голосов
/ 30 января 2009

У меня есть эти таблицы:

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

CreatedByID - это внешний ключ для Employees. У меня есть запрос, который выполняется почти для каждой загрузки страницы.

Плохо ли просто добавлять избыточный столбец OfficeID в Projects, чтобы исключить три объединения? Или я должен сделать следующее:

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

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

Ответы [ 13 ]

36 голосов
/ 30 января 2009

Нормализуй до боли

30 голосов
/ 30 января 2009

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

Недостатки:

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

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

  • Занимает больше места

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

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

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

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

9 голосов
/ 30 января 2009

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

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

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

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

7 голосов
/ 30 января 2009

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

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

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

4 голосов
/ 30 января 2009

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

3 голосов
/ 31 января 2009

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

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

3 голосов
/ 30 января 2009

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

3 голосов
/ 30 января 2009

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

2 голосов
/ 30 января 2009

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

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

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

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

2 голосов
/ 30 января 2009

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

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

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

...