ОП.08 · Основы проектирования баз данных · Практическая №2

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

Разберите правила 1НФ, 2НФ и 3НФ и исправьте исходную структуру, сохранив все этапы преобразования.

Редактор: diagrams.net / draw.ioОдна сквозная модельОтвет: редактируемый XML

Один проект — три этапа

Все практические выполняются последовательно в одном файле diagrams.net. На каждой практической добавляются новые страницы, а прежние остаются для проверки хода проектирования. Все задания выполняются на схеме; отдельные текстовые ответы и автоматическое тестирование здесь не нужны.

Практическая №1Черновая модель
Практическая №2Нормализация
Практическая №3ER-диаграмма

Две части занятия: сначала изучите объяснения и примеры, затем перейдите к самостоятельным заданиям по магазину «ТехноКорзина».

1

Что такое нормализация и почему она нужна?

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

ОбновлениеДобавлениеУдалениеИмя клиента хранитсяв нескольких строках.Исправили не все →противоречие.Нельзя добавить товар,пока нет заказа,если все данныев одной таблице.Удалили последний закази вместе с ним потерялиинформациюо покупателе.
Аномалии — не просто «лишние байты», а риск потерять или исказить информацию.

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

Исходнаямодель1НФодин факт в ячейке2НФполная зависимость3НФбез транзитивныхсписки внутри ячеекатомарные значениянет зависимости отчасти составного PKнет зависимости междунеключевыми полями
Нормальные формы осваиваются по порядку. Каждая следующая сохраняет требования предыдущих.
Нормализация не означает «разбить всё на максимально мелкие таблицы». Необходимы понятные зависимости и сохранение смысла данных. Для работы достаточно разобрать 1НФ, 2НФ и 3НФ.
2

Первая нормальная форма — 1НФ

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

До 1НФ — неудобно
СтудентКружки
ИринаШахматы, Роботы

В одной ячейке два отдельных значения.

После 1НФ — атомарно
СтудентКружок
ИринаШахматы
ИринаРоботы

В каждой ячейке один кружок; для реальной БД нужны стабильные идентификаторы.

Для таблицы покупок после разбиения списка товаров в записи одна строка может описывать одну позицию одного заказа. При условии «один товар не встречается дважды в одном заказе» строку однозначно определит пара (номер_заказа, код_товара) — это составной ключ.

Не путайте количество с повторением записей: если купили три мыши, это одна позиция с полем количество = 3, а не три строки, если в условиях задачи учёт ведётся по позициям.
3

Вторая нормальная форма — 2НФ

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

Функциональная зависимость A → B означает: одно и то же значение A определяет одно конкретное значение B. Например, если ID урока неизменно соответствует названию урока, то ID_урока → название_урока.

Составной PK(ID_урока, ID_темы)пара значений = записьНазвание уроказависит только от ID_урокаСтатус изучения темызависит от всей парычастичная ✕полная ✓
Учебный пример: поле с названием урока не зависит от всей пары «урок + тема», поэтому ему не место в таблице со составным PK.

Когда в одной таблице с PK (урок_id, тема_id) хранится название_урока, описание урока будет повторяться для каждой темы. Решение — хранить сведения об уроке отдельно, а в таблице пар оставить его ID.

Если PK простой, частичной зависимости от части этого ключа быть не может. Но это не гарантирует 3НФ: остаются транзитивные зависимости.
4

Третья нормальная форма — 3НФ

После достижения 2НФ проверяем транзитивные зависимости неключевых полей. Для данного курса используем практическое правило: не храните в таблице факты, которые описывают другой самостоятельный объект и зависят от неключевого атрибута.

ID сотрудникаPKКод отделане ключ сотрудникаНазвание отделазависит от кода отдела
ID сотрудника определяет его отдел, а код отдела — название отдела. Название отдела следует хранить в отдельной таблице «Отделы».
Плохо
Сотрудники
  сотрудник_id  PK
  имя
  отдел_id
  название_отдела

Название отдела повторяется у многих сотрудников и зависит от отдел_id.

Лучше
Сотрудники
  сотрудник_id  PK
  имя
  отдел_id     FK

Отделы
  отдел_id     PK
  название

Информация об отделе хранится в одном месте; сотрудник ссылается на неё по FK.

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

Три вопроса для проверки

  1. Каждая ячейка содержит только одно значение? → 1НФ.
  2. Все неключевые поля относятся ко всему составному ключу, а не его части? → 2НФ.
  3. Нет ли описаний другого объекта, которые зависят от неключевого поля? → 3НФ.
5

Как сохранить ход преобразований в одном XML

Вы продолжаете файл из практической №1. Не удаляйте вкладку 01 · Черновик. Чтобы было видно ваши рассуждения, добавьте три страницы: 02 · 1НФ, 03 · 2НФ, 04 · 3НФ.

Файл Правка Вид Упорядочить …Библиотека фигурТаблица Объект учебной схемыPK — поле идентификатораатрибут_1атрибут_201 · Черновик+Рабочий холст
На схематичном изображении видно, где размещаются вкладки. Для новой страницы используйте «+» внизу холста.

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

6

