当前位置: 首页 > article >正文

大学生创新创业项目管理系统设计——数据库实验九

 本实验为自己设计完成,我当年数据库实验得了94分

目录

1.实验目的

2.实验内容和要求

3.实验步骤

4.实验心得


实验九 数据库设计

1.实验目的

掌握数据库设计的过程和方法。

2.实验内容和要求

(35)大学生创新创业项目管理系统设计

一个学生可以参加多个创新创业项目,一个创新项目也可以多个学生参加,创新项目立 项分为国家、省市、学校等不同的等级,有不同的经费资助,每个项目可以有多个指导教师, 创新项目可以用论文、软著、专利结题,论文有作者、期刊名称、发表时间、卷期页号等信 息,软著有发明人、软著名称、软著登记号等信息,专利有申请号、申请时间和发明人等信 息。试设计一个大学生创新创业管理系统,能够完成对学生创新创业的管理,可以实现统计 高校各个学院某个时间段内创新创业的参加和结题情况,也可以统计各个年级某个时间段内 创新创业的参加情况。

对以上题目进行数据库设计,通过网络平台或图书馆查找相关文献进行需求分析,按照下面的实验步骤完成设计要求。

3.实验步骤

(1)根据所选题目进行系统需求分析和系统设计,画出系统的 E-R 图,给出实体或联

系的属性,标明联系的种类;

由上图可知,学生、项目、论文(或软著、专利)之间存在冗余,我考虑了去除“结题”这一联系,但是由于学生与项目之间是多对多的关系、学生与论文(或软著、专利)之间也是多对多的关系,去除“结题”这一联系后,对于指定项目的结题成果将无法查询到,所以决定保留此冗余,以便于后续查询。

(2)把 E-R 图转换为关系模式;

以下画下划线表示主键,字体加粗的表示外键

1)院系(院系号,院系名)

2)专业(专业号,专业名,院系号

3)学生(学号,姓名,专业号

4)论文(卷期页号,期刊名称,发表时间,项目号

5)专利(专利号,专利名,申请号,申请时间,项目号

6)软著(软著登记号,软著名称,登记时间,项目号

7)项目(项目号,项目名,立项时间,结项时间,等级号

8)项目类型(等级号,等级名,经费)

9)指导老师(工号,姓名)

10)项目学生位次(学号,项目号,学生位次)

11)项目指导老师(工号,项目号

12)学生所得论文(学号,卷期页号,位次)

13)学生所得软著(学号,登记号,位次)

14)学生所得专利(学号,专利号,位次)

(3)根据关系规范理论进行数据库的逻辑设计,给出数据库表的设计,数据库表设计

表1 院系表(department)

字段名

中文含义

类型

约束

备注

did

院系号

char(10)

主键

dname

院系名

varchar(20)

Not null

comment

备注

varchar(20)

null

.

表2 专业表(major)

字段名

中文含义

类型

约束

备注

mid

专业号

int

主键

mname

专业名

varchar(20)

not null

did

院系号

char(10)

外键,参照department表的did

comment

备注

varchar(20)

null

表3 学生表(student)

字段名

中文含义

类型

约束

备注

sid

学号

int

主键

sname

姓名

varchar(20)

not null

mid

专业号

int

外键,参照major表里的mid

comment

备注

varchar(20)

null

表4 论文表(paper)

字段名

中文含义

类型

约束

备注

pid

卷期页号

char(10)

主键

pname

期刊名称

varchar(20)

null

pdate

发表时间

date

null

prid

项目号

char(10)

外键,来自project表的prid

comment

备注

varchar(20)

null

表5 专利表(patent)

字段名

中文含义

类型

约束

备注

ptid

专利号

char(10)

主键

ptname

专利名

varchar(20)

null

ptdate1

申请时间

date

null

ptno

申请号

char(10)

Not null

prid

项目号

char(10)

外键,来自project表的prid

comment

备注

varchar(20)

null

表6 软著表(swcopyright)

字段名

中文含义

类型

约束

备注

swid

登记号

char(10)

主键

swname

登记名称

varchar(20)

null

swdate

登记时间

date

null

prid

项目号

char(10)

外键,来自project表的prid

comment

备注

varchar(20)

null

表7 项目表(project)

字段名

中文含义

类型

约束

备注

prid

项目号

char(10)

主键

prname

项目名

varchar(20)

null

date1

立项时间

date

null

date2

结项时间

date

date2>date1

tid

等级号

char(10)

外键,来自type表里的tid

comment

备注

varchar(20)

null

表8 项目类型表(type)

字段名

中文含义

类型

约束

备注

tid

等级号

char(10)

主键

tname

等级名

varchar(20)

null

money

经费

budget

not null

comment

备注

varchar(20)

null

表9 教师表(teacher)

字段名

中文含义

类型

约束

备注

teaid

工号

int

主键

name

姓名

varchar(20)

Not null

comment

备注

varchar(20)

null

表10 项目学生位次表(prorank)

