Przykłady / System szkolny
System szkolny
Baza danych szkoły łączy uczniów i przedmioty przez zapisy. To tabela pośrednia, która przechowuje też ocenę. Nauczyciele prowadzą grupy z danego przedmiotu w konkretnym semestrze. Obecność jest przypięta do zapisu, po jednym wierszu na ucznia i dzień zajęć.
Poniżej ErdDocs rysuje ten schemat z jego SQL, ze wszystkimi tabelami i relacjami. W karcie „Słownik danych” znajdziesz wersję do druku, w całości i za darmo na tej stronie. SQL jest jeszcze niżej.
Najedź na tabelę, żeby podświetlić jej relacje, i kliknij, żeby je przypiąć.
Do czego służy każda tabela
- students / teachersOsobne tabele. Uczniów i nauczycieli łączy tylko imię, a dane i cykl życia mają różne.
- coursesPrzedmiot w programie nauczania. CS-101 jest zapisany raz, ile razy by go nie prowadzono.
- sectionsGrupa zajęciowa: przedmiot, semestr i nauczyciel. Uczeń zapisuje się właśnie do grupy.
- enrollmentsTabela pośrednia między uczniem a grupą. Oprócz odwołań przechowuje ocenę.
- attendanceObecność jest przypięta do zapisu złożonym kluczem obcym. Nie można odnotować ucznia na zajęciach grupy, do której nie należy.
Decyzje projektowe warte przejęcia
- Rozdzielenie przedmiotu i grupy to podstawa schematu. Jeśli zapisywać uczniów prosto na przedmioty, wszystko się psuje, gdy tylko przedmiot prowadzi się dwa razy. Są wtedy dwa semestry i dwóch nauczycieli, a kolumna oceny tylko jedna. Nie wiadomo już, czego ocena dotyczy.
- Obecność odwołuje się do zapisu złożonym kluczem obcym (student_id, section_id). Dlatego sama baza odrzuci obecność ucznia, który nie jest zapisany do grupy.
- Ocena dopuszcza NULL zamiast wartości domyślnej. Brak oceny znaczy, że semestr jeszcze trwa, a nie że uczeń dostał jedynkę.
SQL
Dialekt PostgreSQL. Ten SQL jest już wklejony w narzędzie powyżej. Możesz go swobodnie skopiować do swojej bazy albo do migracji.
CREATE TABLE students (
id bigserial PRIMARY KEY,
student_no varchar(20) NOT NULL UNIQUE,
full_name varchar(120) NOT NULL,
enrolled_on date NOT NULL
);
CREATE TABLE teachers (
id bigserial PRIMARY KEY,
full_name varchar(120) NOT NULL,
department varchar(80) NOT NULL
);
CREATE TABLE courses (
id bigserial PRIMARY KEY,
code varchar(12) NOT NULL UNIQUE,
title varchar(160) NOT NULL,
credits int NOT NULL
);
COMMENT ON COLUMN courses.code IS 'Kod przedmiotu, np. CS-101';
CREATE TABLE sections (
id bigserial PRIMARY KEY,
course_id bigint NOT NULL REFERENCES courses(id),
teacher_id bigint NOT NULL REFERENCES teachers(id),
term varchar(20) NOT NULL,
room varchar(20)
);
COMMENT ON TABLE sections IS 'Przedmiot prowadzony przez nauczyciela w semestrze; uczniowie zapisują się do grup, nie do przedmiotów';
CREATE TABLE enrollments (
student_id bigint NOT NULL REFERENCES students(id),
section_id bigint NOT NULL REFERENCES sections(id),
grade varchar(2),
PRIMARY KEY (student_id, section_id)
);
COMMENT ON COLUMN enrollments.grade IS 'NULL do końca semestru';
CREATE TABLE attendance (
student_id bigint NOT NULL,
section_id bigint NOT NULL,
class_date date NOT NULL,
present boolean NOT NULL,
PRIMARY KEY (student_id, section_id, class_date),
FOREIGN KEY (student_id, section_id) REFERENCES enrollments(student_id, section_id)
);Najczęstsze pytania
Gdzie umieścić rodziców?
W tabeli guardians i tabeli pośredniej student_guardians. To relacja wiele do wielu, bo rodzeństwo ma wspólnych opiekunów, a uczeń może mieć ich kilku.
Dlaczego nie trzymać teacher_id w courses?
Bo ten sam przedmiot w różnych semestrach prowadzą różni nauczyciele. Nauczyciel należy do grupy, a nie do przedmiotu w programie.