StudentId, StudentName, GroupId, GroupName, CourseId, CourseName, LecturerId, LecturerName, Mark
Дано отношение с атрибутами StudentId, StudentName, GroupId, GroupName, CourseId, CourseName, LecturerId, LecturerName, Mark. И функциональными зависимостями:
Функциональные зависимости: StudentId → StudentName, GroupId, GroupName; GroupId → GroupName; GroupName → GroupId; CourseId → CourseName; LecturerId → LecturerName; StudentId, CourseId → Mark; GroupId, CourseId → LecturerId, LecturerName.
Из предыдущего ДЗ, у этого отношения единственный ключ: {StudentId, CourseId}:
Возьмем надключ из всех аттрибутов. Заметим что StudentId не встерчается в правых частях ФЗ, поэтому ключ обязательно будет содержать StudentId. Для любого множества аттрибутов без StudentId -- это множество не надключ и следовательно не ключ
Аналогичное утверждение верно для CourseId.
Следовательно не будет рассматривать множества аттрибутов не содержащих StudentId, CourseId в качестве ключей
Если множество аттрибутов {StudentId, CourseId} -- надключ, то оно так же и ключ, т.к. любой другой надключ будет содержать в себe это множество и следовательно оно минимально по включению.
Проверим что {StudentId, CourseId} -- надключ: {StudentId, CourseId}* = {StudentId, CourseId, StudentName, GroupId, GroupName, CourseName, Mark, LecturerId, LecturerName} {StudentId, CourseId} -- ключ
Критерии 1НФ:
(StudentId, StudentName, GroupId, GroupName, CourseId, CourseName, LecturerId, LecturerName, Mark) => (StudentId, StudentName, GroupId, GroupName, CourseId, CourseName, LecturerId, LecturerName, Mark).
Ключ: {StudentId, CourseId} Найдем "мешающие" ФЗ:
Разобъем по ФЗ StudentId -> StudentName, GroupId, GroupName:
Распалась ФЗ GroupId, CourseId -> LecturerId, LecturerName. Попробуем вместо этого разбить по ней, добавив в парвую часть CourseName, т.к. нужно разбить по "мешающей" ФЗ CourseId -> CourseName.
Все ФЗ сохранились, теперь разобъем второе отношение по ФЗ StudentId -> StudentName, GroupId, GroupName:
Рассмотри отношение (GroupId, CourseId, LecturerId, LecturerName, CourseName): Оно содержит ФЗ:
Ключ в нем: {GroupId, CourseId}. Мешающая ФЗ: CourseId -> CourseName. Разобъем по ней:
Получим отношения:
Ключ: CourseId Во 2НФ (ключ не составной)
Ключ: {GroupId, CourseId} Во 2НФ (нет "мешающих" правил)
Ключ: StudentId Во 2НФ (ключ не составной)
Ключ: {StudentId, CourseId} Во 2НФ (нет "мешающих" правил)
(StudentId, StudentName, GroupId, GroupName, CourseId, CourseName, LecturerId, LecturerName, Mark) => (StudentId, CourseId, Mark); (CourseId, CourseName); (GroupId, CourseId, LecturerId, LecturerName); (StudentId, StudentName, GroupId, GroupName).
Рассмотрим отношения:
Ключ: CourseId Все неключевые аттрибуты (CourseId) непосредственно зависят от ключевых (CourseId) (единственная ФЗ) В 3НФ
Ключ: (GroupId, CourseId) Все неключевые аттрибуты (LecturerId, LecturerName) непосредственно зависят от ключевых (GroupId, CourseId) (по первой ФЗ) В 3НФ
Ключ: StudentId Все неключевые аттрибуты (StudentName, GroupId, GroupName) непосредственно зависят от ключевых (StudentId) (по первой ФЗ) В 3НФ
Ключ: (StudentId, CourseId) Все неключевые аттрибуты (Mark) непосредственно зависят от ключевых (StudentId, CourseId) (единственная ФЗ) В 3НФ
(StudentId, CourseId, Mark) => (StudentId, CourseId, Mark).
(CourseId, CourseName) => (CourseId, CourseName).
(GroupId, CourseId, LecturerId, LecturerName) => (GroupId, CourseId, LecturerId, LecturerName).
(StudentId, StudentName, GroupId, GroupName) => (StudentId, StudentName, GroupId, GroupName).
Рассмотрим отношения:
Ключ: (GroupId, CourseId) Во второй ФЗ LecturerId - не надключ, декомпозируем по ней. Перед этим построит эквивалентное множество ФЗ:
После декомпозиции потеряем ФЗ GroupId, CourseId -> LecturerName, получим:
Ключ: (GroupId, CourseId) Имеем единственную ФЗ, такую что в левой части ключ => нет ФЗ таких что в левой части не надключ В НФБК
Ключ: StudentId Во второй и третьей ФЗ GroupId и GroupName соответственно - не надключи, декомпозируем по второй. Перед этим построит эквивалентное множество ФЗ:
После декомпозиции потеряем ФЗ StudentId -> GroupName, получим:
Ключ: (StudentId) Имеем единственную ФЗ, такую что в левой части ключ => нет ФЗ таких что в левой части не надключ В НФБК
Ключ: (StudentId, CourseId) Имеем единственную ФЗ, такую что в левой части ключ => нет ФЗ таких что в левой части не надключ В НФБК
Потеряли две ФЗ:
(StudentId, CourseId, Mark) => (StudentId, CourseId, Mark).
(CourseId, CourseName) => (CourseId, CourseName).
(GroupId, CourseId, LecturerId, LecturerName) => (GroupId, CourseId, LecturerId); (LecturerId, LecturerName).
(StudentId, StudentName, GroupId, GroupName) => (StudentId, StudentName, GroupId); (GroupId, GroupName).
Лемма 1: Отношенине R с аттрибутами (A, B, C) и множеством ФЗ:
находится в 4НФ
Рассмотрим потенциальные нетривиальные МЗ:
Следовательно A -> C | B тоже не МЗ
A | B | C |
A1 | B | C1 |
A2 | B | C2 |
x = B, y1 = A1, y2 = GI2, z1 = C1, z2 = C2 {y | (x, y, z1) in R} = { A1 } != { GI2 } = {y | (x, y, z2) in R } Не МЗ
Следовательно B -> C | A тоже не МЗ
A | B | C |
A1 | B1 | C |
A2 | B2 | C |
x = C, y1 = A1, y2 = GI2, z1 = B1, z2 = B2 {y | (x, y, z1) in R} = { A1 } != { GI2 } = {y | (x, y, z2) in R } Не МЗ
Следовательно C -> B | A тоже не МЗ
A | B | C |
A1 | B1 | C |
A2 | B2 | C |
x = {}, y1 = (A1, C), y2 = (GI2, C), z1 = B1, z2 = B2 {y | (y, z1) in R} = { (A1, C) } != { (GI2, C) } = {y | (y, z2) in R } Не МЗ
Следовательно {} -> B | A, C тоже не МЗ
A | B | C |
A1 | B1 | C |
A2 | B2 | C |
x = {}, y1 = (B1, C), y2 = (B2, C), z1 = A1, z2 = GI2 {y | (y, z1) in R} = { (B1, C) } != { (B2, C) } = {y | (y, z2) in R } Не МЗ
Следовательно {} -> A | B, C тоже не МЗ
A | B | C |
A1 | B1 | C1 |
A2 | B2 | C2 |
x = {}, y1 = (B1, C1), y2 = (B2, C2), z1 = A1, z2 = GI2 {y | (y, z1) in R} = { (B1, C1) } != { (B2, C2) } = {y | (y, z2) in R } Не МЗ
Следовательно {} -> C | B, A тоже не МЗ
Рассмотрим отношения:
Ключ: (CourseId) По теореме Дейта-Фейгина 1 - отношение в 5НФ В 4НФ
Ключ: (GroupId, CourseId) По Лемме 1 при A = GroupId, B = CourseId, C = LecturerId находится в 4НФ
Ключ: (LecturerId) По теореме Дейта-Фейгина 1 - отношение в 5НФ В 4НФ
Ключ: (StudentId) По теореме Дейта-Фейгина 1 - отношение в 5НФ В 4НФ
Ключи: (GroupId), (GroupName) По теореме Дейта-Фейгина 1 - отношение в 5НФ В 4НФ
Ключ: (StudentId, CourseId) По Лемме 1 при A = StudentId, B = CourseId, C = Mark находится в 4НФ
(StudentId, CourseId, Mark) => (StudentId, CourseId, Mark).
(CourseId, CourseName) => (CourseId, CourseName).
(LecturerId, LecturerName) => (LecturerId, LecturerName).
(GroupId, CourseId, LecturerId) => (GroupId, CourseId, LecturerId).
(StudentId, StudentName, GroupId) => (StudentId, StudentName, GroupId).
(GroupId, GroupName) => (GroupId, GroupName).
Лемма 2: Отношенине R с аттрибутами (A, B, C) и множеством ФЗ:
находится в 5НФ
По Лемме 1 R не содержит МЗ и по теореме Фейгина не содержит ЗС из двух отношений
Рассмотрим оставшуюся ЗС *{{A}, {B}, {C}}: Рассмотрим проекции для примера:
A | B | C |
A1 | B1 | C1 |
A2 | B2 | C2 |
A |
A1 |
A2 |
B |
B1 |
B2 |
C |
C1 |
C2 |
Получим что P1 join P2 join P3:
A | B | C |
A1 | B1 | C1 |
A1 | B2 | C1 |
A1 | B1 | C2 |
A1 | B2 | C2 |
A2 | B1 | C1 |
A2 | B2 | C1 |
A2 | B1 | C2 |
A2 | B2 | C2 |
Что не равно исходной зависимости и следовательно не является ЗС
Следовательно нет нетривиальных ЗС => В 5НФ
Рассмотрим отношения:
Ключ: (CourseId) По теореме Дейта-Фейгина 1 - отношение в 5НФ
Ключ: (GroupId, CourseId) По Лемме 2 при A = GroupId, B = CourseId, C = LecturerId в 5НФ
Ключ: (LecturerId) По теореме Дейта-Фейгина 1 - отношение в 5НФ
Ключ: (StudentId) По теореме Дейта-Фейгина 1 - отношение в 5НФ
Ключи: (GroupId), (GroupName) По теореме Дейта-Фейгина 1 - отношение в 5НФ
Ключ: (StudentId, CourseId) По Лемме 2 при A = StudentId, B = CourseId, C = Mark в 5НФ
(StudentId, CourseId, Mark) => (StudentId, CourseId, Mark).
(CourseId, CourseName) => (CourseId, CourseName).
(LecturerId, LecturerName) => (LecturerId, LecturerName).
(GroupId, CourseId, LecturerId) => (GroupId, CourseId, LecturerId).
(StudentId, StudentName, GroupId) => (StudentId, StudentName, GroupId).
(GroupId, GroupName) => (GroupId, GroupName).
CREATE DATABASE hw4;
DROP TABLE IF EXISTS Students CASCADE;
DROP TABLE IF EXISTS Groups CASCADE;
DROP TABLE IF EXISTS Lecturers CASCADE;
DROP TABLE IF EXISTS Courses CASCADE;
DROP TABLE IF EXISTS Marks CASCADE;
DROP TABLE IF EXISTS Teachers CASCADE;
CREATE TABLE Courses (
Id int GENERATED ALWAYS AS IDENTITY,
Name varchar(50) not null,
PRIMARY KEY (Id)
);
CREATE TABLE Lecturers (
Id int GENERATED ALWAYS AS IDENTITY,
Name varchar(50) not null,
PRIMARY KEY (Id)
);
CREATE TABLE Groups (
Id int GENERATED ALWAYS AS IDENTITY,
Name varchar(50) not null,
PRIMARY KEY (Id),
UNIQUE (Name)
);
CREATE TABLE Students (
Id int GENERATED ALWAYS AS IDENTITY,
Name varchar(50) not null,
GroupId int not null,
PRIMARY KEY (Id),
FOREIGN KEY (GroupId)
REFERENCES Groups(Id)
);
CREATE TABLE Teachers (
CourseId int not null,
GroupId int not null,
LecturerId int not null,
PRIMARY KEY (CourseId, GroupId),
FOREIGN KEY (CourseId)
REFERENCES Courses(Id),
FOREIGN KEY (GroupId)
REFERENCES Groups(Id),
FOREIGN KEY (LecturerId)
REFERENCES Lecturers(Id)
);
CREATE TABLE Marks (
CourseId int not null,
StudentId int not null,
Mark int not null,
PRIMARY KEY (CourseId, StudentId),
FOREIGN KEY (CourseId)
REFERENCES Courses(Id),
FOREIGN KEY (StudentId)
REFERENCES Students(Id)
);
INSERT INTO Groups (Name) VALUES
('M33371'),
('M3133'),
('M34391');
SELECT * FROM Groups;
INSERT INTO Students (Name, GroupId) VALUES
('Иванов Иван', 1),
('Петров Петр', 2),
('Казимиров Казимир', 3),
('Игнатьев Игнат', 1),
('Тимуров Тимур', 2),
('Станиславов Станислав', 3);
SELECT * FROM Students;
INSERT INTO Lecturers (Name) VALUES
('Корнеев Георгий'),
('Кохась Константин'),
('Маврин Павел');
SELECT * FROM Lecturers;
INSERT INTO Courses (Name) VALUES
('Матанализ'),
('Базы Данных'),
('АиСД');
SELECT * FROM Courses;
INSERT INTO Teachers (CourseId, GroupId, LecturerId) VALUES
(1, 2, 2),
(1, 1, 2),
(2, 1, 3),
(3, 1, 3),
(3, 2, 3);
INSERT INTO Marks (CourseId, StudentId, Mark) VALUES
(1, 1, 2),
(1, 3, 5),
(2, 6, 1),
(3, 2, 10);