字段名

中文含义

类型

约束

备注

prid

项目号

char(10)

外键,来自project表的prid

prid和

sid

联合作为

主键

sid

学号

int

外键,来自project表的sid

rankpr

项目位次

int

not null

comment

备注

varchar(20)

null

表11 项目指导老师(project_teacher)

字段名

中文含义

类型

约束

备注

prid

项目号

char(10)

外键,来自project表的prid

prid和

teaid

联合作为

主键

teaid

工号

int

外键,来自teacher表的teaid

comment

备注

varchar(20)

null

表12 学生所得论文表(stupaper)

字段名

中文含义

类型

约束

备注

sid

学号

int

外键,来自project表的sid

sid和

pid

联合作为

主键

pid

卷期页号

char(10)

外键,来自paper表的pid

rankpa

位次

int

not null

prid

项目号

char(10)

外键,来自project表的prid

comment

备注

varchar(20)

null

表13 学生所得软著表(stusoft)

字段名

中文含义

类型

约束

备注

sid

学号

int

外键,来自project表的sid

sid和

swid

联合作为

主键

swid

登记号

char(10)

外键,来自swcopyright表的swid

ranksw

位次

int

not null

prid

项目号

char(10)

外键,来自project表的prid

comment

备注

varchar(20)

null

表14 学生所得专利表(stupatent)

字段名

中文含义

类型

约束

备注

sid

学号

int

外键,来自project表的sid

sid和

ptid

联合作为

主键

ptid

专利号

char(10)

外键,来自patent表的ptid

rankpt

位次

int

not null

prid

项目号

char(10)

外键,来自project表的prid

comment

备注

varchar(20)

null

(4)对给定的逻辑数据模型选取一个最适合应用环境的物理结构,进行数据库的物理

设计,考虑不同的 DBMS 选型,进行设计方案对比,对物理结构进行评价,评价的重点是

时间和空间效率;

DBMS选型:MySQL。

物理结构设计方案:

    1)使用InnoDB存储引擎,因为它支持事务和行级锁定,适合具有高并发读写需求的应用环境。

    2)为每个表选择合适的索引,以提高查询性能。例如,在学生表上创建一个基于mid字段的B+树索引,以加快按专业查询学生的速度。

    3)考虑使用分区表来提高查询性能和维护效率。根据实际需求,可以根据日期范围或其他条件对论文、专利等表进行分区。

物理结构评价:

    1)时间效率:MySQL在处理大量数据时表现良好,并且支持并发操作。通过适当的索引和分区设计,可以进一步提高查询和写入性能。

    2)空间效率:MySQL的存储引擎具有紧凑的数据存储格式,并且可以通过压缩等技术来减少磁盘空间占用。

(5)在 My SQL 数据库中创建数据库projectcontrol并使用 SQL 语句创建相应的数据库表;

由于存在外键约束,建表顺序依次如下:表1 院系表(department)、表2 专业表(major)、表3 学生表(student)、表8 项目类型表(type)、表7 项目表(project)、表4 论文表(paper)、表5 专利表(patent)、表6 软著表(swcopyright)、表9 教师表(teacher)、表10 项目学生位次表(prorank)、表11 项目指导老师、表12 学生所得论文表(stupaper)、表13 学生所得软著表(stusoft)、表14 学生所得专利表(stupatent)。

以下为建表的SQL语句。

