Когда нужно нарушать правила нормализации? - PullRequest
5 голосов
/ 14 января 2010

Пожалуйста, дайте свое мнение о ситуациях, в которых не стоит нормализоваться. Я только что стал свидетелем горячих дискуссий между архитектором и администратором базы данных, который настаивал на том, что база данных СЛИШКОМ нормализована.

Ответы [ 10 ]

11 голосов
/ 14 января 2010

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

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

10 голосов
/ 14 января 2010

Правило нормализует, пока не повредит, а затем денормализует, пока не сработает. (кто это сказал?)

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

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

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

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

6 голосов
/ 14 января 2010

Когда вы оптимизируете преждевременно

Существует некоторая нормализация для обеспечения будущего роста, и вам это может не понадобиться.

Например, представьте, что у вас есть таблица person. Вы можете иметь birthday в качестве столбца, потому что у каждого человека будет только один день рождения.

Если вы строго нормализуете, у вас не будет phone_number и cell_number и fax_number в качестве столбцов в person, но вместо этого может быть таблица phonenumber, где в каждой строке есть число, тип и отношение person_id. Это может быть лучше, чем просто вставлять новые столбцы в таблицу person, потому что

  1. У многих людей не будет всего этого, оставляя много пустых мест, и
  2. Если у кого-то есть 3 номера ячеек, вы бы добавили неудобные столбцы, например cell_number_2

Концерн № 1 действителен, но проблема № 2 может служить примером того, что «вам это не понадобится». Можно сказать «мы разрешаем только один номер ячейки, и все». В этом случае вам может не понадобиться создавать отдельную таблицу для телефонных номеров.

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

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

И еще одна вещь: вам нужно взвесить тот факт, что это плохо для изменения вашей схемы БД, когда ваш код запущен и работает. Так что все в порядке, чтобы сказать «нам это не понадобится», но постарайтесь быть достаточно уверенными, прежде чем совершить коммит.

5 голосов
/ 14 января 2010

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

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

Это, конечно, вопрос суждения, а также указание, а не правило.

2 голосов
/ 14 января 2010

Работали в месте, где они слишком нормализовались.Они удалили столбец «state» из таблицы почтовых адресов.Вместо 2-байтового столбца состояния они помещают целочисленное поле внешнего ключа, связывающее таблицу состояний.

В итоге:

  • Они заменили 2-байтовый столбец состояния на 4-байтовый столбец в таблице адресов.Теперь каждая строка занимает еще 2 байта памяти.

  • Они добавили таблицу состояний с 4-байтовым столбцом первичного ключа и 2-байтовым столбцом состояния.Занимает больше места для хранения этой таблицы.

  • База данных хранит индекс btree ключей в таблице состояний.Занимает больше места.

  • Труднее писать sql для получения адресов.

  • SQL для извлечения адресов медленнее, чем оригинал.

Конечно, это наивно удаляет дублирующиеся неизменяемые данные.В результате он занимает больше дискового пространства, его труднее использовать и он медленнее.

Вы определенно можете нормализовать слишком много.

2 голосов
/ 14 января 2010

Вам нужно найти наилучшее место ... Будучи слишком нормализованным, вы получите множество «раздуваемых» абстрактных структур, которые содержат всего 1 или 2 столбца данных, и в итоге вы объедините 5 таблиц для большинства запросов.

Будучи недостаточно нормализованным, вы получите много данных в разных местах. Это может привести к замедлению работы БД из-за размера кеша и тому подобного. Кроме того, теперь, когда вам нужно что-то обновить, у вас есть 4 разные таблицы для обновления вместо 1, и даже не заставляйте меня проверять соответствие всех данных в разных местах!

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

1 голос
/ 14 января 2010

Хранилище данных часто использует ненормализованный подход по соображениям производительности. За Википедию :

Стандартное руководство по проектированию базы данных заключается в том, что разработчик должен создать полностью нормализованный дизайн; избирательная денормализация может быть впоследствии выполнена по соображениям производительности. Однако в некоторых дисциплинах моделирования, таких как подход к размерному моделированию при проектировании хранилища данных, явно рекомендуют ненормализованные проекты , т.е. проекты, которые в значительной степени не соответствуют 3NF.

1 голос
/ 14 января 2010

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

0 голосов
/ 14 января 2010

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

И звезда, и снежинка приведут к созданию схемы, которую будет намного проще использовать для различных отчетов, настраиваемых выдержек и интерфейса для инструмента OLAP, такого как Cognos Power Play. Обратная сторона? Каждое отклонение от одной из нормальных форм (кроме 1NF) несет с собой аномалию при вставке / обновлении / удалении данных. Если вы действительно знаете нормальные формы, вы будете знать, каковы связанные аномалии. Когда вы напишите процедуры ETL (извлечение, преобразование и загрузка), чтобы сохранить текущую звезду / снежинку, вам придется обходить эти аномалии.

Так когда же схема звезды или снежинки лучше, чем нормализованная схема? Как правило, для хранилищ данных, витрин данных и баз данных отчетов. В моей собственной практике я никогда не создавал ни одного из них, который не был бы серверной частью для базы данных OLTP, а база данных OLPT выигрывает от почти полной нормализации. Не просто денормализовать и отказаться от всей дисциплины. Это похоже на случайное проектирование.

0 голосов
/ 14 января 2010

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

...