I'm modeling a DynamoDb schema, which currently supports three main entities: Teacher, Student and Class. Class entity has these relationships:
My access patterns are:
If the teacher wants to get the student list of a period, he will need to perform two queries (2, 3).
If a student wants to get the list of periods with their teacher, he will need to perform multiple queries (1, and several of 4).
Here my current dynamodb model:
All of this happens using a single table design and using their corresponding pk and sk. I have some of the lectures Alex Debrie, but I am debating if this is applicable to denormalize the data (in class and enrollment entities like student and teacher names). Or if it's acceptable to keep the design querying by multiple ids.
In terms of requirements, I supposing a class to contain a max of 50 students. A teacher may have 1-5 classes. I believe is fair to say a teacher or student rarely would update their names.
Note: I also read the following post, which an adjescency list for student and classes entities: How to model Student/Classes with DynamoDB (NoSQL)
Any advice on how to manage this class relationship with student and teacher in my design is well received. I feel this is getting over complicated in my design.
Given your requirements and access patterns, let's explore a more streamlined DynamoDB schema design using a single-table approach.
TEACHER#<TeacherID>
#METADATA
TeacherName
, OtherTeacherAttributes
STUDENT#<StudentID>
#METADATA
StudentName
, OtherStudentAttributes
CLASS#<ClassID>
#METADATA
ClassName
, TeacherID
, Period
STUDENT#<StudentID>
ENROLLMENT#<ClassID>
ClassID
, TeacherID
, Period
, ClassName
, TeacherName
Find periods for a student:
PK = STUDENT#<StudentID> AND begins_with(SK, 'ENROLLMENT#')
Find periods for a teacher:
TEACHER#<TeacherID>
Period
GSI1PK = TEACHER#<TeacherID> AND GSI1SK = <Period>
Get students by period:
CLASS#<ClassID>
ENROLLMENT#<StudentID>
GSI2PK = CLASS#<ClassID>
Get teacher by period:
PK = CLASS#<ClassID> AND SK = #METADATA
{
"PK": "TEACHER#T123",
"SK": "#METADATA",
"TeacherName": "Mr. Smith",
"OtherTeacherAttributes": {...}
}
{
"PK": "STUDENT#S456",
"SK": "#METADATA",
"StudentName": "Alice Johnson",
"OtherStudentAttributes": {...}
}
{
"PK": "CLASS#C789",
"SK": "#METADATA",
"ClassName": "Math 101",
"TeacherID": "T123",
"Period": "2024-07-21T09:00:00Z"
}
{
"PK": "STUDENT#S456",
"SK": "ENROLLMENT#C789",
"ClassID": "C789",
"TeacherID": "T123",
"Period": "2024-07-21T09:00:00Z",
"ClassName": "Math 101",
"TeacherName": "Mr. Smith"
}
In DynamoDB, denormalization is often beneficial for reducing the number of queries. Since updates to teacher and student names are rare, duplicating this information in enrollment records is acceptable and will improve query efficiency.