-- 表1 院系表(department)CREATE TABLE department (did CHAR(10) PRIMARY KEY,dname VARCHAR(20) NOT NULL,comment VARCHAR(20));-- 表2 专业表(major)CREATE TABLE major (mid INT PRIMARY KEY,mname VARCHAR(20) NOT NULL,did CHAR(10),comment VARCHAR(20),FOREIGN KEY (did) REFERENCES department(did));-- 表3 学生表(student)CREATE TABLE student (sid INT PRIMARY KEY,sname VARCHAR(20) NOT NULL,mid INT,comment VARCHAR(20),FOREIGN KEY (mid) REFERENCES major(mid));-- 表8 项目类型表(type)CREATE TABLE type (tid CHAR(10) PRIMARY KEY,tname VARCHAR(20),money FLOAT NOT NULL,comment VARCHAR(20));-- 表7 项目表(project)CREATE TABLE project (prid CHAR(10) PRIMARY KEY,prname VARCHAR(20),date1 DATE,date2 DATE,tid CHAR(10),comment VARCHAR(20),CHECK (date2 > date1),FOREIGN KEY (tid) REFERENCES type(tid));-- 表4 论文表(paper)CREATE TABLE paper (pid CHAR(10) PRIMARY KEY,pname VARCHAR(20),pdate DATE,prid CHAR(10),comment VARCHAR(20),FOREIGN KEY (prid) REFERENCES project(prid));-- 表5 专利表(patent)CREATE TABLE patent (ptid CHAR(10) PRIMARY KEY,ptname VARCHAR(20),ptdate1 DATE,ptno CHAR(10) NOT NULL,prid CHAR(10),comment VARCHAR(20),FOREIGN KEY (prid) REFERENCES project(prid));-- 表6 软著表(swcopyright)CREATE TABLE swcopyright (swid CHAR(10) PRIMARY KEY,swname VARCHAR(20),swdate DATE,prid CHAR(10),comment VARCHAR(20),FOREIGN KEY (prid) REFERENCES project(prid));-- 表9 教师表(teacher)CREATE TABLE teacher (teaid INT PRIMARY KEY,name VARCHAR(20) NOT NULL,comment VARCHAR(20));-- 表10 项目学生位次表(prorank)CREATE TABLE prorank (prid CHAR(10),sid INT,rankpr INT NOT NULL,comment VARCHAR(20),PRIMARY KEY (prid, sid),FOREIGN KEY (prid) REFERENCES project(prid),FOREIGN KEY (sid) REFERENCES student(sid));-- 表11 项目指导老师CREATE TABLE project_teacher (prid CHAR(10),teaid INT,comment VARCHAR(20),PRIMARY KEY (prid, teaid),FOREIGN KEY (prid) REFERENCES project(prid),FOREIGN KEY (teaid) REFERENCES teacher(teaid));-- 表12 学生所得论文表(stupaper)CREATE TABLE stupaper (sid INT,pid CHAR(10),rankpa INT NOT NULL,prid CHAR(10),comment VARCHAR(20),PRIMARY KEY (sid, pid),FOREIGN KEY (sid) REFERENCES student(sid),FOREIGN KEY (pid) REFERENCES paper(pid),FOREIGN KEY (prid) REFERENCES project(prid));-- 表13 学生所得软著表(stusoft)CREATE TABLE stusoft (sid INT,swid CHAR(10),ranksw INT NOT NULL,prid CHAR(10),comment VARCHAR(20),PRIMARY KEY (sid, swid),FOREIGN KEY (sid) REFERENCES student(sid),FOREIGN KEY (swid) REFERENCES swcopyright(swid),FOREIGN KEY (prid) REFERENCES project(prid));-- 表14 学生所得专利表(stupatent)CREATE TABLE stupatent (sid INT,ptid CHAR(10),rankpt INT NOT NULL,prid CHAR(10),comment VARCHAR(20),PRIMARY KEY (sid, ptid),FOREIGN KEY (sid) REFERENCES student(sid),FOREIGN KEY (ptid) REFERENCES patent(ptid),FOREIGN KEY (prid) REFERENCES project(prid));

(6)通过导入文件的方式在数据库表中输入若干条测试数据,也可以直接插入若干条

测试数据;

    这里选择通过excel文件导入数据库表数据。

首先创建数据文件:

图2 本地构建excel数据表格

    按照建表顺序,导入各个excel:

图3 导入数据及成功结果

(7)自行设计若干问题并编写 SQL 语句完成对所提问题的实现,SQL 语句要求至少

12 条,自定义功能要求,并对 SQL 语句运行,要求包括下面的语句:

create table(要求包含实体完整性、参照完整性和用户自定义完整性的定义)、create

index、 create view、 select 语句 (至少 5 条,要求把 from、where、group by、having、order by 等子句用上,并实现多表查询)、insert、 delete、update、grant、revoke 语句。对于 select 语句,需要给出相应的数据查询结果的截图。

(8)对自定义的复杂的查询要求或复杂报表生成要求,以及复杂的自定义完整性要求,

使用存储过程和触发器来实现,并进行实验验证,给出验证结果截图。

下面为自拟题目及SQL语句和结果展示:

1)参照project的表结构,创建项目表(project1)时定义实体完整性、参照完整性、用户自定义完整性。

CREATE TABLE project1 (prid CHAR(10),prname VARCHAR(20) NOT NULL, date1 DATE NOT NULL,date2 DATE NOT NULL,tid CHAR(10) NOT NULL,comment VARCHAR(20),CONSTRAINT pk_project PRIMARY KEY (prid),#实体完整性CONSTRAINT fk_project_tid FOREIGN KEY (tid) REFERENCES type(tid), #参照完整性CONSTRAINT check_dates CHECK (date2 > date1)#用户自定义完整性
);

2)对项目表(project)创建一个索引(按项目号降序),索引的名字是index_prid

学生表(student)创建一个索引(按学号降序),索引的名字是index_sid

CREATE INDEX index_prid ON project(prid DESC);  
CREATE INDEX index_sid ON student(sid DESC);  

图4 建立索引成功

3)设大创项目参与学生位次为1(即表prorank里的rankpr为‘1’)的是该项目的负责人,负责人的专业所在学院即该项目所属学院,查询属于“人工智能与数据科学学院”的全部大创项目。

SELECT * FROM project p1
WHERE p1.prid IN(SELECT p2.prid FROM project p2,prorank,student,major,departmentWHERE p2.prid = prorank.pridAND prorank.sid = student.sidAND student.mid = major.midAND major.did = department.didAND prorank.rankpr = 1AND department.dname = '人工智能与数据科学学院');

