对于学生选课和成绩管理系统数据库设计的分析
额数据库是啥呢
数据库是存储在计算机上的有组织可共享的大量数据的集合
那么我们应当解决两个问题
第一怎么存
第二存什么
第三如何取
第四如何更新
那么设计什么样的数据结构跟实现什么样的功能是密切相关的
那么看到标题就可以想到是学生选课和学生成绩管理
那么最基础的肯定要有学生,课程,成绩
这三种数据对象
如果有大量的数据实例我们都可以分到这几种数据对象里
那么首先我们要分析学生与课程的关系是选与被选。。
那么这里就有一个基础的问题了通过学生一个实例我们怎么知道他选了哪些课程呢
图论里我们知道如果一个学生选了一门课于是我们可以连边
A[stuid].push_back(courseid)
B[courseid].push_back(stuid)
那么我们每次查一个学生选了哪些课遍历一遍线性表就ok
这里似乎是不用考虑时间复杂度的数据量小?
这样存的意思似乎是。。每一个学生编号代表一个表。。然后里面存了一堆课程结构体
然后课程也是这样。。。相当于表里套表
链表。。
在数据库里该如何处理呢。。
我还没想到怎么妥善处理
但是我们还有一种解决方法
那就是单独存一个选课关系表
每一条是课程学生关联的一个条目。。
但是这样课程信息就冗余了。。
其实学生和信息都挺冗余的。。
后来问了一下菊苣。。这个存法实际上是正确的。。。
因为你O(n)的空间怎么存的下n^2的图呢。。
链表跟存边的表还是有区别的。。
链表只存一个头
边表会重复多个头
边表可以双向遍历,这是链表所不能具备的。。链表只能单向。。准确的说是一次比较两个关键字
那么我们的边表就相当于合并了我刚刚说的那两个链表,我们通过这个边表来实现快速的存取
那么这个选课关系边表的主键是啥。。能唯一标识一个元祖的东西都可以用来当主键。。
显然这里我们可以让stuid,courseid来当主键,这个有重复就不合理了对吧。。怎么hash出不同的散列值是数据库的事情了吧
//所以我们就。。把课程单独抽出来。。每个课程做一个选课表?
关于学生和成绩以及课程和成绩。。
那么一种思路是说。。我们可以参考选课表的主键。。
就是说。。有成绩的前提是某个学生选了这个课
那么我们就可以参考这个关系。。那么对于每一个选课关系都可以对应一个成绩。。
那么这个成绩既是学生的成绩又是课程的成绩。。
上面选课表我们如果只存stuid,courseid,查到了还要再去学生表和课程表里面再去找
那么我们可以采取多加空间存上学生的一些信息。。和课程的一些信息。。这样可以减少查找时间
相当于是在用空间换时间。。那么你这样做的后果是增加空间。。并且每次更新也要实时地更新才行
链表存到数据库里实际上就是把链表变成edge pair然后把edges存进去,当然要处理成唯一的
还有一个发现的事实是。。查找路径一般在数据库里不用存储,怎么查和怎么高效查询是程序员以及数据库设计之初做的工作?
一般来说要做好的工作是维护好数据的逻辑性?维护好数据之间的关系?
数据库的重构。。好像还没有资格考虑。。
那么关于这三者的关系应该是理清了。。。
那么我们还要实现其他的功能。。。
其他要实现的功能我还没有理清下面我们把他们都打上一遍熟悉一下
不过对于刚才成绩那里还是有问题的。。如果说。。这个学生选了课但没有考试。。那么他的成绩是多少呢
如果是0,那么考过也可以是0啊对吧。。有歧义的。。我们还可以另开一个判断考试状态的标志位来进行特判
那么对于成绩还有问题。。如果说还有添加其他类型的成绩。。比如说。。平时成绩。。实验成绩。。考试成绩
那么对于这种类型的扩展。。由于关系并没有太大的变化。。基本上我们是可以考虑直接附加在基本成绩或者
最终成绩的后面
有时候这种业务逻辑的处理可以交给人?比如某成绩算多少。。都算哪些成绩
=========
我们来分析一下系统管理员的功能(1人)
需求分析里写了。。这个工作只需要一个人来干
首先他要进行教务管理员的信息维护。。
就是说对于教务管理员所有信息的增删查改。。包括对于教务管理员用户名和密码的修改
因为这个涉及到安全性。。所以。。要考虑特判和权限问题。。毕竟不是所有人都能操作
特判一般放到程序中处理?
而且我们还要设计教务管理员都要有哪些必要信息需要登记
他还要进行对于系所基本信息的增删查改。。那么上面他说过顶层教学单位是院。。所以说
我们要有一个表来存一共有哪些院。。
然后我们还需要再建立一个表外键是院系,表明每个院都有哪些系所。。
有了系所我们还需要再建立一个专业表。。
外键是系所。。表明每个系所都有哪些专业。。
有了专业表我们还需要建立一个班级表。。
外键是专业。。表明每个专业都有哪些班级
除此之外系统管理员还能修改课程的类别信息。。
而且还能修改自己的密码
=============
对于教务管理员
教务管理员可以对学生的基本信息进行增删查改
为了避免教务管理员更改系统管理员的密码。。可以分开存储表。。或者特判
教务管理员还能对于教师的基本信息进行增删查改。。甚至用户名密码
策略可以是。。如果确认是教师。。那么我们就取出用户id。。在用户表里修改对应id的密码
他还要求维护开课计划
开课计划维护(课程名、课程编号、课程类别、总学时、学分、开课年级)
那么我们再开一个开课计划表。。那么这个情形就和单独头结点的链表相似了。。存的是节点而不是边
开课这个节点和所有课程的连边
他还要求开课数据的维护。。
开课数据维护(课程编号、任课教师、开课班级、选课人数上限等,需要支持合班功能)
开课数据必然在开课计划中有的前提条件为true的情形下进行?
不太确定。。因为开课计划是常常变化的。。不过这个也是常常变化的。。
外键先缓一手
如果说我们再开一个开课数据表。。那么除了储存课程基本信息。。他还要求支持合班功能。。
合班功能是什么意思呢。。我们枚举一下题意
第一把这个课程的多个授课班级合并成一个。。
第二仅仅是为了允许一个课程可以有多个授课班级。。
那么无论是哪一种情况我们都需要考虑再开一个链表。。存储开课数据表中的多个授课班级
我们新建一个授课班级表
所以说我们可以开外键来存链表。。然后动态修改每个课程的授课班级条目就能实现合并班级?
我认为讲道理。。我们还是要存多个班级的?
当然我们也可以考虑设计成每个条目是课程-授课班级的边表来存储。。这样也行的吧
最后一个功能他可以修改自己的密码
=======================
对于学生功能
学生可以查询他已经选了的课程和他的成绩。。不知道没考试的科目能不能查。。
按理说。。成绩是不存在的。。
学生可以查看自己的基本信息
学生可以修改自己的登录密码。。
学生可以选课。。那么这个功能就相当于往选课表里面添加元祖
===================
对于教师。。
教师可以更改自己的登录密码
教师可以查看开课信息,每个课程的基本信息与选课学生的名单。。这个可以由基本表去生成
成绩录入功能。。。批量地给学生列表来更新或者插入成绩。。那么。。我们是需要做成一个列表。。
我们通过选择课程来唯一标识一群学生
成绩导入功能。。。根据学生学号和课程号来更新学生的成绩。。
我们可以先在选课表里面找到这个关系。。通过这个关系再去成绩表里面去更新这个成绩