ErdDocs

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를 두지 않나요?

같은 과목을 학기마다 다른 교사가 가르치기 때문입니다. 교사가 속하는 것은 과목 목록이 아니라 개설 강좌입니다.

다른 예제