@MoonMaster
Программист и этим все сказано

Нормализация БД. Зло или добро?

Добрый день!

Недавно смотрел интересную презентацию человека, который реализовал свой стартап до полноценного проекта. В этом проекте он использовал БД Postgres. Все конечно было интересно, но он сказал одну вещь, которая меня шокировала. Он сказал так: "Нормализация это зло! В некоторых случаях (этот процент небольшой) и при необходимости используйте нормализацию БД." Я никогда еще не делал проекты связанные с запросом данных в БД или вообще работой с БД, но проходил теорию по данному вопросу (в университете). И у меня возник вполне резонный вопрос: действительно ли нормализация БД является не лучшим союзником в реализации своего проекта (программы)?
  • Вопрос задан
  • 3044 просмотра
Решения вопроса 3
newross
@newross
Product owner
Сильно зависит от масштаба проекта. Не стоит бросаться из крайности в крайность.
Для мелких проектов нормализация делает работу проще.
Но когда речь идет об огромных объемах данных и высокой частотой запросов, нормализация становится врагом. Даже простые JOIN увеличивают время выполнения запросов на порядок. Поэтому денормализация БД, внесение избыточности - обычная практика для HiLoad.
Ответ написан
Комментировать
pi314
@pi314
Президент Солнечной системы и окрестностей
Нормализация ради нормализации - зло в подавляющем большинстве случаев! Нормализация, как часть продуманного проектирования или рефакторинга модели данных - однозначно добро. Структура БД должна быть, по возможности, оптимальной для запросов, выполняемых на ней приложением, а вовсе не соответствовать какой-то там нормальной форме :) Это "оптимально" может в каждом конкретном случае зависеть от кучи факторов, начиная от самих запросов и особенностей конкретной использованной СУБД, и вплоть до объемов доступной памяти и скорости обращения к диску.
Ответ написан
Комментировать
Therapyx
@Therapyx
Data Science
По мне так - везде найдется тот, кто будет критиковать даже самый лучше вещи в мире.
И вот это видимо и есть такой случай. Ниразу не видел, чтобы нормализацию выставляли в плохом свете. Конечно, если ваш проект, программа на столько маленькая, что можно обойтись и без нормализации и при этом останется такое же удобство, быстродейственность, то это да - нормализация мб и не нужна. Но у проектов есть чудесное свойство, а именно развиваться :) И вот лучше такие вещи продумывать заранее, ежели потом держаться за голову.
Ответ написан
Пригласить эксперта
Ответы на вопрос 5
Fesor
@Fesor
Full-stack developer (Symfony, Angular)
Все зависит от контекста высказывания (задачи разные бывают). Бросаться в крайности это глупо (только ситхи все возводят в абсолют (с) Оби)

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

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

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

Именно по причине несовпадения двух структур БД: максимально нормализованной, удобной для разработчика/проектировщика, и оптимизированной для выполнения запросов - стандартный цикл проектирования БД включает в себя этап нормализации до опредленного уровня (хотя бы до 3нф), и последующей денормализации для ускорения конкретных запросов (также, как и построение необходимых индексов). Т.к. денормализация требует усложнения логики работы с базой (те самые обновления в нескольких местах), эту логику (чаще всего это хранимки или триггеры, реже - на стороне приложения) нужно реализовывать максимально аккуратно и формально. Это похоже на написание кода на высокоуровневом языке и последующая его компиляция под конкретную платформу с максимальными оптимизациями. Единственное важное отличие - особенности целевой платформы известны заранее, и компилятор, учитывающий эти особенности, можно написать один раз, а вот особенности работы БД в каждой задаче - свои, поэтому в каждом случае нужно проводить работу по оптимизации БД с нуля.

Нужно отметить, что в современных системах денормализация схемы - не единственный и не всегда лучший способ повышения производительности. Кэширование часто используемых данных в каком-нибудь memcached - иногда проще и эффективнее, чем денормализация БД и поддержка ее согласованности.
Ответ написан
Комментировать
@maxkoryukov
Родился, тусуюсь
Давайте разбираться.

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

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

Я бы старался нормализовать данные, но не до академического фанатизма, а до той степени, когда таблицы не вызывают отвращения ни у меня, ни у оптимизатора запросов используемой СУБД.
Ответ написан
Комментировать
@coodan
Согласен. Очень плохая практика, и ее рост ничего не доказывает.

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

Чувак просто слышал звон, да не знает где он. Взял мощную СУБД, а освоить мозгов не хватило. Вот и хвастается теперь своим невежеством, полагая, что он самый умный, а остальные дураки все.
Ответ написан
Комментировать
@kofon
Я человек
Если у тебя ещё нет опыта работы, то сделай чтобы он появился.
А то сейчас ты можешь сделать преждевременный вывод, и возможно он будет ошибочным.

А на счёт зло добро, не знаю...
ИМХО, смотря до какой степени проводить нормализацию
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы