Ответ
Вторая нормальная форма (2NF) — это второй шаг в процессе нормализации реляционных баз данных, следующий после 1NF. Её цель — устранение частичных функциональных зависимостей неключевых атрибутов от составного первичного ключа.
Формальное определение: Таблица находится во 2NF, если:
- Она находится в 1NF.
- Любой её неключевой атрибут функционально полно зависит от каждого кандидатного ключа таблицы. Проще: не должно быть ситуации, когда поле зависит только от части составного ключа.
Ключевые концепции:
- Ключевой атрибут: Атрибут, входящий в состав любого кандидатного ключа.
- Неключевой атрибут: Атрибут, не входящий ни в один кандидатный ключ.
- Полная функциональная зависимость: Атрибут
Bполностью зависит от ключаA, если он функционально зависит отAи не зависит ни от какого собственного подмножестваA.
Практический пример и решение:
-
Проблемная таблица (нарушает 2NF):
Enrollment(StudentID, CourseID, CourseName, Grade)- Предположим, PK =
(StudentID, CourseID). Gradeзависит от всей пары (какую оценку получил конкретный студент по конкретному курсу). ✅CourseNameзависит только отCourseID. Это частичная зависимость. ❌
- Предположим, PK =
-
Нормализация до 2NF: Разделяем на две таблицы.
-- Таблица для связи Студент-Курс (оценка зависит от всей пары ключей) CREATE TABLE Grades ( student_id INT, course_id INT, grade INT, PRIMARY KEY (student_id, course_id) ); -- Таблица для данных курса (название зависит только от своего PK) CREATE TABLE Courses ( course_id INT PRIMARY KEY, course_name VARCHAR(100) );Результат: Устранена избыточность (название курса не дублируется для каждого студента) и связанные с ней аномалии обновления и удаления.
Ответ 18+ 🔞
А, ну вот, опять эти ваши нормальные формы, блядь. Вторая, говоришь? Ну, слушай сюда, сейчас я тебе так объясню, что ты, сука, сам начнёшь таблицы в уме нормализовать, как охуевший.
Представь себе, есть у тебя табличка, типа, «Зачётки». Записал туда всё подряд: StudentID, CourseID, CourseName, Grade. И ключ у тебя составной — пара (StudentID, CourseID). Вроде всё логично, да? Какой студент, какой курс, какая оценка и, нахуй, название курса зачем-то приплели.
И вот тут-то, ёпта, и начинается пиздец. Смотри: оценка Grade — она честная, блядь. Она зависит от ВСЕЙ этой парочки. Чтобы узнать, как Васёк сдал «Квантовую механику», надо и Васёка знать, и курс. Полная зависимость, красота.
А CourseName? А название курса — оно, сука, хитрая жопа! Ему похуй на Васёка! Название «Квантовой механики» не изменится, если Васёк её завалит или я, блядь, её завалю. Оно зависит ТОЛЬКО от CourseID. Только от части ключа! Это и есть та самая частичная зависимость, от которой 2NF хочет нас избавить, как от дурного сна.
И что получается? Получается овердохуища дублирования, блядь. Если курс «Введение в Python» у 300 студентов, то его название будет записано 300 раз, ядрёна вошь! Захотел переименовать курс в «Введение в Python, но ты всё равно нихуя не поймёшь» — иди и 300 записей обновляй, в рот меня чих-пых! Удалишь последнего студента с курса — и название курса, блядь, нахуй пропадёт из базы вместе с ним! Это же аномалии удаления и обновления, ёперный театр!
Так как же быть? А вот как, бздуны! Берёшь и разрываешь эту нездоровую связь. Делишь одну больную таблицу на две здоровые, нормальные.
-- Вот это — чистая правда. Оценка привязана к студенту И курсу. Всё честно.
CREATE TABLE Grades (
student_id INT,
course_id INT,
grade INT,
PRIMARY KEY (student_id, course_id)
);
-- А это — справочник курсов. Название живёт тут, зависит только от своего айдишника. Идилия, блядь.
CREATE TABLE Courses (
course_id INT PRIMARY KEY,
course_name VARCHAR(100)
);
Вот и вся магия, ёклмн. Разнёс данные по разным углам. Теперь название курса хранится в одном-единственном месте. Хочешь поменять — поменял в одном месте, и везде подтянулось. Удалил всех студентов — курс в справочнике себе спокойно живёт. Избыточность — на ноль, аномалии — в пизду.
Вот так и работает Вторая Нормальная Форма. Не даёт тебе привязывать данные, которым похуй друг на друга. Заставляет думать головой, а не просто пихать всё в одну кучу. Мудро, блядь.