Нормализация реляционной базы данных
Разберите правила 1НФ, 2НФ и 3НФ и исправьте исходную структуру, сохранив все этапы преобразования.
Один проект — три этапа
Все практические выполняются последовательно в одном файле diagrams.net. На каждой практической добавляются новые страницы, а прежние остаются для проверки хода проектирования. Все задания выполняются на схеме; отдельные текстовые ответы и автоматическое тестирование здесь не нужны.
Две части занятия: сначала изучите объяснения и примеры, затем перейдите к самостоятельным заданиям по магазину «ТехноКорзина».
Что такое нормализация и почему она нужна?
Нормализация — последовательная проверка и преобразование структуры реляционной базы данных для уменьшения ненужного повторения фактов и неправильных зависимостей между полями. Она помогает избежать проблем при вставке, изменении и удалении данных.
Например, если адрес покупателя записан в каждой строке его заказов, изменение адреса потребует менять множество строк. Одно пропущенное изменение — и у одного клиента в разных заказах окажутся разные актуальные адреса.
Первая нормальная форма — 1НФ
В 1НФ каждое пересечение строки и столбца содержит одно значение выбранного типа, нет списков и повторяющихся наборов полей. Строки можно однозначно отличать по ключу.
| Студент | Кружки |
|---|---|
| Ирина | Шахматы, Роботы |
В одной ячейке два отдельных значения.
| Студент | Кружок |
|---|---|
| Ирина | Шахматы |
| Ирина | Роботы |
В каждой ячейке один кружок; для реальной БД нужны стабильные идентификаторы.
Для таблицы покупок после разбиения списка товаров в записи одна строка может описывать одну позицию одного заказа. При условии «один товар не встречается дважды в одном заказе» строку однозначно определит пара (номер_заказа, код_товара) — это составной ключ.
количество = 3, а не три строки, если в условиях задачи учёт ведётся по позициям.Вторая нормальная форма — 2НФ
Таблица удовлетворяет 2НФ, если уже находится в 1НФ и каждый неключевой атрибут полностью функционально зависит от всего кандидатного ключа, а не только от части составного ключа. Для базового упражнения рассмотрим выбранный составной PK.
Функциональная зависимость A → B означает: одно и то же значение A определяет одно конкретное значение B. Например, если ID урока неизменно соответствует названию урока, то ID_урока → название_урока.
Когда в одной таблице с PK (урок_id, тема_id) хранится название_урока, описание урока будет повторяться для каждой темы. Решение — хранить сведения об уроке отдельно, а в таблице пар оставить его ID.
Третья нормальная форма — 3НФ
После достижения 2НФ проверяем транзитивные зависимости неключевых полей. Для данного курса используем практическое правило: не храните в таблице факты, которые описывают другой самостоятельный объект и зависят от неключевого атрибута.
Сотрудники сотрудник_id PK имя отдел_id название_отдела
Название отдела повторяется у многих сотрудников и зависит от отдел_id.
Сотрудники сотрудник_id PK имя отдел_id FK Отделы отдел_id PK название
Информация об отделе хранится в одном месте; сотрудник ссылается на неё по FK.
Внешний ключ (FK) — поле, ссылающееся на уникальный идентификатор записи в другой или той же таблице. Например, Сотрудники.отдел_id хранит идентификатор реально существующего отдела. При переносе поля в отдельную таблицу важно не потерять связь.
Три вопроса для проверки
- Каждая ячейка содержит только одно значение? → 1НФ.
- Все неключевые поля относятся ко всему составному ключу, а не его части? → 2НФ.
- Нет ли описаний другого объекта, которые зависят от неключевого поля? → 3НФ.
Как сохранить ход преобразований в одном XML
Вы продолжаете файл из практической №1. Не удаляйте вкладку 01 · Черновик. Чтобы было видно ваши рассуждения, добавьте три страницы: 02 · 1НФ, 03 · 2НФ, 04 · 3НФ.
Разместите на каждой странице не только итоговые таблицы, но и поясняющие стрелки или короткие выноски: какое нарушение было и что вы сделали. Все сведения из исходных заказов должны остаться представимыми после преобразования.
Практические задания: нормализация «ТехноКорзины»
Откройте свой файл практической №1. Пользуйтесь теми же четырьмя заказами и справочными данными. Для удобства ниже приведена исходная информация по позициям — это данные, а не готовая структура правильных таблиц.
| Заказ | Дата | Клиент | Товар | Кол-во |
|---|---|---|---|---|
| 201 | 05.10.2026 | К01 · Анна Смирнова | Т01 · Мышь | 2 |
| 201 | 05.10.2026 | К01 · Анна Смирнова | Т02 · Клавиатура | 1 |
| 202 | 06.10.2026 | К02 · Борис Ли | Т03 · SSD 1 ТБ | 1 |
| 203 | 06.10.2026 | К01 · Анна Смирнова | Т03 · SSD 1 ТБ | 1 |
| 203 | 06.10.2026 | К01 · Анна Смирнова | Т01 · Мышь | 1 |
| 204 | 07.10.2026 | К03 · Дарья Петрова | Т02 · Клавиатура | 1 |
| 204 | 07.10.2026 | К03 · Дарья Петрова | Т04 · USB-хаб | 1 |
Остальные значения (телефоны, коды категорий, цены и названия категорий) берите из практической №1. Все приведённые цены — текущие цены каталога. Исторические цены отдельным полем в этом задании не моделируются.
Задание 1. Создайте страницу «02 · 1НФ»
- Перенесите структуру
Заказ_черновикна новую страницу так, чтобы не повредить первую. - Устраните поле-список товаров: разверните каждый заказ в отдельные позиции.
- Разместите на странице одну таблицу со всеми данными, нужными для описания каждой позиции: идентификаторы, дату, покупателя и его телефон, товар и его свойства, количество.
- Заполните на этой схеме все 7 позиций из приведённых данных.
- Выберите составной PK, аргументируйте выбор в выноске «Ключ 1НФ».
Задание 2. Создайте страницу «03 · 2НФ»
- Скопируйте страницу
02 · 1НФв новую вкладку и назовите её03 · 2НФ. - Найдите поля, которые зависят только от номера заказа, и поля, которые зависят только от кода товара.
- Разделите большую таблицу на несколько таблиц, чтобы убрать частичные зависимости от составного PK.
- Для каждой полученной таблицы укажите название, поля, PK, а ссылки на другие таблицы пометьте как FK.
- Нарисуйте минимум две стрелки с пояснением, почему поле перенесено в другую таблицу.
Задание 3. Создайте страницу «04 · 3НФ»
- Создайте следующую вкладку и скопируйте модель 2НФ.
- Проверьте оставшиеся транзитивные зависимости: относятся ли имя/телефон к заказу или к покупателю? Относится ли название категории к товару или к самой категории?
- Вынесите независимые описания в соответствующие таблицы. После доработки в проекте должны быть отдельно представлены клиенты, заказы, товары, категории и позиции заказа.
- Обозначьте PK и FK во всех таблицах. Для позиции заказа сохраните осмысленный ключ, исключающий дубли одной и той же пары «заказ–товар».
- Добавьте справа блок «Почему это 3НФ» с тремя короткими аргументами.
Задание 4. Протестируйте модель мысленно
- Покажите на странице 3НФ, куда будет добавлен новый клиент К04, даже если у него пока нет заказа.
- Покажите, как изменить телефон клиента К01, не переписывая его заказы.
- Покажите, какие записи понадобятся для добавления нового товара Т05 в существующую категорию.
- Ответы оформите тремя текстовыми выносками на схеме, не отдельным документом.
- Сохраните рабочий
.drawioи экспортируйте XML, включающий все страницы.
📤 Сохранение и сдача
Ответом является один редактируемый XML-файл из diagrams.net. Скриншоты, PNG, PDF, Word и ссылки не заменяют XML. Страница материала не загружает работу автоматически — отправить файл нужно самостоятельно через сервис.
- Сохраните рабочий проект через File → Save или File → Save As в формате
.drawio. Этот файл оставьте себе для продолжения. - Выберите File → Export as → XML. Включите All Pages, чтобы в файл вошли все страницы проекта. Не включайте Selection Only. Параметр Compressed можно отключить для удобства проверки XML.
- Скачайте XML и назовите файл
tehnokorzina_Фамилия_ПР02.xml(вместо слова «Фамилия» укажите свою фамилию латиницей или кириллицей). - Для проверки откройте экспортированный XML через File → Open From → Device в diagrams.net и убедитесь, что он редактируется и содержит нужные страницы.
- Перейдите на homework.probochka-corp.ru, откройте соответствующую практическую работу №2, прикрепите полученный
.xmlи завершите отправку в интерфейсе сервиса.
После сдачи не удаляйте рабочий .drawio: в следующей практической потребуется продолжить тот же проект.