Практические задания: нормализация «ТехноКорзины»

Откройте свой файл практической №1. Пользуйтесь теми же четырьмя заказами и справочными данными. Для удобства ниже приведена исходная информация по позициям — это данные, а не готовая структура правильных таблиц.

ЗаказДатаКлиентТоварКол-во
20105.10.2026К01 · Анна СмирноваТ01 · Мышь2
20105.10.2026К01 · Анна СмирноваТ02 · Клавиатура1
20206.10.2026К02 · Борис ЛиТ03 · SSD 1 ТБ1
20306.10.2026К01 · Анна СмирноваТ03 · SSD 1 ТБ1
20306.10.2026К01 · Анна СмирноваТ01 · Мышь1
20407.10.2026К03 · Дарья ПетроваТ02 · Клавиатура1
20407.10.2026К03 · Дарья ПетроваТ04 · USB-хаб1

Остальные значения (телефоны, коды категорий, цены и названия категорий) берите из практической №1. Все приведённые цены — текущие цены каталога. Исторические цены отдельным полем в этом задании не моделируются.

Задание 1. Создайте страницу «02 · 1НФ»

  1. Перенесите структуру Заказ_черновик на новую страницу так, чтобы не повредить первую.
  2. Устраните поле-список товаров: разверните каждый заказ в отдельные позиции.
  3. Разместите на странице одну таблицу со всеми данными, нужными для описания каждой позиции: идентификаторы, дату, покупателя и его телефон, товар и его свойства, количество.
  4. Заполните на этой схеме все 7 позиций из приведённых данных.
  5. Выберите составной PK, аргументируйте выбор в выноске «Ключ 1НФ».
Самопроверка: никаких списков в ячейках; 7 строк позиций; ни одна пара значений составного PK не повторяется.

Задание 2. Создайте страницу «03 · 2НФ»

  1. Скопируйте страницу 02 · 1НФ в новую вкладку и назовите её 03 · 2НФ.
  2. Найдите поля, которые зависят только от номера заказа, и поля, которые зависят только от кода товара.
  3. Разделите большую таблицу на несколько таблиц, чтобы убрать частичные зависимости от составного PK.
  4. Для каждой полученной таблицы укажите название, поля, PK, а ссылки на другие таблицы пометьте как FK.
  5. Нарисуйте минимум две стрелки с пояснением, почему поле перенесено в другую таблицу.
Самопроверка: заказ не дублирует дату и данные покупателя в каждой позиции; свойства товара не записываются заново в каждой позиции; количество осталось привязано к конкретной позиции.

Задание 3. Создайте страницу «04 · 3НФ»

  1. Создайте следующую вкладку и скопируйте модель 2НФ.
  2. Проверьте оставшиеся транзитивные зависимости: относятся ли имя/телефон к заказу или к покупателю? Относится ли название категории к товару или к самой категории?
  3. Вынесите независимые описания в соответствующие таблицы. После доработки в проекте должны быть отдельно представлены клиенты, заказы, товары, категории и позиции заказа.
  4. Обозначьте PK и FK во всех таблицах. Для позиции заказа сохраните осмысленный ключ, исключающий дубли одной и той же пары «заказ–товар».
  5. Добавьте справа блок «Почему это 3НФ» с тремя короткими аргументами.
Самопроверка: у одной и той же категории название хранится один раз; телефон клиента хранится в одном логическом месте; ни одна позиция заказа не потеряна.

Задание 4. Протестируйте модель мысленно

  1. Покажите на странице 3НФ, куда будет добавлен новый клиент К04, даже если у него пока нет заказа.
  2. Покажите, как изменить телефон клиента К01, не переписывая его заказы.
  3. Покажите, какие записи понадобятся для добавления нового товара Т05 в существующую категорию.
  4. Ответы оформите тремя текстовыми выносками на схеме, не отдельным документом.
  5. Сохраните рабочий .drawio и экспортируйте XML, включающий все страницы.

📤 Сохранение и сдача

Ответом является один редактируемый XML-файл из diagrams.net. Скриншоты, PNG, PDF, Word и ссылки не заменяют XML. Страница материала не загружает работу автоматически — отправить файл нужно самостоятельно через сервис.

  1. Сохраните рабочий проект через File → Save или File → Save As в формате .drawio. Этот файл оставьте себе для продолжения.
  2. Выберите File → Export as → XML. Включите All Pages, чтобы в файл вошли все страницы проекта. Не включайте Selection Only. Параметр Compressed можно отключить для удобства проверки XML.
  3. Скачайте XML и назовите файл tehnokorzina_Фамилия_ПР02.xml (вместо слова «Фамилия» укажите свою фамилию латиницей или кириллицей).
  4. Для проверки откройте экспортированный XML через File → Open From → Device в diagrams.net и убедитесь, что он редактируется и содержит нужные страницы.
  5. Перейдите на homework.probochka-corp.ru, откройте соответствующую практическую работу №2, прикрепите полученный .xml и завершите отправку в интерфейсе сервиса.

После сдачи не удаляйте рабочий .drawio: в следующей практической потребуется продолжить тот же проект.

Чек-лист перед отправкой