我正在对 DynamoDb 架构进行建模,该架构目前支持三个主要实体:教师、学生和班级。类实体具有以下关系:
我的访问模式是:
如果老师想要获取某个时段的学生列表,则需要执行两次查询(2, 3)。
如果学生想要获取老师的时段列表,他将需要执行多次查询(1 次和 4 次中的几次)。
这是我当前的 dynamodb 模型:
所有这一切都是使用单个表设计并使用相应的 pk 和 sk 来实现的。 我有一些讲座Alex Debrie,但我正在争论这是否适用于非规范化数据(在班级和注册实体中,例如学生和教师姓名)。或者如果可以接受通过多个 id 来保持设计查询。
就要求而言,我假设一个班级最多有50名学生。一位老师可能有1-5节课。我相信可以公平地说,老师或学生很少会更新他们的名字。
注意:我还阅读了以下文章,其中是学生和班级实体的邻接列表:如何使用 DynamoDB (NoSQL) 为学生/班级建模
在我的设计中,任何关于如何管理与学生和老师的班级关系的建议都会受到好评。我觉得我的设计变得过于复杂。
考虑到您的要求和访问模式,让我们探索使用单表方法的更简化的 DynamoDB 架构设计。
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
查找学生的时段:
PK = STUDENT#<StudentID> AND begins_with(SK, 'ENROLLMENT#')
找老师上课:
TEACHER#<TeacherID>
Period
GSI1PK = TEACHER#<TeacherID> AND GSI1SK = <Period>
按时段获取学生:
CLASS#<ClassID>
ENROLLMENT#<StudentID>
GSI2PK = CLASS#<ClassID>
按时段获取老师:
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"
}
在 DynamoDB 中,非规范化通常有利于减少查询数量。由于教师和学生姓名很少更新,因此在注册记录中复制此信息是可以接受的,并且会提高查询效率。