education
University Portal
Who is enrolled on this course?
Enrol students on courses, assign professors and record grades.
Students, professors, departments, courses, assignments and grades share one table. Enrolment and teaching items link people to courses, and an index on each reads the link from the other end, so the same items list a student's courses and a course's students.
The model
Student
A registered student with academic records
- pk
- STUDENT#<studentId>
- sk
- STUDENT#<studentId>
Attributes: PK (S), SK (S), studentId (S), firstName (S), lastName (S), email (S), departmentCode (S), enrollmentYear (N), status (S), gpa (N), creditsCompleted (N)
Course
A course offering for a specific semester
- pk
- COURSE#<courseCode>
- sk
- SEMESTER#<semesterId>
Attributes: PK (S), SK (S), GSI3PK (S), GSI3SK (S), courseCode (S), semesterId (S), title (S), departmentCode (S), credits (N), capacity (N), enrolledCount (N), schedule (M), description (S)
Professor
A faculty member who teaches courses
- pk
- PROFESSOR#<professorId>
- sk
- PROFESSOR#<professorId>
Attributes: PK (S), SK (S), professorId (S), firstName (S), lastName (S), email (S), departmentCode (S), title (S), officeLocation (S), officeHours (M)
Department
An academic department offering courses
- pk
- DEPT#<deptCode>
- sk
- DEPT#<deptCode>
Attributes: PK (S), SK (S), deptCode (S), name (S), building (S), chairProfessorId (S)
Enrolment
Links a student to a course (adjacency list edge)
- pk
- STUDENT#<studentId>
- sk
- ENROLL#<courseCode>#<semesterId>
Attributes: PK (S), SK (S), GSI1PK (S), GSI1SK (S), studentId (S), courseCode (S), semesterId (S), status (S), enrolledAt (S)
Assignment
A graded assignment for a course
- pk
- COURSE#<courseCode>#<semesterId>
- sk
- ASSIGN#<assignmentId>
Attributes: PK (S), SK (S), assignmentId (S), courseCode (S), semesterId (S), title (S), description (S), maxPoints (N), weight (N), dueDate (S), type (S)
Grade
A student's grade for a course
- pk
- STUDENT#<studentId>
- sk
- GRADE#<courseCode>#<semesterId>
Attributes: PK (S), SK (S), GSI4PK (S), GSI4SK (S), studentId (S), courseCode (S), semesterId (S), letterGrade (S), gradePoints (N), credits (N), finalizedAt (S)
Teaching
Links a professor to a course (adjacency list edge)
- pk
- COURSE#<courseCode>#<semesterId>
- sk
- PROF#<professorId>
Attributes: PK (S), SK (S), GSI2PK (S), GSI2SK (S), professorId (S), courseCode (S), semesterId (S), role (S)
Access patterns
- QueryGet student's current enrolments
List all courses a student is currently enrolled in
- Query · GSI1Get all students in a course
List all students enrolled in a specific course section
- Query · GSI2Get professor's teaching schedule
List all courses a professor is teaching
- Query · GSI4Calculate student GPA
Aggregate grades across all courses for GPA calculation
- Query · GSI3Get department course catalogue
List all courses offered by a department
- TransactWriteItemsSubmit grade for student
Create or update a grade record for a student in a course
- QueryGet course assignments
List all assignments for a course section
- GetItemGet student details
Fetch one student's record, with the GPA held on it.
- QueryGet professor details
Fetch one professor's profile and office hours.
- QueryGet department details
Fetch one department's name, building and chair.
Design notes
Adjacency list for M:N relationshipswhy
Enrolment and Teaching entities serve as "edges" in an adjacency list graph. This enables querying from either direction: student→courses OR course→students. Alternative would be two separate tables, but single-table keeps all data together.
Grade separate from Enrolmentwhy
Grades are stored as separate items rather than attributes on Enrolment. This enables historical grade tracking, partial grades during semester, and atomic grade updates without touching enrolment status.
Denormalised GPA on Studenttrade-off
GPA is stored directly on Student for quick read access. Trade-off: must update GPA when grades change. Alternative: calculate on-read from grades, but requires aggregation query for every student fetch.
Two keys for a coursewhy
A course is keyed COURSE#<code> with the semester in its sort key, so one Query lists every time it has run. The items that belong to one offering - its assignments, its teaching and, through GSI1, its enrolments - partition on COURSE#<code>#<semester> instead, so one offering reads without the others.
Atomic counter for enrolment countgotcha
enrolledCount uses atomic ADD operation to prevent race conditions. When a student enrols, the count is incremented atomically. Watch for the gotcha: if enrolment fails after counter increment, count can drift.
Submitting a grade is a transaction the page cannot runtrade-off
Submit grade for student is a TransactWriteItems: it puts the grade and moves the enrolment from enrolled to completed, so a grade never exists for a course the student was not enrolled on. The engine in this page does not support TransactWriteItems, so it is not offered as a run.
Taught in the course
- The key is the address - GetItem needs the whole primary key: partition and sort.
- Model a one-to-many with one partition - A parent and its children share a partition key, so one Query fetches them together.
List all courses a student is currently enrolled in
Choose an access pattern above, or build your own request. See what comes back and what it costs.
Write transactions, streams, tags and TTL are among the operations this browser build leaves out. dynoxide's native build has them.