图5 查询到的智能学院项目结果

4)统计各个年级2021-2023年内创新创业的参加人数,按学号(sid)前两位表示年级。

SELECT LEFT(student.sid, 2) AS grade, COUNT(DISTINCT student.sid) AS '大创参与人数'
FROM student
WHERE EXISTS (SELECT 1 FROM prorank, projectWHERE prorank.prid = project.pridAND YEAR(project.date1) BETWEEN 2021 AND 2023 #date1为立项时间AND prorank.sid = student.sid
)
GROUP BY grade;

图6 各个年级参与大创人数

5)查询2020-2023年内创新创业项目的参加学生人数大于4的学院,并按照参加人数降序排序。

SELECT d.dname AS '学院名称', COUNT(DISTINCT st.sid) AS '参加人数'
FROM department d, major m, student st, project p,prorank pr
WHERE d.did = m.didAND m.mid = st.midAND st.sid = pr.sidAND pr.prid = p.pridAND p.date1 BETWEEN'2020-01-01' AND '2023-12-31'
GROUP BY d.did, d.dname
HAVING COUNT(DISTINCT st.sid) > 4
ORDER BY COUNT(DISTINCT st.sid) DESC;

图7  2020-2023年内创新创业项目的参加学生人数大于4的学院

 6)查询“物联网工程”专业每个学生的论文、软著、专利的分别获得个数。

SELECT s.sid, s.sname, (SELECT COUNT(sp.pid) FROM stupaper sp WHERE sp.sid = s.sid) AS paper_count,(SELECT COUNT(sw.swid) FROM stusoft sw WHERE sw.sid = s.sid) AS software_count,(SELECT COUNT(pt.ptid) FROM stupatent pt WHERE pt.sid = s.sid) AS patent_count
FROM student s
WHERE s.mid IN (SELECT mid FROM major WHERE mname = '物联网工程');

图8 “物联网工程”专业每个学生的成果明细

 7)查询2021-2022年每个学院所有项目的经费总金额,按经费降序排序。(各个项目类型的经费在type表里的money给出,项目归属由项目位次第一的学生所在学院决定)

SELECT department.dname AS 学院名称, SUM(type.money) AS 经费总金额
FROM project, prorank, student, major, department, type
WHERE project.prid = prorank.prid #项目排名第一人即项目负责人,其所在院系即项目所属院系AND prorank.rankpr = '1' AND prorank.sid = student.sid AND student.mid = major.midAND major.did = department.did AND project.tid = type.tidAND project.date1 BETWEEN'2021-01-01' AND '2022-12-31'
GROUP BY department.did
ORDER BY SUM(type.money) DESC;

图9 2021-2022年每个学院所有项目的经费总金额

8)查询所有项目的论文、软著、专利产出个数,并给出总数,按项目号降序排序。

SELECT project.prid AS 项目号,project.prname AS 项目名称,(SELECT COUNT(DISTINCT pid) FROM paper WHERE paper.prid = project.prid) AS 论文产出个数,(SELECT COUNT(DISTINCT swid) FROM swcopyright WHERE swcopyright.prid = project.prid) AS 软著产出个数,(SELECT COUNT(DISTINCT ptid) FROM patent WHERE patent.prid = project.prid) AS 专利产出个数,(SELECT COUNT(DISTINCT pid) FROM paper WHERE paper.prid = project.prid) + (SELECT COUNT(DISTINCT swid) FROM swcopyright WHERE swcopyright.prid = project.prid)+ (SELECT COUNT(DISTINCT ptid) FROM patent WHERE patent.prid = project.prid) AS 产出总数
FROM project
#由于prid为字符型,使用CAST函数转为整型排序
ORDER BY CAST(project.prid AS UNSIGNED);

图10 所有项目的论文、软著、专利产出个数及总数

 9)创建一个视图viewdepartment1,要求显示各个项目项目号、项目名称、所在学院、立项时间、论文产出个数、软著产出个数、专利产出个数、产出总数、指导老师姓名。

