1 实验描述
1.1 实验目的
熟悉开发实现一个数据库应用系统的基本流程。
熟悉数据库操作以及应用与数据库交互过程的编写。
掌握使用数据库作为工具完成访问控制的方法。
掌握防止SQL注入的基本方法。
掌握数据库并发、数据备份与恢复等功能的实现
1.2 实验内容
1.对系统进行需求分析,主要针对数据库进行需求分析,可以采用数据流图、数据字典等方式。
2.对系统和数据库进行设计,根据需求分析的有关内容,画出系统的E-R图,并据此设计对应的数据库表结构,然后对系统进行简单范式分析等。
设计实现一个数据库应用系统,Web、App等皆可,数据库、语言、平台、框架等可自选,推荐使用Linux+Apache+PHP+Mysql。有如下要求:
1)用户登录,至少两种不同类型的用户权限访问控制;
2)用户口令哈希存储;
3)体现数据库完整性检查;
4)体现防SQL注入;
5)进行系统并发测试;
6)具有数据备份与恢复功能。
1.3 实验步骤
1.根据自己所选的数据库、语言、框架以及实验要求,结合前面所学内容进行需求分析和数据库与系统设计。
2.根据需求分析和数据库设计,使用前面所学知识在数据库中建立数据库、数据表等。
3.根据所选的语言、框架设计前端页面
1.4 实验环境
Linux+Apache+PHP+Mysql
Ubuntu16.04.01+Apache/2.4.18+ PHP 5.6.40+ mysql Ver 14.14 Distrib 5.7.33
2 需求分析
根据实验针对要求,选择教务系统作为实现目标
2.1 数据流图
在教务系统中,学生的主要需求为查看所有课程以及选课科目成绩,选择选修课以及在教务系统中打印成绩;教师的主要需求为查看自己所教课程,并登记选修这一门课程的学生的成绩。初步的数据流图如下
在教务系统中,学生的主要需求为查看所有课程以及科目成绩,选择想要选修的课程以及成绩单的打印;教师的主要需求为查看自己任教课程的情况,并对自己课程下学生的成绩进行登记。初步的数据流图如下:
除了实现上述设计的部分以外,还要对学生和老师的个人信息进行处理,因此添加如下部分
数据项:
数据项名 | 含义说明 | 别名 | 数据类型 | 长度 | 取值域 | 取值含义 | 与其他数据项的逻辑关系 |
---|---|---|---|---|---|---|---|
学号 | 唯一标识每一个学生 | 学生编号 | 字符型 | 13 | 0e12~1e13- 1 | 前四位为入学年份,中间四位为学院编号,后五位为学院内的顺序编号 | 主键或外键 |
姓名 | / | / | 字符型 | 10 | 非空 | 一个人的姓名 | |
性别 | / | / | 字符型 | 2 | 男/女 | 一个人的性别 | |
年龄 | / | / | 整型 | 2 | 1~99 | 一个人的年龄 | |
院系 | 所在的院系 | / | 字符型 | 30 | 非空 | 所在的院系 | |
专业 | 所在的专业 | / | 字符型 | 30 | 非空 | 所在的专业 | |
课程号 | 唯一标识每一门课程 | 课程编号 | 字符型 | 11 | 0e10~1e11- 1 | 前四位为开课年份 | 主键或外键 |
课程名 | 课程的名称 | 课程名称 | 字符型 | 30 | 非空 | 课程的名称 | |
工号 | 唯一标识每一个教师 | 教师编号 | 字符型 | 8 | 0e7~1e8-1 | 教师的编号 | 主键或外键 |
成绩 | 学生在某一面课程中的成绩 | 成绩 | 整型 | 3 | 0-100 | 学生在课程下的成绩 | |
学分 | 每一门课有不同的学分 | / | 整型 | 1 | 0~9 |
数据结构:
数据结构名 | 含义说明 | 组成 |
---|---|---|
学生 | 是学籍管理的主体数据结构,定义了一个学生的个人信息 | 学号、姓名、性别、年龄、院系、专业、加权平均成绩 |
教师 | 定义了一个教师的个人信息 | 工号、姓名、性别、年龄、院系 |
课程 | 定义了一门课程的信息,包括执教老师工号 | 课程号、课程名、学分、工号 |
成绩单 | 定义了一门学生成绩的有关信息 | 课程号、课程名、成绩 |
选课单 | 定义了一门课程的选课有关信息 | 学号、性别、院系、专业、成绩 |
数据流:
数据流名 | 说明 | 数据流来源 | 数据流去向 | 组成 |
---|---|---|---|---|
学生 | 学生的唯一标识 | 学生 | “学生选课”处理 | 学号 |
学生 | 学生的个人信息 | 学生表 | “学生选课”处理 | 学号 |
课程 | 课程的信息 | 课程表 | “学生选课”处理 | 课程号 |
选课信息 | 学生所选课程信息 | “学生选课” 处理 | 学生选课表 | 学号、课程号 |
成绩 | 学生所选课程成绩信息 | 教师 | “成绩登记”处理 | 学号、课程号、成绩 |
选课信息 | 学生所选课程信息 | 学生选课表 | “成绩登记”处理 | 学号、课程号 |
成绩 | 所选所选课程成绩信息 | “成绩登记” 处理 | 学生选课表 | 学号、课程号、成绩 |
学生 | 学生的唯一标识 | 学生 | “打印成绩单”处理 | 课程号、课程名 |
课程 | 课程的信息 | 课程表 | “打印成绩单”处理 | 课程号、课程名 |
成绩 | 学生的课程成绩信息 | “打印成绩单”处理 | 成绩单 | 课程号、学号、成绩 |
学生成绩信息 | 学生所有课程的成绩信息 | “打印成绩单”处理 | 成绩单 | 课程号、课程名、成绩 |
学生 | 学生的个人信息 | 学生表 | “打印选课单”处理 | 学号、姓名、院系、专业 |
选课信息 | 学生所选课程信息 | 学生选课单 | “打印选课单”处理 | 学号、课程号 |
选课学生信息 | 某课程的所选选课学生信息 | “打印选课单”处理 | 选课单 | 学号、姓名、院系、专业、成绩 |
处理过程:
处理过程名 | 说明 | 输入 | 输出 | 处理 |
---|---|---|---|---|
学生选课 | 学生从可选修的课程中选课 | 学生、课程 | 学生选课信息 | 每学期学生都可从公布的课程中选修需要的课程 |
成绩登记 | 教师对所授课的学生成绩进行登记 | 选课信息、成绩 | 成绩 | 每学期教师对授课课程的学生成绩进行登记、 |
打印成绩单 | 学生对所选课程成绩进行打印 | 学生、课程、成绩 | 学生成绩信息 | 学生可以查询并打印所选课程成绩 |
打印选课单 | 教师对某一课程下的选课名单信息进行打印 | 学生、课程、选课信息 | 选课学生信息 | 教师可以查询并打印自己某一课程的选课名单 |
3 数据库设计
3.1 系统设计与数据库设计
根据2中分析,可以发现总体为:学生、教师以及课程分别对应三个实体,E-R图如下所示:
针对实体和实体关系进行建表,可以初步分为学生表(学号,姓名,性别,年龄,院系,专业)、教师表(工号,姓名,院系)、课程表(课程名,课程号,学分)、选课表(学号、课程号、成绩)、授课表(课程号、工号)。
根据ER图转换为关系模式
学生(学号,姓名,性别,系别,入学时间,家庭住址,专业,密码)
教师(教师号,姓名,性别,系别,学历,职位,密码)
课程(课程号,教师号,课程名,学分)
成绩(选课号,学号,成绩)
选课(选课号,学号)
授课(课程号,教师号,课程名)
因为各表函数依赖左部都包含候选码(学号、工号、课程号、(学号,课程号)),所以至少是BCNF。
4 数据库及表的建立
本实验选择在Web上实现一个简易版的教务系统,选择实验框架为LAMP,相关配置参考实验一
4.1 数据库的建立
首先建立数据库eas(Educational Adminstration Systeam):CREATE DATABASE eas;,然后在数据库eas中建立3中分析的各表,因为元组信息涉及中文,因此将表的默认编码设为utf8
4.2各表建立(完整性测试)
USER:
因为需要经过登录操作来是实现用户权限访问控制,所以需要对用户的登录账号、口令及权限进行存储,这里的登录账号就是学生的学号、教师的工号,对应的建表语句如下:
CREATE TABLE user ( id INT(11) PRIMARY KEY AUTO_INCREMENT, username VARCHAR(255) NOT NULL UNIQUE, password VARCHAR(255) NOT NULL, identity INT(1) NOT NULL, name VARCHAR(255) ) DEFAULT CHARSET=utf8;
id为自增的逐渐,不用而额外赋值;username为用户的账号名设置为非空且UNIQUE(不能重复);password为账号对应的口令设置为非空,同时为了防止信息泄露,这里对用户口令进行哈希存储;identity为用户的身份标识(非空),实现用户权限访问控制,-1标识管理员权限,0标识学生,1标识教师;另外额外存储name字段,显示用户姓名,方便操作。
Student:
student表中,各个字段存储的相对于的个人信息,建表如下:
CREATE TABLE student ( id INT(11) PRIMARY KEY AUTO_INCREMENT, username VARCHAR(255) NOT NULL UNIQUE, name VARCHAR(255), sex VARCHAR(5), age INT(5), college VARCHAR(255), major VARCHAR(255), FOREIGN KEY (username) REFERENCES user(username) ON DELETE CASCADE ) DEFAULT CHARSET=utf8;
其中username为外键,说明student中必须为已经注册的用户,才可以拥有个人信息,当用户注销时,其对应的个人的信息也将被删除;同样属于数据库完整性检查的一部分,还需要对sex、age等字段的值进行规定,但是因为MySQL的限制不可以通过CHECK语句来实现,因此要在之后的php编写过程中通过判断语句手动实现
teacher:
teacher表中,各个字段存储的相对于的个人信息,建表如下:
CREATE TABLE teacher ( id INT(11) PRIMARY KEY AUTO_INCREMENT, username VARCHAR(255) NOT NULL UNIQUE, name VARCHAR(255), college VARCHAR(255), FOREIGN KEY (username) REFERENCES user(username) ON DELETE CASCADE ) DEFAULT CHARSET=utf8;
其中username为外键,说明student中必须为已经注册的用户,才可以拥有个人信息,当用户注销时,其对应的个人的信息也将被删除;同样属于数据库完整性检查的一部分,还需要对sex、age等字段的值进行规定,但是因为MySQL的限制不可以通过CHECK语句来实现,因此要在之后的php编写过程中通过判断语句手动实现
Course:
Corse表中记录了各项课程的信息,建表语句如下:
CREATE TABLE course ( id INT(11) PRIMARY KEY AUTO_INCREMENT, cno VARCHAR(255) NOT NULL UNIQUE, cname VARCHAR(255) NOT NULL, username VARCHAR(255) NOT NULL, name VARCHAR(255) NOT NULL, number INT(3) NOT NULL DEFAULT 0, FOREIGN KEY (username) REFERENCES teacher(username) ON DELETE CASCADE ) DEFAULT CHARSET=utf8;
cno、cname分别对应着课程的编号和课程名且课程编号设为UNIQUE,不可重复以及课程名称设置为非空;username、name是任课教师的工号及姓名,同样通过外键限制,表现为注册在籍的教师才能任课;number则是一门课程的选课人数(初始为0),通过计算可以得出课程的剩余容量(本教务系统中简单地将所有课程的最大容量设为120),以辅助选课的进行。
S_C:
S_C表将学生信息与课程信息结合起来,描述所有学生的选课情况以及成绩情况,建表语句如下:
CREATE TABLE S_C ( id INT(11) PRIMARY KEY AUTO_INCREMENT, username VARCHAR(255) NOT NULL, cno VARCHAR(255) NOT NULL, grade INT(5), FOREIGN KEY (username) REFERENCES student(username) ON DELETE CASCADE, FOREIGN KEY (cno) REFERENCES course(cno) ON DELETE CASCADE ) DEFAULT CHARSET=utf8; ALTER TABLE S_C ADD UNIQUE KEY(username, cno);
Username设置为选课学生的学号,cno为相应课程的编号;grade为选课成绩,因为选课时没有成绩,故设置为默认为空。同时选课表中的username和cno均为外键并共同构成UNIQUE,可以通过该键进行信息的查询。
至此,数据库表的建立初步完成,若有其他需要,可以在上述表中继续加入更多列。
4.3 用户权限及功能
本实验中涉及的教务系统,一共有三种身份:管理员、学生、教师,首先确定每个身份的去权限及可以进行的对应操作
管理员:
整个教务系统中有且仅有1名数据库管理员,有着最高权限,管理学生用户和教师的注册于注销;所有课程的添加与删除也必须在该身份下完成;另外模拟显示生活中教秘统一登记成绩,所有选课记录对应的成绩也由管理员进行完成修改;管理员同时负责整个数据库的维护和备份与恢复,防止出现重大意外。
学生:
学生通过管理员提前给的不同账号及对应的口令登录教务系统,可以查看个人信息并进行修改(账号学号除外);所有课程信息据内可见,同时根据课程余量决定选课结果;每个学生在老师给出成绩后可以查看所选课程的成绩,并导出为成绩单
教师:
教师通过管理提前给的不同账号及对应的口令登录教务系统,查看个人信息并进行修改(账号工号除外);教师查看自己授课课程选课情况及学生成绩,并将其导出为选课单
5 教务系统的设计(附PHP源码实现分析)
5.1 页面设计
教务系统分为登录页面和用户页面,用户页面因为4中用户分类又可以分为管理员页面、学生页面、教师页面。本实验中,通过html、css以及js的结合对教务系统涉及到的所有界面进行设计,具体的功能实现在PHP中实现。
实验中所有的页面设计文件都位于文件夹style中,所有html文件在教务系统的使用中并不发挥实质性作用,仅作为设计实现的一部分,起预览作用。以下则是对各个界面的简要分析。
5.2 登录界面
所有用户公用一个登录界面,界面仅具有登录框,输入正确的username和password即可,具体参见文件style/login.html
5.3 管理员界面
管理员界面又管理用户、管理课程以及登记成绩三部分组成。管理用户界面显示用户及更改用户的输入框,参见文件style/admin/admin_course.html;登记成绩界面所有选课记录对应成绩的输入框,参见文件style/admin/admin_grade.html。三个界面的切换
由左侧导航栏实现,跳转命令参见文件style/admin/admin.js。
5.4 学生界面
学生界面由个人信息,选课列表以及成绩查询三部分所构成。个人信息界面显示个人信息及更改用户口令的输入框,参见文件style/student/student_student.html;选课列表显示所有课程信息及选课的输入框,参加文件
5.5 嵌入PHP
教务系统所有的功能实现均依赖PHP语言实现,通过嵌入html来完成各种功能,对应的php文件均在对应文件夹中。教务系统功能是实现各PHP文件的相互切换,来完成对数据库的调用。大部分php文件是在上述完成的界面内嵌入PHP来实现的,也有少数功能只有PHP单独构成,并无可视界面。
5.6 函数 check($value)(防止sql注入):
在许多php文件中,都会有一个函数check的定义,该函数的主要功能是检查输入,并对特护符号加上反斜杠,从一定程度上防止sql的注入。函数实现如下:
function check($value) { if (get_magic_quotes_gpc()) { $value = htmlspecialchars(trim($value)); } else { $value = addslashes(htmlspecialchars(trim($value))); } return $value; }
5.7 身份识别
在php文件中,需要对身份信息进行确认,来获取各自身份的权限,否则所有的用户都可以通过直接访问获得超出权限的操作。这里通过读取绘画信息中保存的信息进行判断。
if (!isset($_SESSION['username']) or !isset($_SESSION['identity'])) { header("Location:login.php"); exit();
其中判断身份-1为管理员,0为学生,1为教师
if ($identity == -1) { // admin header("Location:admin_user.php"); exit(); } elseif ($identity == 0) { // student header("Location:student_student.php"); exit(); } elseif ($identity == 1) { // teacher header("Location:teacher_teacher.php"); exit(); } else { echo " <script> alert('无法识别的身份信息!!'); window.location.href = 'login.php' ; </script> "; exit(); }
5.8 数据库的连接与关闭(实现并发功能)
在PHP与mysql的交互过程中,直接使用mysqli系列函数即可实现数据库的连接与关闭。
$db = @mysqli_connect("localhost", "root", "123456", "eas"); if (!$db) { die("Fail to connect the database!!" . mysqli_connect_error()); } mysqli_query($db, "begin");
使用函数@mysqli_connct()连接数据库eas,如果来凝结失败则会退出当前界面,并输出连接错误信息,如果连接成功则继续进行,跳转到下一界面。因为涉及学生选课等操作,系统应具有并发功能,所以通过函数mysqli_query($db,’begin’)来开启事务,来避免不必要的错误并与允许rollback操作。
mysqli_query($db, "commit"); mysqli_close($db); mysqli_query($db, "rollback"); mysqli_close($db);
当增删查操作成功完成后,对结果进行commit;当完整性检查后无法进行或是发生位置错误时则会rollback,并和数据库断开连接。
5.9登录用户口令哈希存储
登录时规定用户名及口令不能为空,且对用户名进行检查并调用MD5函数对password进行哈希加密。在成功连接数据库后,通过与查询到的user表中口令进行比对,来判断是否登录成功,参见如下代码:
$username = check($_POST['username']);= $password = MD5($_POST['password']);
登录失败时,会弹出警告窗口提示错误信息,并返回login界面;登录成功,则将用户名及对应身份信息临时存储到会话信息中,跳转到loginSuccess.php,并在此文件中,识别用户身份,跳转到对应页面。
版权声明:
1、该文章(资料)来源于互联网公开信息,我方只是对该内容做点评,所分享的下载地址为原作者公开地址。2、网站不提供资料下载,如需下载请到原作者页面进行下载。
3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考学习用!
4、如文档内容存在违规,或者侵犯商业秘密、侵犯著作权等,请点击“违规举报”。