数据库课程设计2
DATABASE FINAL TEST
前言
个人认为大家对设计数据库等思维上的问题都不存在问题,故将重点放在代码撰写,debug,环境配置上。
整体过程概述
1.配置环境
前端使用html+css+js+php
后端php+mysql
工具使用:phpstorm,mysql bench,edge浏览器,firefox浏览器
学习html,php的基本语法等
2.整体设计
详尽的思考系统边界
进行数据库设计以及功能实现(客户端)的设计
3.start coding
同时进行功能的增加和DEBUG
环境配置
php环境
使用phpstudy懒人包,直接完成配置(但是也存在问题).
**1 **download phpstudy window/linux version
2 在phpstudy中选择安装mysql(或者在mysql官方下载)
2.5 mysql图形管理工具,可以使用phpmyadmin(个人没有使用成功),或者mysql bench.
3 下载安装phpstorm widows/linux version
4 在phpstorm中选择php解释器,于是就可以进行php代码的编写了!
DEBUG
以下是我个人遇到的问题。
1mysql启动
首先在本机(arch linux),mysql无法正常启动,显示
Can't connect to local server through socket '/run/mysqld/mysqld.sock' (2)
解决方案:无解,换一台电脑(widows10)进行coding.
2mysql配置
phpstudy中无法启动mysql.点击启动会立刻停止。
解决方案:
1. 换端口,由于widows下mysql服务会自动启动,因此会占用3306端口,因此phpstudy中无法启动mysql,只需在phpstudy中设置mysql将端口换到空闲端口即可(可以在terminal中使用命令行查看,具体百度),但转换端口后可能依旧无法启用。
2.在服务中中断mysql(失败方案),windows不让终止,遂放弃。
3. 在mysql官网重新下载mysql,并将在安装过程中将端口设置为一空闲端口(记住端口号)
3phpstorm配置
如果是初次使用jetbrains的产品,需要使用山大云邮进行验证。
4phpstorm配置
下载好phpstorm后并不能直接运行php代码(由于缺少php的解释器),需要手动添加php解释器。
解决方案:
1.phpstorm中,file->settings->php
2.选择php language level(在phpstudy中下载的php版本),选择CLI interpreters(右边的三个点)
3.添加CLI interpreter,选择localpath,在phpstudy的安装路径中,
./phpstudy/extention
如果是windows系统选择php.exe,linux下选择对应的可执行文件。
综上,php开发环境配置完成。
数据库设计
综述
完全参考山大的选课系统,PPT要求。但考虑大家对自己的数据库肯定已经有些想法故不多赘述。
关于课程开设问题
一个问题,老师是否有权限开设课程?或者说,是否任何老师都有权限开设课程?
答案为否。故个人认为只有管理员有权限开设课程,老师也需要服从组织安排(bushi)
一些精妙的设计(其实也不是数据库的设计)
关于信息录入,我们可以只录入基本信息(学号,账号密码)其余信息不填写,等使用者手动填写(就像很多APP一样)
真的不是我懒
设计不合理之处
与其说是数据库设计的不合理,不如说是前端设计的不合理。
暂时需要人工的添加学生账号和课程号,然而这些作为key的属性最好是不可以人为改变的。
关于学生选课系统的边界
学生选课系统,顾名思义,应该负责管理选课,课程开设等。
但对于成绩管理是否应该列入其中呢?
如果需要列入其中,那么这么过去开设的课程的信息就需要一直保存下来,也就是说对每一学期的课程都要进行存储。但是显然一个学生历史成绩如何对当下的选课关联性不大。
代码编写过程
前言
由于大家使用的编程语言不尽相同,这里只用php做具体例子。
基本框架设计
就学生选课系统来说,需要有登录界面,然后对于学生,老师,管理员有不同的界面。每个界面都要实现相应的功能。(先把需要的功能设计好)
具体实现
就登录界面和学生端,需要实现登录的方法,课程的增删查改。
于是在登录界面,首先使用html的表单功能实现输入帐号和密码
<form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post">
账号:<input type = "text" name = "account">
密码:<input type = "password" name = "password">
<input type = "submit" name = "login" value = "登陆">
<input type = "submit" name = "register" value = "注册?">
</form>
然后通过php的一些Magic Global Constant,将表单中的数据读入到变量中
$id = $_REQUEST["account"];
$password_now = $_REQUEST["password"];
然后链接数据库,在数据库中查找学生/老师/管理员的帐号是否存在与输入一致的,且检查密码是否正确,若存在且密码正确,则跳转到对应的学生/老师/管理员端口.
<?php
$id = $_REQUEST["account"];
$password_now = $_REQUEST["password"];
//DATABASE operations
$conn = connectMysql();
$student_password = queryStudentPassword($conn,$id);
$teacher_password = queryTeacherPassword($conn,$id);
$administrator_password = queryAdminPassword($conn,$id);
//echo $student_password;
//echo $student_password_now;
if($_REQUEST["login"] == "登陆"){
if($student_password === $password_now && $password_now != ""){
session_start();
$_SESSION["id"] = $id;
echo $_SESSION["id"];
$url = "student.php";
header("location: $url");
}else{
echo "failed";
}
if($teacher_password === $password_now && $password_now != ""){
session_start();
$_SESSION["id"] = $id;
$url = "teacher.php";
header("location: $url");
}
if($administrator_password === $password_now && $password_now != ""){
session_start();
$_SESSION["id"] = $id;
$url = "administrator.php";
header("location: $url");
}
}
?>
学生端口可以照葫芦画瓢,同样用表单读入数据,然后进行增删查改。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>山东大学学生选课系统——学生端</title>
</head>
<body>
<!--html-->
<!--选课-->
<form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post">
请输入想要选择的课程号:
<input type = "text" name="select_cid">
<input type = "submit" name = "选课" value = "submit">
</form>
<!--查询-->
<form action = "<?php echo $_SERVER['PHP_SELF']; ?>" method = "post">
请输入想要查询的课程号:
<input type = "text" name = "query_cid">
请输入想要查询的课程名:
<input type = "text" name = "query_cname">
<input type = "submit" name = "查询" value = "submit">
</form>
<!--退课-->
<form action = "<?php echo $_SERVER['PHP_SELF']; ?>" method = "post">
请输入想要退选的课程号:
<input type = "text" name = "drop_cid">
<input type = "submit" name = "退课" value = "退课">
</form>
<!--列出课表-->
<form action = "<?php echo $_SERVER['PHP_SELF']; ?>" method = "post">
<input type = "submit" name = "list_course" value = "列出课表">
</form>
<form action = "<?php echo $_SERVER['PHP_SELF']; ?>" method = "post">
<input type = "submit" name = "list_select_course" value = "列出已选课表">
</form>
<!--php-->
<!--functions-->
<?php
function connectMysql(){
$servername = "localhost:5000";
$username = "root";
$password = " ";
$dbname = "student_course";
$conn = new mysqli($servername, $username, $password,$dbname);
if ($conn->connect_error) {
echo 233333;
die("连接失败: " . $conn->connect_error);
}
return $conn;
}
function queryStudentPassword($conn,$sid){
$sql = "SELECT * FROM student WHERE sid = $sid";
$res = $conn->query($sql);
$row = mysqli_fetch_array($res,MYSQLI_ASSOC);
return $row["student_password"];
}
function queryTeacherPassword($conn,$tid){
$sql = "SELECT * FROM teacher WHERE tid = $tid";
$res = $conn->query($sql);
$row = mysqli_fetch_array($res,MYSQLI_ASSOC);
return $row["teacher_password"];
}
function queryAdminPassword($conn,$aid){
$sql = "SELECT * FROM administrator WHERE aid = $aid";
$res = $conn->query($sql);
$row = mysqli_fetch_array($res,MYSQLI_ASSOC);
return $row["administrator_password"];;
}
function queryCourse($conn,$cid,$cname){
$sql = "SELECT * FROM course WHERE cid = $cid";
$ret = $conn->query($sql);
if(!$ret){
echo "failed";
}else{
return $ret;
}
}
function listCourse($conn){
$sql = "SELECT * FROM course";
$result = $conn->query($sql);
while($result != false && $row = $result->fetch_assoc()) {
echo "课程号: " . $row["cid"]. " 课程名: " . $row["cname"]." 授课老师:". $row['tid']. " 授课时间: ".$row['start_time']. "<br>";
}
}
function listSelectCourse($conn,$sid){
$sql = "SELECT * FROM course WHERE cid in
(SELECT cid FROM student_course WHERE sid = $sid)";
$result = $conn->query($sql);
while($result != false && $row = $result->fetch_assoc()) {
echo "课程号: " . $row["cid"]. " 课程名: " . $row["cname"]." 授课老师:". $row['tid']. " 授课时间: ".$row['start_time']. "<br>";
}
}
function selectCourse($conn,$sid,$cid){
$sql1 = "SELECT * FROM student_course WHERE cid = $cid and sid = $sid";
$sql2 = "SELECT * FROM course WHERE cid = $cid";
$result1 = $conn->query($sql1);
$result2 = $conn->query($sql2);
if($result2->num_rows === 0){
echo "无此课程";
return;
}
if($result1->num_rows > 0){
echo "已选此课";
return;
}
$sql3 = "INSERT INTO student_course VALUES($sid,$cid,NULL)";
if ($conn->query($sql3) === TRUE) {
echo "新记录插入成功";
} else {
echo "Error: " . $sql3 . "<br>" . $conn->error;
}
}
function dropCourse($conn,$sid,$cid){
$sql1 = "SELECT * FROM student_course WHERE cid = $cid and sid = $sid";
$sql2 = "SELECT * FROM course WHERE cid = $cid";
$result1 = $conn->query($sql1);
$result2 = $conn->query($sql2);
if($result2->num_rows === 0){
echo "无此课程";
return;
}
if($result1->num_rows === 0){
echo "未选此课";
return;
}
$sql3 = "DELETE FROM student_course WHERE cid = $cid and sid = $sid";
$result3 = $conn->query($sql3);
if($result3) {
echo "删除成功";
}else{
echo "删除失败";
}
}
function listStudentInfo($conn,$sid){
$sql = "SELECT * FROM student WHERE sid = $sid";
$res = $conn->query($sql);
$row = mysqli_fetch_array($res,MYSQLI_ASSOC);
echo "学号:".$row['sid']." 姓名:".$row['student_name']." 学院:".$row['school']." 身份证号:".$row['id_number']." 年龄:".$row['age']
." 性别:".$row['sex']."<br>";
}
?>
<?php
// 个人信息
session_start();
$conn = connectMysql();
$sid = $_SESSION["id"];
listStudentInfo($conn,$sid);
if($_REQUEST["选课"] == "submit"){
$s_cid = $_REQUEST["select_cid"];
selectCourse($conn,$sid,$s_cid);
}
if($_REQUEST["查询"] == "submit"){
$q_cid = $_REQUEST["query_cid"];
$q_cname = $_REQUEST["query_cname"];
// echo $q_cid;
// echo $q_cname;
$result = queryCourse($conn,$q_cid,$q_cname);
while($result != false && $row = $result->fetch_assoc()) {
echo "课程号: " . $row["cid"]. " 课程名: " . $row["cname"]. "<br>";
}
}
if($_REQUEST["退课"] == "退课"){
$d_cid = $_REQUEST["drop_cid"];
dropCourse($conn,$sid,$d_cid);;
}
if($_REQUEST["list_course"] == "列出课表"){
listCourse($conn);
}
if($_REQUEST["list_select_course"] == "列出已选课表"){
listSelectCourse($conn,$sid);
}
?>
</body>
</html>
DEBUG
1文件间传值
由于php的变量作用域是文件,因此在登录系统中,进行跳转后变量会丢失(比如无法知道当前登录的帐号是什么)。
解决方案:使用SESSION
SESSION可以将值传给服务器,然后由服务器保存,需要时再取出。
//数据传到服务器。
session_start();
$_SESSION["id"] = $id;
//数据从服务器读出
session_start();
$sid = $_SESSION["id"];
2链接mysql失败(mysql8)
由于mysql8使用了新的密码验证插件,因此使用网络上的教程无法链接
(显示如下)
The server requested authentication method unknown to the client
解决方案(个人):启动mysql安装包,进行版本管理,对密码验证功能选择旧版本即可。
或者使用博客方法(失败):
https://blog.csdn.net/u014029795/article/details/104830252
项目展示
播放视频视频视频
一些问题
BUG
1不出所料,果然又出现了对中文的支持问题,在添加课程的过程中,发现如果课程名称为中文则会添加失败,暂时正在解决。
改进
前端
显然,这个界面实在是太丑了!过于拉跨。
安全性
密码在数据库中保存的为密码本身,这很不安全(但是方便调试),所以计划更改为md5加密后的字符串。
功能性
如今的基本功能已经能用,但是使用很不方便,因此计划进行优化。
鲁棒性
此代码为两天内赶工赶出,并没有做太多合理性检测,很有可能有由于用户操作导致的意料之外的bug.