CREATE VIEW viewdepartment1 AS
SELECT project.prid AS 项目号,project.prname AS 项目名称,(SELECT department.dnameFROM prorank,student,major,departmentWHERE project.prid = prorank.pridAND prorank.sid = student.sidAND student.mid = major.midAND major.did = department.didAND prorank.rankpr = 1    #按项目第一名学生所在学院决定项目归属) AS 所属学院,project.date1 AS 立项时间,(SELECT COUNT(DISTINCT pid) FROM paper WHERE paper.prid = project.prid) AS 论文产出个数,(SELECT COUNT(DISTINCT swid) FROM swcopyright WHERE swcopyright.prid = project.prid) AS 软著产出个数,(SELECT COUNT(DISTINCT ptid) FROM patent WHERE patent.prid = project.prid) AS 专利产出个数,(SELECT COUNT(DISTINCT pid) FROM paper WHERE paper.prid = project.prid) + (SELECT COUNT(DISTINCT swid) FROM swcopyright WHERE swcopyright.prid = project.prid)+ (SELECT COUNT(DISTINCT ptid) FROM patent WHERE patent.prid = project.prid) AS 产出总数,(SELECT GROUP_CONCAT(teacher.`name` SEPARATOR ',')FROM teacher,project_teacher WHERE teacher.teaid = project_teacher.teaidAND project.prid = project_teacher.prid) AS 指导老师
FROM project     
#由于prid为字符型,使用CAST函数转为整型排序
ORDER BY CAST(project.prid AS UNSIGNED);

本题解释:由于“指导老师”项在一个项目中可能存在多个匹配项,直接SELECT teacher.`name` 后提示创建视图失败。通过查阅资料,选择使用GROUP_CONCAT()函数成功解决该问题,将多个老师姓名字段拼接为一个,以逗号分隔。

视图结果如下所示:

图11 视图viewdepartment1结果

10) 创建一个视图viewstudent1,要求显示2023年内“人工智能与数据科学学院”各个学生学号、学生姓名、所在专业、发表论文篇数、登记软著个数、拥有专利个数、获得总数。其中时间按各个论文、软著、专利的发表/登记/申请时间为准。

CREATE VIEW viewstudent1 AS
SELECT student.sid AS 学号,student.sname AS 姓名,major.mname AS 所在专业,
(
SELECT COUNT(stupaper.pid) FROM stupaper,paper
WHERE stupaper.sid = student.sidAND stupaper.pid = paper.pidAND paper.pdate BETWEEN '2023-01-01' AND '2023-12-31'
) AS 发表论文篇数,
(
SELECT COUNT(stusoft.swid) FROM stusoft,swcopyright
WHERE stusoft.sid = student.sidAND stusoft.swid = swcopyright.swidAND swcopyright.swdate BETWEEN '2023-01-01' AND '2023-12-31'
) AS 登记软著个数,
(
SELECT COUNT(stupatent.ptid) FROM stupatent,patent
WHERE stupatent.sid = student.sidAND stupatent.ptid = patent.ptidAND patent.ptdate1 BETWEEN '2023-01-01' AND '2023-12-31'
) AS 拥有专利个数,
(
SELECT COUNT(stupaper.pid) FROM stupaper,paper
WHERE stupaper.sid = student.sidAND stupaper.pid = paper.pidAND paper.pdate BETWEEN '2023-01-01' AND '2023-12-31') +(SELECT COUNT(stusoft.swid) FROM stusoft,swcopyrightWHERE stusoft.sid = student.sidAND stusoft.swid = swcopyright.swidAND swcopyright.swdate BETWEEN '2023-01-01' AND '2023-12-31')+(SELECT COUNT(stupatent.ptid) FROM stupatent,patentWHERE stupatent.sid = student.sidAND stupatent.ptid = patent.ptidAND patent.ptdate1 BETWEEN '2023-01-01' AND '2023-12-31') AS 获得总数
FROM student,major,department
WHERE student.mid = major.midAND major.did = department.didAND department.dname = '人工智能与数据科学学院'
ORDER BY (student.sid) DESC;

图12 视图viewstudent1结果

 11)   在学生表(student)中插入一条记录,学号21XXXX,姓名XXX,专业为物联网工程。对插入的记录进行查看。

INSERT INTO student(sid,sname,mid) #插入记录
VALUES (21XXXX,'XXX',
(SELECT major.mid FROM major WHERE major.mname = '物联网工程'));
#查看结果
SELECT*FROM student WHERE student.sname ='XXX';

12)更新11题所插入的记录,将“XXX”记录的comment更新为“本实验作者”。对更新的这条记录进行查看。 

#更新操作
UPDATE student
SET comment = '本实验作者'
WHERE student.sname = 'XXX';
#查看结果
SELECT*FROM student WHERE student.sname ='XXX';

13)删除学生表中“XXX”的记录。 

#删除操作
DELETE FROM student
WHERE student.sname = 'XXX';
#查看结果
SELECT*FROM student WHERE student.sname ='XXX';

执行查询语句后发现该条记录已不存在,删除成功。

图15 删除后,查询不到该记录

14)创建“admin”用户,为其创建一个管理员角色,授予其查看所有表及修改项目

表(project)、学生表(student)老师表(teacher)的权限。

