课堂学习效果反馈系统数据库设计

前言

一个数据库的设计可以说关系到系统方方面面。基本当数据库被设计出来,系统的实现的工作量就完成了一大半了。

前段时间根据某个题目设计了一个系统的数据库,想想在之前的设计中,存在许多问题,所以特地吸取经验,重新设计了一下。特此记录。

条件

题目功能模块

部门的创建,查询和更新

课程的创建,查询和更新

授课知识点的创建,查询和更新

反馈指标的创建,查询和更新

反馈结果的统计和展示

授课效果的智能提醒

分析

题目和条件分析

智慧课堂学习效果反馈系统的关键词是:智慧课堂学习效果反馈

所以系统的使用场景学校或者教育机构。因此,也就能牵引出存在3个角色学生,教师和管理员。除此之外,还需要有部门,课程,授课知识点,反馈指标,反馈结果和授课效果实体。

关系分析

一个学校(系统)存在多个部门,多个管理员。一个部门有多个学生,教师和课程。

一门课程可以绑定多个老师,变成多门课程。每一门课程存在多节课时。每一节课时存在不同的授课知识点,即存在多个知识点。而每一个知识点同样存在不同反馈指标。

反馈结果和授课效果都是反馈指标的反映。

逻辑分析

针对关系分析,有以下逻辑:

  • 时间问题:正常情况下,一周有5天,一天有8个时间段可以上课。一门课可以有8周,或者17周上课时间;同一个老师不能够在同一个时间段上存在2门课;同一个学生不能够在同一个时间段上存在2门课。
  • 老师问题:一门课程可以绑定多个老师,变成多门课程;
  • 部门问题:一门课程同样需要绑定部门的,这也导致了一门课程只能绑定一个部门,且该门课程只能由这一个部门的老师授课。
  • 课程问题:一门没有绑定老师的课程的课时是固定的,8个课时,17个课时,或者其它。
  • 地点问题:一个教室不能出现同一个时间有两门课程

关于大小课的问题,大小课可以作为不同的课程处理。但一门课程要么没有大小课,要么只能有一门小课。

单双周问题,有些课程是存在单双周现象的。

  • 学生问题:一个部门存在多个学生,学生可以选择任何一门课程。
  • 其它问题:授课知识点是课时中的一部分,反馈指标是授课知识点的一部分。而反馈效果是反馈指标的反映。

数据库设计与情景试演

数据库设计

全局字典表sys_dicts
说明

负责存储稳定的全局配置,例如配置角色和部门,教师甚至是8个上课时间段

字段名描述
id主键
type类型
typerepre类型描述
name名称
repre描述
number排序
createtime创建时间
updatetime更新时间
other其它
情景试演

例如配置部门,有软件工程系和计算机系;配置角色,有管理员,教师和学生;则有以下内容:

idtypetypereprenamereprenumbercreatetimeupdatetimeother
11部门软件工程系1
21计算机系2
32角色管理员1
42教师2
52学生3
角色表sys_roles
说明

角色表存储系统的用户群体,即管理员,教师和学生;

为什么不采用分表的形式,即管理员表,教师表和学生表;

一方面是因为全局字典表sys_dicts可以控制角色的分类;另一方面,多一张表意味着多一套固定流程;

当然,也考虑到数据库效率问题,当数据量过大时,是否会影响系统查询效率;由于系统只是面向一个学校;一届的人数并不多,当毕业后,即可将毕业的学生存入到数据仓库中。活跃的用户数肯定不会存在上百万,甚至千万的记录数。所以不存在大数据量要分表的问题。

字段名描述
id主键
role角色(全局字典表的角色类型中主键之一)
number号码(学号,工号)
name用户名
passwd密码(登录名可以使用号码)
dept部门(全局字典表的角色类型中主键之一)
createtime入学时间
updatetime更新时间
other其它

当然还会有其它字段,这里就不列举了。

因为其它字段与这个系统的条件并不相关,增加可以丰富系统,但并不会有所影响系统的数据库设计;

下面的也是如此。

情景试演

增加一个管理员,老师和学生,则会有

idrolenumbernamepasswddeptcreatetimeupdatetimeother
13000000adminxxx
24123450张三xxx1
351740xxxxxx张三xxx2
课程表sys_class
说明

