Открыть сервис

Нормализация базы данных

Нормализация базы данных — это процесс проектирования реляционной базы данных, направленный на устранение избыточности данных и обеспечение их целостности путём приведения структуры таблиц к ряду последовательных нормальных форм. Основная цель нормализации — минимизация дублирования информации и предотвращение аномалий при вставке, обновлении и удалении записей. Концепция была предложена Эдгаром Коддом в 1970 году в рамках реляционной модели данных и впоследствии развита другими исследователями, в частности Реймондом Бойсом и Рональдом Фаджином.

История и предпосылки

До появления реляционных баз данных данные часто хранились в плоских файлах или иерархических структурах, что приводило к значительной избыточности и сложности поддержки. В 1970 году Эдгар Кодд опубликовал работу «A Relational Model of Data for Large Shared Data Banks», где впервые описал реляционную модель. Нормализация стала логическим следствием этой модели: Кодд определил первую, вторую и третью нормальные формы. Позже, в 1974 году, Реймонд Бойс и Эдгар Кодд совместно разработали нормальную форму Бойса — Кодда (BCNF), которая является более строгой версией третьей нормальной формы. В 1979 году Рональд Фаджин ввёл четвёртую нормальную форму, связанную с многозначными зависимостями, а затем и пятую нормальную форму, связанную с зависимостями соединения.

В СССР и России теория нормализации получила распространение в 1980-х — 1990-х годах с развитием СУБД на основе реляционной модели, таких как dBASE, FoxPro, затем PostgreSQL, MySQL и других.

Основные понятия

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

Нормальные формы

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

Первая нормальная форма (1NF)

Таблица находится в первой нормальной форме, если выполнены следующие условия:

Пример нарушения: в одной ячейке столбца «Телефоны» перечислены несколько номеров через запятую. Для приведения к 1NF необходимо создать отдельную строку для каждого номера.

Вторая нормальная форма (2NF)

Таблица находится во второй нормальной форме, если она находится в 1NF и каждый неключевой атрибут (не входящий в первичный ключ) функционально полно зависит от всего первичного ключа. Это условие актуально для таблиц с составными первичными ключами. Если атрибут зависит только от части ключа, такую зависимость называют частичной.

Пример нарушения: таблица «Заказы» с составным ключом (ID_заказа, ID_товара) и атрибутом «Цена товара» — цена зависит только от ID_товара, а не от всей комбинации. Требуется вынести информацию о товаре в отдельную таблицу.

Третья нормальная форма (3NF)

Таблица находится в третьей нормальной форме, если она находится в 2NF и отсутствуют транзитивные зависимости — то есть неключевые атрибуты не зависят от других неключевых атрибутов. Иными словами, каждый неключевой атрибут должен напрямую зависеть от первичного ключа.

Пример нарушения: таблица «Сотрудники» с атрибутами: ID_сотрудника (ключ), Отдел, Адрес_отдела. Адрес_отдела зависит от Отдела, а не напрямую от ID_сотрудника. Следует создать отдельную таблицу «Отделы».

Нормальная форма Бойса — Кодда (BCNF)

Нормальная форма Бойса — Кодда является более строгим вариантом 3NF. Таблица находится в BCNF, если для каждой нетривиальной функциональной зависимости X → Y (где Y не является подмножеством X) набор X является потенциальным ключом (сверхключом) отношения. На практике BCNF часто совпадает с 3NF, но существуют ситуации, когда 3NF выполнена, а BCNF — нет. BCNF устраняет остаточные аномалии, возникающие из-за пересекающихся составных ключей.

Четвёртая нормальная форма (4NF)

Таблица находится в четвёртой нормальной форме, если она находится в BCNF и в ней отсутствуют нетривиальные многозначные зависимости. Многозначная зависимость (X →→ Y) возникает, когда заданный набор значений X определяет набор значений Y, не зависящий от остальных атрибутов. Пример: у одного преподавателя может быть несколько курсов и несколько учебных групп — при перечислении всех комбинаций возникает избыточность.

Пятая нормальная форма (5NF)

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

Доменно-ключевая нормальная форма (DKNF)

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

Преимущества и недостатки нормализации

Преимущества

Недостатки

Практическая реализация

В современной практике проектирования баз данных часто используется процесс нормализации как итеративный метод. Типичная последовательность действий:

  1. Определить сущности и атрибуты на основе требований.
  2. Представить данные в виде ненормализованной таблицы.
  3. Привести таблицу к 1NF, устранив повторяющиеся группы.
  4. Привести к 2NF, устранив частичные зависимости.
  5. Привести к 3NF (или BCNF), устранив транзитивные зависимости.

На практике многие проектировщики сразу моделируют схему, находящуюся в 3NF, не проходя через последовательное преобразование. Инструменты CASE (например, ERwin, PowerDesigner, Draw.io) позволяют автоматизировать процесс.

В веб-приложениях и OLTP-системах (системы операционной обработки транзакций) нормализация до 3NF является стандартом. В аналитических системах (OLAP) и хранилищах данных часто используется снежинка или звёздная схема, которые могут быть денормализованы для ускорения агрегаций.

Пример нормализации

Исходная ненормализованная таблица (список заказов):

Номер заказаКлиентГородТовары
101ИвановМосква«Ручка», «Тетрадь»
102ПетровСанкт-Петербург«Карандаш»

Шаг 1: 1NF — разворачиваем списки товаров в отдельные строки, добавляем первичный ключ (например, составной из номера заказа и товара).

Номер заказаКлиентГородТовар
101ИвановМоскваРучка
101ИвановМоскваТетрадь
102ПетровСанкт-ПетербургКарандаш

Шаг 2: 2NF — выявляем частичную зависимость: «Клиент» и «Город» зависят только от номера заказа, а не от товара. Создаём две таблицы:

Таблица «Заказы»:

Номер заказаКлиентГород
101ИвановМосква
102ПетровСанкт-Петербург

Таблица «Состав заказа»:

Номер заказаТовар
101Ручка
101Тетрадь
102Карандаш

Шаг 3: 3NF — проверяем транзитивную зависимость: «Город» зависит от «Клиента»? Если у клиента всегда один город, то возникает транзитивная зависимость (номер заказа → клиент → город). Создаём отдельную таблицу «Клиенты»:

Таблица «Клиенты»:

ID_клиентаИмяГород
1ИвановМосква
2ПетровСанкт-Петербург

Таблица «Заказы»: (содержит ID_клиента вместо имени и города)

Номер заказаID_клиента
1011
1022

Таблица «Состав заказа» остаётся без изменений.

После этого схема соответствует третьей нормальной форме.

Критика и альтернативы

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

Источники

  1. Codd, E. F. (1970). «A Relational Model of Data for Large Shared Data Banks». Communications of the ACM.
  2. Date, C. J. (2003). «An Introduction to Database Systems». Addison-Wesley.
  3. Когаловский М. Р. (2005). «Энциклопедия технологий баз данных». Финансы и статистика.
  4. Кузнецов С. Д. (2012). «Базы данных: модели и языки». Бином-Пресс.

BFOmetr — база данных и аналитика по компаниям России.

На главную BFOmetr →