CREATE USER 'admin'@'localhost' IDENTIFIED WITH mysql_native_password BY '123456';
CREATE role role_admin;
GRANT SELECT ON TABLE department TO role_admin;
GRANT SELECT ON TABLE major TO role_admin;
GRANT UPDATE,SELECT ON TABLE student TO role_admin;
GRANT SELECT ON TABLE type TO role_admin;
GRANT UPDATE,SELECT ON TABLE project TO role_admin;
GRANT SELECT ON TABLE paper TO role_admin;
GRANT SELECT ON TABLE patent TO role_admin;
GRANT SELECT ON TABLE swcopyright TO role_admin;
GRANT UPDATE,SELECT ON TABLE teacher TO role_admin;
GRANT SELECT ON TABLE prorank TO role_admin;
GRANT SELECT ON TABLE project_teacher TO role_admin;
GRANT SELECT ON TABLE stupaper TO role_admin;
GRANT SELECT ON TABLE stusoft TO role_admin;
GRANT SELECT ON TABLE stupatent TO role_admin;
GRANT role_admin TO 'admin'@'localhost';
#激活角色 
SET DEFAULT role ALL TO 'admin'@'localhost';

15)验证admin的权限是否分配成功。以admin用户名登录数据库,修改project表里“基于深度学习的图像识别与分类算法研究”项目的立项时间(date1)为2021-09-19,结项时间(date2)为2023-09-29;尝试修改type表,观察有何输出。

首先,以admin用户名登录数据库。

图16  admin登录数据库

然后,先查询修改前的“基于深度学习的图像识别与分类算法研究”项目的信息,然后进行UPDATE操作,最后查看修改后的结果。

#查看更新前结果
SELECT * FROM project 
WHERE project.prname = '基于深度学习的图像识别与分类算法研究';
#更新操作
UPDATE project
SET project.date1 = '2021-09-19',project.date2 = '2023-09-29'
WHERE project.prname = '基于深度学习的图像识别与分类算法研究';
#查看更新后的结果
SELECT * FROM project 
WHERE project.prname = '基于深度学习的图像识别与分类算法研究';

操作前后结果对比如下,成功实现更新。

图17 操作前数据

图18 更新后数据

尝试以admin用户修改项目类型type表,修改国家级项目经费为50000:

UPDATE type
SET type.money = 50000
WHERE type.tname = '国家级';

 由于没有给admin授予更新type表的权限,更新失败,满足第14题的权限分配。

图19 admin无更新type表权限

16)回收admin从角色获得的权限,删除角色,并对比回收前后admin的权限变化。

#查看回收前admin的权限
SHOW GRANTS FOR 'admin' @'localhost';
#回收admin从角色获得的权限
REVOKE role_admin FROM 'admin' @'localhost';
#删除角色
DROP role role_admin;
#查看回收后admin的权限
SHOW GRANTS FOR 'admin' @'localhost';

图20 回收权限前admin的权限

图21 回收权限后admin的权限

 17)定义一个存储过程 proc1,计算所有学生的综合加分,并记录在学生表中comment内。这里只给论文、专利、软著排名为第一(排名在stupaper、stupatent、stusoft表中存在)的学生加分,并且论文加2分,专利加1分,软著加0.5分,执行这个存储过程。

DELIMITER $$
DROP PROCEDURE IF EXISTS proc1;
CREATE PROCEDURE proc1()
BEGINDECLARE sid_val INT;DECLARE done INT DEFAULT 0;DECLARE comment_str VARCHAR(20);DECLARE score FLOAT;-- 声明绑定结果的游标DECLARE student_cursor CURSOR FOR SELECT sid FROM student;-- 声明异常处理程序DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;OPEN student_cursor;read_loop: LOOPFETCH student_cursor INTO sid_val;IF done THENLEAVE read_loop;END IF;SET score = 0;-- 判断论文是否排名第一SET @paper_count := (SELECT COUNT(*) FROM stupaper WHERE sid = sid_val AND rankpa = 1);IF @paper_count > 0 THENSET score = score + 2;END IF;-- 判断专利是否排名第一SET @patent_count := (SELECT COUNT(*) FROM stupatent WHERE sid = sid_val AND rankpt = 1);IF @patent_count > 0 THENSET score = score + 1;END IF;-- 判断软著是否排名第一SET @soft_count := (SELECT COUNT(*) FROM stusoft WHERE sid = sid_val AND ranksw = 1);IF @soft_count > 0 THENSET score = score + 0.5;END IF;-- 将得分值转换为字符串类型,并更新学生表中的comment字段SET comment_str = CAST(score AS CHAR);UPDATE student SET comment = comment_str WHERE sid = sid_val;END LOOP;CLOSE student_cursor;
END$$
DELIMITER ;
CALL proc1();#执行存储过程

执行后student表结果如下图所示,comment成功更新为加分的分数。

图22 存储过程 proc1执行后student表结果

18)定义一个存储过程 proc2,计算2021-2023年所有学院的大创项目的结题成果数量(包括论文、专利、软著),将总数量大于15的学院的备注(comment)标注为“优秀大创组织单位”,执行这个存储过程。

