ER 圖範例 / 學校管理系統
學校管理系統
學校的資料庫透過選課(enrollments)把學生和科目連起來。選課是同時存放成績的中介資料表。教師在每個學期負責某科目的開課班級。出缺勤則掛在選課上,每位學生每個上課日一列。
下方由 ErdDocs 依 SQL 畫出這份結構,包含所有資料表與關聯。「資料字典」分頁有可列印的版本,在本頁免費完整顯示。SQL 在頁面更下方。
你的結構
把滑鼠移到資料表上會標示它的關聯,點一下即可固定。
每個資料表的用途
- students / teachers分開的資料表。只是名字相同,生命週期與資料都不一樣。
- courses課程目錄上的科目。CS-101 不管開了幾次都只有一筆。
- sections開課班級,也就是科目、學期、教師的組合,是學生實際參加的單位。
- enrollments學生與開課班級的中介資料表,帶的值是成績。
- attendance用複合外鍵掛在選課上,所以不可能在沒選的班級被記為出席。
值得借鏡的設計決策
- 把科目和開課班級分開,是這份結構的基礎。如果讓學生直接選「科目」,同一科目開第二次就會出問題。會出現兩個學期、兩位教師,成績欄位的意義也會互相衝突。
- 出缺勤以複合外鍵 (student_id, section_id) 參照選課。這樣資料庫本身就會拒絕沒有選課的學生的出缺勤紀錄。
- 成績不設預設值,而是允許 NULL。沒有成績本身就是資訊(學期進行中),不是零分。
SQL
PostgreSQL 方言。可以貼進上方工具(已經放好了)、你自己的資料庫或 migration,也可以自由複製。
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 '科目代碼,例如 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 '開課班級:某位教師在某學期開設的科目。學生選的是開課班級,不是科目';
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';
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)
);常見問題
家長要放在哪裡?
放在 guardians 資料表與中介資料表 student_guardians。這是多對多,因為兄弟姊妹共用家長,一位學生也可能有多位監護人。
為什麼不把 teacher_id 放在 courses?
因為同一科目在不同學期由不同的教師授課。教師屬於開課班級,而不是課程目錄上的科目。