ERD 예제 / 학교 관리 시스템
학교 관리 시스템
학교 데이터베이스는 수강(enrollments)을 통해 학생과 과목을 잇습니다. 수강은 성적도 담는 중간 테이블입니다. 교사는 학기마다 과목의 개설 강좌를 맡습니다. 출결은 수강에 매달리며, 학생과 수업일마다 한 행입니다.
아래에서 ErdDocs가 이 스키마의 모든 테이블과 관계를 SQL로 그립니다. 「데이터 사전」 탭에는 인쇄용 문서가 있고, 이 페이지에서 전체를 무료로 볼 수 있습니다. SQL은 페이지 아래쪽에 있습니다.
내 스키마
테이블에 마우스를 올리면 관계가 강조되고, 클릭하면 고정됩니다.
각 테이블의 역할
- students / teachers별도 테이블. 이름이 같을 뿐 수명 주기도 데이터도 다릅니다.
- courses과목 목록. CS-101은 몇 번 열려도 하나입니다.
- sections개설 강좌입니다. 과목, 학기, 교사의 조합으로, 학생이 실제로 참여하는 단위입니다.
- enrollments학생과 개설 강좌의 중간 테이블로, 담고 있는 값은 성적입니다.
- attendance복합 외래 키로 수강에 매달립니다. 수강하지 않은 강좌에 출석할 수는 없습니다.
가져갈 만한 설계 결정
- 과목과 개설 강좌의 분리가 이 스키마의 토대입니다. 학생을 「과목」에 수강시키면, 같은 과목이 두 번 열리는 순간 깨집니다. 학기가 둘, 교사가 둘이 되고, 성적 컬럼 하나의 뜻이 서로 부딪힙니다.
- 출결은 복합 외래 키 (student_id, section_id)로 수강을 참조합니다. 수강하지 않은 학생의 출결은 데이터베이스 자체가 거부합니다.
- 성적은 기본값 없이 NULL을 허용합니다. 성적이 없다는 것 자체가 정보(학기 중)이지 0점이 아닙니다.
SQL
PostgreSQL 방언입니다. 위의 툴(이미 들어 있습니다), 내 데이터베이스, 마이그레이션에 자유롭게 복사해서 쓰세요.
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입니다. 형제자매는 보호자를 공유하고 학생에게는 보호자가 여럿일 수 있으므로 다대다입니다.
왜 courses에 teacher_id를 두지 않나요?
같은 과목을 학기마다 다른 교사가 가르치기 때문입니다. 교사가 속하는 것은 과목 목록이 아니라 개설 강좌입니다.