前2个表的设计并不牵连多个表,所以设计并不难

但是课程的逻辑太多了,几乎整个数据库的设计或多或少都会与这个相关

字段名描述
id主键
name课程名
repre课程描述
dept部门
iseveryweek单双周/每周(字典)(3个值分别表示单周,双周,每周)
weeknumber上课周期(字典)
lessonflag是否有小课(如果有,则大小可具有同一随机字符串;无为空)
islesson是否是小课
createtime创建时间
updatetime更新时间
情景试演

课程的添加一般是管理员添加的,所以当管理员添加一门课程时,会有

// 只描述关键字段
class = {
    'id':'1',
    'name':'编程规范',
    'repre':'编程规范是养成良好编码习惯的一门课程',
    'dept':'',//字典主键,1表示软件工程系
    'iseveryweek':'',//字典主键
    'weeknumber':'',//字典主键
    'lessonflag':'',
    'islesson':''
}
课程老师表sys_class_teacher
说明

一开始是将未绑定老师的课程和绑定老师的课程进行分表存储的,想想这个决定是对的。因为不这样做的话,课程表里会有大量的重复字段,例如当编程规范绑定多名老师后,课程名编程规范将会出现大量出现在name字段上。所以,独立出来比较好

字段名描述
id主键
classid课程外键(sys_class主键)
teacherid老师外键(sys_roles主键)
time上课时间(一周5天之一)
timeslot上课时间段(8个时间段之一)
studentnums学生人数
address上课地点
createtime创建时间
updatetime更新时间
other其它
情景试演

为一门课程绑定一节课

class = {
    'id':'1',
    'name':'编程规范',
    'repre':'编程规范是养成良好编码习惯的一门课程',
    'dept':'1',//字典主键,1表示软件工程系
    'iseveryweek':'',//字典主键
    'weeknumber':'',//字典主键
    'lessonflag':'',
    'islesson':''
}
class_teacher = {
    'id':1,
    'classid':'1',
    'teacherid':'1',
    'time':'',//周三
    //
    'timeslot':'',//第7个时间段
    //sys_dicts['typerepre'] = 'timesolt'
    //sys_dicts['name']=7
    //timeslot = sys_dicts['id']
    'studentnums':'40',
    'address':''// 地点字典
}

关于地点问题,可以在后台查询出当前时间闲置的教室,再随机设置

也可以将当前闲置的教师供管理员选择

获取当前时间闲置的教室伪代码步骤:

  • 根据sys_class_teacher的classid获取课程信息,主要获取iseveryweek和weeknumber字段;
  • 获取sys_class_teacher的time和timeslot,address
  • 根据上两个步骤和第一周的时间,可以组成时间表。时间表中的每一个元素里包含具体时间,已有课程列表
  • 根据前一个步骤,对数据进行清洗,最终得到闲置教室

其实地点的设置可以在所有课程都定下来后,再随机分配即可

课程学生表sys_class_student
说明

课程绑定完老师后,则需要为sys_class_teacher绑定学生了

首先,有几点需要明确:

  • 一个学生不能同时拥有两门课程一样的课程,也不能只上有大小课的课程中的一门
  • 同一个时间,学生不可以有2门或者以上课程安排;
字段名描述
id主键
classteacherid课程老师主键
studentid学生
createtime创建时间
updatetime更新时间
情景试演

当一门已绑定老师的课程绑定学生时,首先获取课程classid,再根据这个classid,获取课程信息。由字段lessflag判断是否有小课,如果有,则根据字符串查询出这门课的所有小课课程

同时将两门课程绑定给学生;

如果这门课程没有小课,则直接绑定;

时间问题:根据这个学生的id,获取他的所有课程,查看是否冲突即可。


课程课时表sys_class_time
说明

一门课程需要有多节课时

字段名描述
id主键
classteacherid已绑定老师课程id
title课时标题
repre描述
createtime创建时间
updatetime更新时间
情景试演

其实这张表的最好的处理方式时,当课程sys_class一绑定好老师,即设计完成表sys_class_teacher时,就应该根据表sys_class的上课周期weeknums,是否单双周iseveryweek,以及表sys_class_teacher的id,time,timesolt,开学时间自动生成。