DROP PROCEDURE IF EXISTS proc2;
DELIMITER //
CREATE PROCEDURE proc2()
BEGINDECLARE did_temp CHAR(10);DECLARE count_temp INT;DECLARE done INT DEFAULT 0;DECLARE cur1 CURSOR FORSELECT DISTINCT m.didFROM prorank pr, project p, student s, major mWHERE pr.rankpr = 1AND pr.sid = s.sidAND p.prid = pr.pridAND s.mid = m.midAND p.date2 BETWEEN '2021-01-01' AND '2023-12-31';DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;OPEN cur1;read_loop: LOOPFETCH cur1 INTO did_temp;IF done THENLEAVE read_loop;END IF;SELECT COUNT(*) INTO count_tempFROM paper pa, patent pt, swcopyright sw, project p, student s, prorank pr, major m, department dWHERE (pa.prid = p.prid OR pt.prid = p.prid OR sw.prid = p.prid)AND p.prid = pr.pridAND pr.sid = s.sidAND s.mid = m.midAND m.did = d.didAND p.date2 BETWEEN '2021-01-01' AND '2023-12-31'AND d.did = did_temp;IF count_temp > 15 THENUPDATE departmentSET comment = '优秀大创组织单位'WHERE did = did_temp;END IF;END LOOP;CLOSE cur1;
END//
DELIMITER ;
CALL proc2();

图23 存储过程proc2执行后department表结果

19)定义一个存储过程 proc3,计算2021-2023年所有大创项目的结题成果数量(包括论文、专利、软著),将产出总数量大于15的项目指导老师的备注(comment)标注为“优秀指导老师”,执行这个存储过程。

DROP PROCEDURE IF EXISTS proc3;
DELIMITER //
CREATE PROCEDURE proc3()
BEGINDECLARE prid_val CHAR(10);DECLARE teaid_val INT;DECLARE proj_count INT;DECLARE comment_val VARCHAR(20);DECLARE done BOOLEAN DEFAULT FALSE;DECLARE cur CURSOR FORSELECT prid, teaid FROM project_teacher WHERE prid IN (SELECT prid FROM project WHERE YEAR(date2) BETWEEN 2021 AND 2023);DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;OPEN cur;read_loop: LOOPFETCH cur INTO prid_val, teaid_val;IF done THENLEAVE read_loop;END IF;SET proj_count = (SELECT COUNT(*) FROM (SELECT pid FROM paper WHERE prid = prid_val AND YEAR(pdate) BETWEEN 2021 AND 2023UNION ALLSELECT ptid FROM patent WHERE prid = prid_val AND YEAR(ptdate1) BETWEEN 2021 AND 2023UNION ALLSELECT swid FROM swcopyright WHERE prid = prid_val AND YEAR(swdate) BETWEEN 2021 AND 2023) AS result_count);IF proj_count > 15 THENSET comment_val = '优秀指导老师';UPDATE teacher SET comment = comment_val WHERE teaid = teaid_val;END IF;END LOOP;CLOSE cur;
END //
DELIMITER ;
-- 执行存储过程
CALL proc3();

图24 存储过程proc3执行后teacher表结果

20)创建一个学生分数表(score),包括学号,分数,备注。(只给论文、专利、软著排名为第一(排名在stupaper、stupatent、stusoft表中存在)的学生加分,并且论文加2分,专利加1分,软著加0.5分)。建完表后上定义三个AFTER INSERT触发器,当插入论文、专利、软著记录时,学生的分数自动修改,保持数据一致性。

首先,建立score表:

CREATE TABLE score (sid INT,score DECIMAL ( 5, 2 ),COMMENT VARCHAR ( 20 ),PRIMARY KEY ( sid ),
FOREIGN KEY ( sid ) REFERENCES student ( sid ) 
);

 然后,插入score表数据:

INSERT INTO score (sid, score)
SELECT student.sid,(SELECT COALESCE(SUM(CASE WHEN rankpa = 1 THEN 2 ELSE 0 END), 0) FROM stupaper WHERE stupaper.sid = student.sid) +(SELECT COALESCE(SUM(CASE WHEN rankpt = 1 THEN 1 ELSE 0 END), 0) FROM stupatent WHERE stupatent.sid = student.sid) +(SELECT COALESCE(SUM(CASE WHEN ranksw = 1 THEN 0.5 ELSE 0 END), 0) FROM stusoft WHERE stusoft.sid = student.sid) AS score
FROM student;

其中,COALESCE 函数用于处理子查询中的求和结果。如果求和结果为 NULL,COALESCE 函数将其替换为 0,以确保计算分数时不会出现 NULL 值。

定义触发器:

检验触发器功能:

#查询200001学生的分数

SELECT * FROM score WHERE score.sid =200001;
#插入一条记录
INSERT INTO paper(pid) VALUES('PA371');
INSERT INTO stupaper(sid,pid,rankpa) VALUES(200001,'PA371',1);
#显示结果
SELECT * FROM score WHERE score.sid =200001;
#插入一条记录
INSERT INTO patent(ptid,ptno) VALUES('PT892',12121);
INSERT INTO stupatent(sid,ptid,rankpt) VALUES(200001,'PT892',3);
#显示结果
SELECT *  FROM score WHERE score.sid =200001;
#插入一条记录
INSERT INTO swcopyright(swid) VALUES('SW793');
INSERT INTO stusoft(sid,swid,ranksw) VALUES(200001,'SW793',2);
#显示结果
SELECT *  FROM score WHERE score.sid =200001;

