В прошлой статье я говорил про то, что нужно разделять сущности и не дублировать одну и ту же информацию, либо же наоборот, в некоторых особо не удобных случаев лучше эту информацию продублировать и провести денормализацию БД. Нормализация, денормализация, что это вообще за слова такие?
Существует такое понятие как нормальная форма. На собесе могут спросить: сколько нормальных форм ты знаешь? Так вот: многие, очень многие говорят, что их всего 5, что в корне не верно. Это самые часто используемые 5 НФ, а на самом деле их 6 + еще две специальные нормальные формы. Если так ответишь на собесе и потом расскажешь, что это за специальные формы - собеседующий почувствует собственную неполноценность и больше не будет задавать такие вопросы, иначе кто хочет упасть в грязь лицом перед кандидатом-занудой?
Пока что звучит страшно. Ну как обычно, пора привыкнуть. Сейчас объясню и все станет понятнее. Поэтому давай разберемся, что стоит за этими семью нормальными формами. Сразу скажу, что всю эту информацию ты можешь найти в Википедии, но оно тебе надо?
Переменная отношения находится в первой нормальной форме (1НФ) тогда и только тогда, когда в любом допустимом значении отношения каждый его кортеж содержит только одно значение для каждого из атрибутов.
Разве что надо еще ввести понятие Кортеж - это упорядоченный набор значений из фиксированного количества полей, по сути - строка таблицы. В общем, объясняю по-человечески:
Первая НФ
Это когда на разный набор данных есть по отдельному кортежу, а не все в одной строчки пишется для каждого элемента
До приведения:
После приведения:
Вторая НФ
Это когда мы не плодим одну и ту же сущность в одной таблице в виде разных кортежей данных, как в 1НФ
До приведения:
После приведения:
Таблица товаров:
Таблица заказов:
Третья НФ:
Тут посложнее, в третьей НФ мы должны избавиться от транзитивных зависимостей. В нашем примере такая зависимость есть в таблице товаров. Зависимости тут такие: если товар связан со складом, а склад связан со временем работы, то товар связан со временем работы
До приведения:
После приведения:
Четвертая НФ
Здесь настало время рассказать про виды связей таблиц:
- 1 к 1, когда на 1 запись из первой таблице всегда соответствует только 1 запись из второй таблицы. По сути один кортеж данных, разнесенный на 2 таблицы. Пример: Таблицы сотрудников и их рабочих телефонов, при учете, что у каждого сотрудника может быть только один телефон и один телефон может принадлежать только одному сотруднику. Это неправильное отношение. В данном случае данные должны быть слиты в одну таблицу, но иногда, в особых случаях приходится делать и такое, жертвуя логикой в угоду производительности.
- 1 ко многим, ну тут просто: у одной записи в первой таблице может быть много связей в другой. В нашем случае - это таблица товаров и таблица заказов, ведь у одного вида товара может быть несколько заказов.
- многие ко многим. Вот об этом виде связей и есть четвертая НФ.
Смотри, допустим, у нас появляется таблица поставщиков
И нам как-то надо их связать с таблицей товаров, чтобы всегда знать, к какому поставщику адресовать рекламацию. Но если мы напрямую свяжем эти две таблицы, то у нас получится связь многие-ко-многим, ведь у одного поставщика может быть несколько видов товаров и в то же время, один и тот же вид товара может поставляться несколькими поставщиками. То есть многие товары ко многим поставщикам. Чтобы решить эту проблему, мы должны добавить промежуточную таблицу что-то вроде Товары_Поставщики.
Теперь обе таблицы опосредованно (через третью) связаны друг с другом и мы можем сказать, кто нам что поставил.
Пятая НФ
Это как обычно предыдущая, плюс еще некоторые условия. В нашем примере есть зависимость товара от поставщика а еще зависимость заказа от товара и поставщика. При объединении этих трех таблиц (привет, объединение множеств!), мы получим полную билеберду, не связанную с реальностью
Так вот, чтобы отношение находилось в 5 нормальной форме, нам надо иметь однозначные кортежи данных для всех возможных вариантов поставщиков, заказов и товаров, а это еще три таблицы:
Товары_Заказа, Товары_Поставщика, Поставщики_Заказов. В общем, штука, которая может и мозг пополам поломать. Но реальность состоит в том, что как правило, при проектировании ПО, 5 НФ уже является избыточной и поэтому ее не используют так часто.
Шестая НФ
Про нее я тебе расскажу справочно, лично я ее не использовал ни разу за 15+ лет своей карьеры. Но то, что она есть тебе знать надо - на интервью могут спросить. Таблица находится в 6 нормальной форме, когда она не может быть подвергнута дальнейшим декомпозициям без потерь. Бред какой-то, мы уже в 5 все оптимизировали по самые помидоры.
Так вот, собственно, почему ее очень мало где используют. Ее используют в так называемых хронологических базах, то есть БД, в которых данные хранятся не только в их текущем виде, но и хранятся их прошлые значения. И если ты такое скажешь на собесе, то или поразишь собеседующего в самое сердечко или в чувство собственной важности, так как он может этого просто не знать. И если честно, я его понимаю.
Дополнительные Нормальные Формы
Эти 6 форм - стандартные для всех реляционных баз данных, но есть и их дополнения в виде еще двух форм:
- Форма Бойса-Кодда - это расширенная 3 НФ. Наконец-то здесь необходимо сказать про ключевые значения. Ключ - это то, по чему можно однозначно идентифицировать строку в таблице. В нашем случае есть Код товара, это и есть ключ, так как он уникальный во всей таблице. Так же, если нельзя однозначно идентифицировать запись по одному полю, то к нему добавляют второе, а иногда и третье поле, то есть необходимый минимум полей, которые помогают идентифицировать запись. Например в таблице Товары_Поставщики у нас составной ключ из двух полей, так как если мы добавим поле Статус (не знаю чего, просто статус), и оно с большой долей вероятности будет не ключевым. Так вот, эта форма Бойса-Кодда действует только в случае составных ключей, расширяя третью НФ и говорит нам, что ключевые атрибуты того самого составного ключа не должны зависеть от атрибутов не ключевых
- Доменно-ключевая НФ и она скорее про ограничения по данным, которые могут быть записаны в каких-либо ячейках таблицы. И записаны там могут быть только данные из заранее определенного списка. Помимо ограничения доменов, есть еще и ограничение ключей: некоторая комбинация атрибутов может являть собой потенциальный ключ.
Все, я попытался максимально просто раскрыть достаточно сложную тему, но если у тебя есть вопросы - задавай, буду ждать комментариев! А еще - подписок!