然后由老师进行填写/修改标题,描述即可

课程课时知识点sys_class_time_keypoint
说明

一门课程的某节课时可以由多个知识点,且是不同;但相比其它表设计,其实不难。

字段名描述
id主键
classteacherid课程老师id
classtimeid课程课时id
name知识点名称
repre知识点描述
nums排序
difficulty难度(难度程度可以存储在字典中)
情景试演

其实字段classteacherid是可以根据classtimeid字段查询获得的;所以可有可无。但因为层次太多了,所以增加这一个字段。后面的表中的classteacherid也是如此。

这个课程课时知识点应该是老师进行操作的。

老师可以为自己负责的课程课时添加知识点。

首先在sys_class_teacher根据老师id获取该老师负责的课程,再到sys_class_time根据sys_class_teacher的id获取课时列表;

点击进入某个课时,并为该课时添加资料即可。

反馈指标表sys_feedback
说明
字段名描述
id主键
keypointid知识点id
classteacherid课程老师id
name反馈指标名称
repre反馈指标描述
createtime创建时间
updatetime更新时间
other其它
情景试演

和知识点那张表类似吧

反馈结果表sys_feedback_res
说明

反馈结果是反馈指标的一个反映,表结构简单,只是存储填写者和填写结果即可

字段名描述
id主键
feedbackid反馈指标id
classteacherid课程老师id
studentid学生id
res填写结果
createtime创建时间
updatetime更新时间
情景试演

反馈结果存在一个逻辑—当一个学生评价完成后,就不可以再进行评价了

另外,这张表的记录有2种方式产生:

  • 方式1

由学生填写时产生

  • 方式2

当老师创建反馈指标后,获取当前课程的所有学生,自动生成记录;

res,createtime,updatetime为空,等待补充;

这种方式可以很方便得提示学生还有反馈需要填写;

总结

在以上的表设计中,很明显地能看出中间的几个表的层级是一层套着一层的。特别是sys_class_xxx那一块。

无论是学生和老师,都需要实现下钻的逻辑流程,那也意味着实现上钻。如果要满足数据的四种特性的话,就要非常注意数据的操作行为。不能够出现一次不符常理的操作。

例如:删除sys_class_teacher中的一条记录,则需要删除其它表与此相关的记录。正所谓,牵一发而动全身。正是这个意思。

总结

关于数据库的设计,可以说是关系到整个系统的逻辑合理性了。一般,当一个数据库被设计出来,那就意味着系统的基本逻辑,功能都已经确定了。

在之前,对于数据库的设计一般只是局限于想到什么就加什么,但是在实现功能的时候,需要错误的设计做更多可以避免的编码。

关于学校类系统,也设计了一些,但一般最多也就一层关系;所以印象里,学校类系统并不怎么样;但通过这次的数据库设计,明白一个功能完善的学校系统,需要考虑的方面太多太多了。小至上课时间,大至上课地点。这些都要一一考虑。

其实这几天一直听到一个概念,“数据库设计的表很少是不是不合理?”。于我理解而言,数据库的设计好坏和表的数量并没有关系,表越多,固然可以分门别类地把数据存储好,但是其中的关系如果不理清楚,只会徒增工作量。在Java语言中,一个表意味着一个实体,一个dao层,甚至更多;而且不同的表,表内的结构却是大部分一致,那也意味着冗余了,如全局配置表sys_dicts中的角色,是可以拆分成管理员表,教室表和学生表3张表;表越少,意味着有些不同性质的数据需要在一个表中。例如上面讲到的未绑定老师的课程和绑定老师的课程可以存储在同一张课程表sys_class中,但是这意味着表中有2类数据。而这两类数的字段结构并不一致。绑定老师的课程是有上课时间字段的,还有其它字段。所以数据库的设计好和表的数量并没有关系。

这一整套设计方案是在原来的基础上的修改,并增加了一些逻辑和思路。所以总有些地方可能没考虑周全。最后,如有错误,请斧正

Logo

助力广东及东莞地区开发者,代码托管、在线学习与竞赛、技术交流与分享、资源共享、职业发展,成为松山湖开发者首选的工作与学习平台

更多推荐