er

School System ER Diagram

Map students, courses, teachers, enrollments, and grades in one schema that shows how a join table carries the real relationships.

School System ER Diagram — Mermaid er template preview
Static preview — open the editor for a live, editable version.

Open in editor

The code

erDiagram
  STUDENT ||--|{ ENROLLMENT : makes
  COURSE ||--|{ ENROLLMENT : receives
  TEACHER ||--o{ COURSE : teaches
  ENROLLMENT ||--o{ GRADE : earns
  STUDENT {
    string name
    date date_of_birth
  }
  COURSE {
    string code
    string title
    int credits
  }
  ENROLLMENT {
    date enrolled_on
    string term
  }
  TEACHER {
    string name
    string department
  }

How this template works

Schools are a perfect teaching ground for entity-relationship design because the interesting relationships are all many-to-many in disguise. Students take courses, courses are taught by teachers, and the grade lives on the enrollment rather than on the student or the course. This diagram captures that structure in four entities and four relationships.

Start with the join table. STUDENT ||--|{ ENROLLMENT : makes and COURSE ||--|{ ENROLLMENT : receives together express that a student takes many courses and a course holds many students, with ENROLLMENT as the meeting point. Because the enrollment is a real entity, it gets its own attribute block, holding date enrolled_on and string term, and it anchors the assessment data: ENROLLMENT ||--o{ GRADE : earns lets a single enrollment accumulate several graded pieces of work. TEACHER ||--o{ COURSE : teaches rounds out the picture with a plain one-to-many. Every attribute block follows the same two-column format, a type word and a name, such as int credits under COURSE.

The gotcha is putting data in the wrong entity. A grade belongs to the enrollment, not to the student, because the same student can take the same course in a different term and earn a different mark. If you find yourself wanting to draw a relationship straight from STUDENT to GRADE, you are usually one join table away from the cleaner model. Also keep entity names singular; STUDENTS and STUDENT will render as two unrelated boxes.

To grow the template, add a SEMESTER entity and link it to ENROLLMENT, extend GRADE with score and graded_at fields, or add a ROOM entity for scheduling. The pattern stays the same as the diagram grows: one line per relationship, one block per entity.

Related templates for comparison: the blog CMS ER diagram uses the same join-table trick for categories, the e-commerce ER diagram shows the pattern in a shop, and the employee management ER diagram applies it to staffing. The ER diagram guide has the complete symbol reference.

Variations to try

Related templates