1、概述
1.1项目背景
为了深刻的理解MySQL数据库,以学生成绩信息管理为例,设计一个简单、规范、高效的学生成绩信息管理系统数据库。
1.2需求分析
1.2.1信息需求
对学校而言,学生成绩管理是管理工作中重要的一环,但是高校学生的成绩管理工作量大、繁杂,人工处理非常困难。因此,借助于强大计算机的处理能力,能够把人从繁重的成绩管理工作中解脱出来,并且更加准确、安全、清晰的管理环境。
1.2.2 功能需求
能够进行数据库的数据定义、数据操纵、数据控制等处理功能。具体功能应包括:可提供课程安排、课程成绩数据的添加、插入、删除、更新、查询,学生及教职工基本信息查询的功能。
1.2.3 安全性与完整性要求
对于学生成绩管理系统数据库来讲,由于其主要数据是学生成绩,只能由本人以及所教老师及教务处知道,因此做好数据安全性是重中之重。另外,要求所有在校学生的信息都要录入其中,并且要设计好个别情况。
2. 概念结构设计
概念结构设计是整个数据库设计的关键,它通过对用户需求进行综合、归纳与抽象,形成一个独立于具体DBMS的概念模型。
根据学生成绩信息管理数据库设计需求抽象出学生、教师、课程、成绩四个实体,对四个实体做简化处理,默认一门课程仅被一位老师讲授。因简化后关系结构比较简单,故省略了局部E-R图。对4个实体之间的关系进行分析如下:
一位学生会被多位老师教导,一位老师会教导多位学生,所有学生与教师之间是多对多(m:n)的关系;
一位学生可能会选修多门课程,一门课程会被多位学生选修,所以学生与课程之间是多对多(m:n)的关系;
一位学生会有多项成绩(具体指某学生一门课程的分数),一项成绩仅被一位学生拥有,所以学生与成绩是一对多(1:n)的关系;
一位教师会讲授多门课程,一门课程会被一位教师讲授,所以教师与课程的关系是一对多(1:n)的关系;
一门课程拥有多项成绩,一项成绩仅被一门课程拥有,所以课程与成绩的关系是一对多(1:n)的关系;
2.1 抽象出系统实体
学生(学号、姓名、班级、性别、专业、出生日期、学分);
老师(教师编号、姓名、学院);
课程(课程编号、教师编号、课程名称、课程学分);
成绩(学号、课程编号、分数);
2.2 全局E-R图
3. 逻辑结构设计
3.1 关系模式
E-R图向关系模型转化要解决的问题是如何将实体型和实体间的联系转化为关系模式,如何确定这些关系模式的属性和码。
设计学生成绩管理数据库,包括学生(students)、老师(teachers)、课程(courses)、成绩(scores)四个实体,其关系模式中对每个实体定义属性如下:
students 表:学号(sid)、姓名(sname)、班级(sclass)、性别(sgender)、专业(smajor)、出生日期(sbirthday)、学分(credit_points),此为联系“students表”所对应的关系模式,学号为该关系的候选码,满足第三范式。
teachers表:教师编号(tid)、姓名(tname)、学院(tschool),此为联系“teachers表”所对应的关系模式,教师编号为该关系的候选码,满足第三范式。
courses表:课程编号(cid)、教师编号(tid)、课程名称(cname)、学分(credit_point),此为联系“courses表”所对应的关系模式,课程编号和教师编号为该关系的候选码,满足第三范式。
scores表:学号(sid)、课程编号(cid)、分数(score),此为联系“scores表”所对应的关系模式,学号和课程编号为该关系的候选码,满足第三范式。
3.2表结构
数据库中包含4个表,即学生(students)、老师(teachers)、课程(courses)、成绩(scores)。
students表的表结构
teachers表的表结构
courses表的表结构
scores表的表结构
4. 物理设计和实施
4.1 数据库及表创建
4.1.1 创建数据库
-- 如果已有该数据库,则删除
DROP DATABASE IF EXISTS StudentScore;
-- 创建数据库
CREATE DATABASE StudentScore CHARSET=UTF8;
4.1.2 创建数据表
-- 使用数据库
USE StudentScore;
-- 创建数据表
-- table 1: students
DROP TABLE IF EXISTS students;
CREATE TABLE students(
sid INT(20) UNSIGNED PRIMARY KEY AUTO_INCREMENT NOT NULL,
sname VARCHAR(20),
sclass INT(10),
sgender VARCHAR(10),
smajor VARCHAR(20),
sbirthday DATE,
credit_points INT(5) -- 学生已修学分
);
-- table 2: teachers
DROP TABLE IF EXISTS teachers;
CREATE TABLE teachers(
tid INT(10) UNSIGNED PRIMARY KEY AUTO_INCREMENT NOT NULL,
tname VARCHAR(20),
tschool VARCHAR(20)
);
4.2 表数据增删改查测试
4.3 创建视图
4.3.1 创建一个学生视图,要求显示学生学号、姓名、班级、性别、专业、各科成绩、平均分、总分
DROP VIEW IF EXISTS v_students_info;
CREATE VIEW v_students_info AS
SELECT stu.sid,
stu.sname,
stu.sclass,
stu.sgender,
stu.smajor,
ifnull(sum(sc.score), 0) AS "总分"
FROM students stu LEFT JOIN
scores sc ON stu.sid = sc.sid LEFT JOIN
courses c ON c.cid = sc.cid
GROUP BY stu.sid;
4.4 创建函数
4.4.1 创建一个通过学号sid获取学生信息的函数
DROP FUNCTION IF EXISTS get_student_info_by_sid;
DELIMITER //
CREATE DEFINER = CURRENT_USER FUNCTION get_student_info_by_sid(id INT)
RETURNS VARCHAR(300)
DETERMINISTIC
BEGIN
END//
DELIMITER ;
-- 调用函数
SELECT get_student_info_by_sid(8);
4.4.2 自定义函数 2:要求函数体中包含其中一种流程控制语句,要求输入学生学号sid、课程编号,显示学生姓名、课程名称、成绩是否及格(即成绩>=60)
DROP FUNCTION IF EXISTS get_student_scores_by_id;
DELIMITER //
CREATE DEFINER = CURRENT_USER FUNCTION get_student_scores_by_id(sid INT, cid INT)
RETURNS VARCHAR(300)
DETERMINISTIC
BEGIN
-- 多个变量要分开声明,否则会报错
DECLARE score INT;
DECLARE name VARCHAR(20);
DECLARE course_name VARCHAR(20);
ELSE
RETURN '找不到该学生、课程或该学生没有选课!';
END IF;
END//
DELIMITER ;
-- 调用函数
SELECT get_student_scores_by_id(1, 2);
4.5 创建存储过程
4.5.1 学生每选修一门课,如果该门课程成绩达到60分及以上,则把该门课程学分加到学生学分里面,输出该学生姓名、学分
DROP PROCEDURE IF EXISTS add_scores;
DELIMITER //
CREATE DEFINER = CURRENT_USER PROCEDURE add_scores(
IN stu_id INT,
IN co_id INT,
IN s_score INT,
OUT name VARCHAR(20),
OUT s_credit_point INT
)
DETERMINISTIC
BEGIN
-- 多个变量要分开声明,否则会报错
DECLARE points INT;
COMMIT;
END//
DELIMITER ;
-- 测试调用存储过程
SELECT * FROM students WHERE sid > 10;
CALL add_scores(11, 2, 33, @name, @s_credit_point);
SELECT @name, @s_credit_point;
CALL add_scores(12, 2, 88, @name, @s_credit_point);
SELECT @name, @s_credit_point;
4.6 创建触发器
4.6.1 创建一个更新学生学分的触发器,如果该学生分数>=60,则给该学生加上这门课的学分
DROP TRIGGER IF EXISTS update_credit_point;
DELIMITER //
CREATE TRIGGER update_credit_point
AFTER INSERT ON scores FOR EACH ROW
BEGIN
DECLARE points INT;
END IF;
END//
DELIMITER ;
-- 测试数据
SELECT * FROM students WHERE sid < 3;
INSERT INTO scores VALUES
(1, 4, 77),
(2, 4, 55);
SELECT * FROM students;
实验总结
本实验按照数据库设计的整体流程进行规划和设计关系型数据库,设计了相关关系模式,为后续进一步设计和实现更加复杂的数据库打下坚实基础,对数据库相关知识点进行了巩固。