数据库设计——当学生记录本身也需要相互关联时,我们应该如何设计teacher/student关系

Database design - How should we design a teacher/student relationship when student records themselves also need to be associated to each other

所以这是我们一直在努力尝试找出优化方法的东西。


在一个简单的世界中,这可以通过一个简单的多对多桥接 table 来解决,如下所示:

id teacher_id student_id
1 1 1
2 1 2
3 1 3
4 2 1

然而,我们还有另一个复杂的问题需要解决。学生记录可以来自不同的“来源”,即:

  1. 该学生是由另一个系统创建的,该系统将该学生及其 类 的记录传输给我们(大多数学生和师生关系记录都是通过这种方式创建的)。
  2. 学生自行注册(通过应用程序),或
  3. 该学生由教师手动创建(通过教师门户)

因此,在某些情况下,来自不同来源的学生记录也应该相互关联:

id name id_number source_type
1 Rachel Doe 9898123 created_by_system
2 Rachel Doe 9898123 app_user
3 John Doe 9833456 created_by_teacher

例如上面,我们有一个案例,其中 student_ids 1 和 2,Rachel Doe,实际上是同一个人。第一条记录由系统自动生成,第二条记录是 Rachel 在她的学生应用程序上在系统中注册时创建的。两条记录共享一个 id_number,这是学校的唯一标识符。


如果我们这样做 student_ids 1 和 2 都链接到 Rachel 的所有老师,她的老师会看到重复的记录,即 Rachel 的应用程序帐户和她由系统创建的记录。因此,将这两个 student_id 记录相互关联起来似乎更明智,但这将如何影响 teachers_students_mappings table?

理论上也有可能同一个学生存在3条不同的学生记录(即老师手动创建记录,然后系统创建记录,然后学生在应用程序上创建帐户)。

在输入新记录的数据之前,您必须检查 id_number 是否存在。在那种情况下,您必须 return 标识而不是插入该记录。

因为您已经拥有一个独一无二的 id_number,并提供了一种机制来实现您拥有 一个,而不是 两个 Rachel 做的,用它作为 Students table 的 PRIMARY KEY每个学生还有另一个id

另一方面,如果您有一个 StudentHistory table 来记录每个学生或为每个学生采取的各种行动,则它需要自己的 PRIMARY KEY。这似乎是一个单独的话题。

因此,在为学生“插入”或“更新”一行时,请使用

INSERT INTO Students (id_number, name, foo, ...)
    VALUES ("9898123", "Rachel Doe", 123, ...)
    ON DUPLICATE KEY UPDATE
        foo = VALUES(foo), ...;

或者(如果来自 SELECT):

INSERT INTO Students (id_number, name, foo, ...)
    SELECT id_number, name, foo, ...
        FROM other table ...
    ON DUPLICATE KEY UPDATE
        foo = VALUES(foo), ...;