由下图可知,触发器实现了相应的功能,即只有插入论文/专利/软著位次为1时,才会自动修改分数。

图25 insert触发器功能验证

21)根据第20题,设计三个before delete 触发器,实现删除相应记录时,学生的分数也自动扣除。

CREATE TRIGGER update_score_pa_before
BEFORE DELETE ON stupaper
FOR EACH ROW
BEGINIF OLD.rankpa = 1 THENUPDATE scoreSET score = score - 2WHERE sid = OLD.sid;END IF;
END;
CREATE TRIGGER update_score_pt_before
BEFORE DELETE ON stupatent
FOR EACH ROW
BEGINIF OLD.rankpt = 1 THENUPDATE scoreSET score = score - 1WHERE sid = OLD.sid;END IF;
END;
CREATE TRIGGER update_score_sw_before
BEFORE DELETE ON stusoft
FOR EACH ROW
BEGINIF OLD.ranksw = 1 THENUPDATE scoreSET score = score - 0.5WHERE sid = OLD.sid;END IF;
END;验证触发器功能:#查询200001学生的分数
SELECT * FROM score WHERE score.sid =210033;
#删除stupaper
DELETE FROM stupaperWHERE stupaper.sid = 210033 AND stupaper.rankpa = 1;
#查询200001学生的分数
SELECT * FROM score WHERE score.sid =210033;
#删除stupatent
DELETE FROM stupatentWHERE stupatent.sid = 210033 AND stupatent.rankpt =1;
#查询200001学生的分数
SELECT * FROM score WHERE score.sid =210033;
DELETE FROM stusoftWHERE stusoft.sid = 210033 AND stusoft.ranksw =1;
#查询200001学生的分数
SELECT * FROM score WHERE score.sid =210033;

图26 delete触发器验证

由上图可知,将‘210033’的所有排名第一的成果都删除后,其分数自动归零,验证了触发器的功能。

4.实验心得

   通过本次实验,我对数据库设计的流程和办法有了清晰的认识,并且在自己建表、写数据的过程中体会到了完整性约束的意义;在绘制E-R图时,我考虑方便查询,保留了数据冗余,在编程解决问题时验证了我这一想法的正确性,使得查询项目的产出成果更加方便;我更加熟悉了MySQL语句的编写,并且在自己解决问题时,查阅资料发现了GROUP_CONCATCOALESCE()等平时讲课没有用过的函数的便利性;我对复杂问题使用了存储过程和触发器,并且在存储过程中使用了游标,进一步加强了我对存储过程和触发器的认识。

        另外,设计表格时缺少考虑学生的加分这一属性,所以我在后期处理时,用存储过程直接将加分放到学生表里comment中;在实现触发器时,新建了一个grade表,圆满完成了实验。

http://www.lryc.cn/news/2385463.html

相关文章:

  • 电磁场与电场、磁场的关系
  • Python爬虫实战:研究Newspaper框架相关技术
  • Kotlin MultiPlatform 跨平台版本的记账 App
  • PIO 中的赋值魔术,MOV 指令
  • [docker]更新容器中镜像版本
  • 第十七次CCF-CSP算法(含C++源码)
  • 打造一个支持MySQL查询的MCP同步插件:Java实现
  • 黑马k8s(十五)
  • Axure项目实战:智慧运输平台后台管理端-订单管理1(多级交互)
  • 解决 cursor 中不能进入 conda 虚拟环境
  • 微信小程序请求扣子(coze)api的例子
  • C++ 实现二叉树的后序遍历与中序遍历构建及层次遍历输出
  • 基于大模型的髋关节骨关节炎预测与治疗方案研究报告
  • qiankun解决的问题
  • JavaScript从入门到精通(一)
  • 快速失败(fail-fast)和安全失败(fail-safe)的区别
  • 虚拟环境中的PyQt5 Pycharm设置参考
  • AI 笔记 - 模型优化 - 注意力机制在目标检测上的使用
  • AUTOSAR图解==>AUTOSAR_SRS_LIN
  • UML 时序图 使用案例
  • 华为昇腾使用ollama本地部署DeepSeek大模型
  • 多态的总结
  • Windows 高分辨率屏幕适配指南:解决界面过小、模糊错位问题
  • tvalid寄存器的理解
  • C++八股 —— 手撕定时器
  • K8S-statefulset-mysql-ha
  • 【方案分享】展厅智能讲解:基于BLE蓝牙Beacon的自动讲解触发技术实现
  • web常见的攻击方式有哪些?如何防御?
  • 力扣:《螺旋矩阵》系列题目
  • 发电厂进阶,modbus TCP转ethernet ip网关如何赋能能源行业