数据库设计,如何设计一个 班级学生表,实现班级学生的停课、复课、结课、转班、考勤这些操作?

现在公司项目需要实现班级的学生的停课操作、复课操作、结课操作、转班操作,后面可以根据考勤时间来查询班级里面的学生来给他们考勤。这个数据表怎么设计呢?
现在的思路是3张表:
student学生版,
class班级表,
class_student班级学生表
class_studnet的字段:class_id,student_id,in_time(入班日期),out_time(转班日期),stop_date(停课日期),recover_date(复课日期),is_close(是否结课), 然后根据日期来查询给定日期当天的班级学生列表。这样有个问题:我要是修改停课日期或复课日期,就会出现混乱。
有没有好的设计方案?

阅读 4.6k
1 个回答

16:27 修改

[Student]
| student_id | name | ... |

[Class]
| class_id | ... |

[ClassAndStudent]
| cs_id | class_id | student_id | state | is_close |

[Status]
| cs_id | option | date |

[ClassAndStudent.state] 是每天系统自动根据 [Status.date] 来刷新的:

// cs_id 为空时刷新整张表,不为空时即只刷新指定学生在指定班级的状态
update_date(cs_id) {
    result = cs_id == null ? Status.selectAll().orderBy('date')
                           : Status.selectByCSID(cs_id);
    for (row : result) {
        if (row.date == current_date) {
            switch (row.option) {
                case 'in':
                    ClassAndStudent.selectBy(row.cs_id).setState('就读');
                    ClassAndStudent.selectBy(row.cs_id).setClassId(new_class_id);
                    break;
                ...
            }
        }
    }
}

然后给 [Status] 表加个触发器,或者直接每次前端提交新状态时,后端代码加入:

cs_id = Status.insert({class_id}, {student_id}, 'in', {date});
update_state(cs_id);

这样 [ClassAndStudent.state] 就是该学生在该班的实时状态了。


原答案:

因为不太清楚你所说的 "混乱" 是指什么,以下仅作讨论:

[Student]
| student_id | name | ... | is_close

[Class]
| class_id | student_id | option | date |

option通过 in/out/stop/recover 来表示操作,date保存该操作的时间。
查询时只需要判断 [Student.is_close] ,然后对特定student_id的结果集通过 [Class.date] 按降序排序,即可知道该学生是否结课,未结课的话就能获取该学生当前所读的班级以及当前状态(in/out/stop/recover)。

查询考勤则是,对于日期早于query_dateoptionstop的,is_close也为假的,即为需要考勤的学生,此时group by一下就可以按班为单位查询了。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进