资讯详情

资讯详情

研一数据库大作业实战:学生成绩管理系统四表设计与SQL实现

简介这份北京邮电大学研一数据库课程大作业文档面向正在完成数据库原理课程设计的高校学生与自学者围绕学生成绩管理系统给出从需求梳理到建表落地的完整设计思路。内容依次展开功能与数据需求、Course、Student、Sc、Teacher 四张表的结构定义、局部与全局 ER 图、逻辑结构设计与数据字典并写明主外键约束、一对多联系的处理方式以及 CREATE TABLE 等建库建表语句不及格名单统计、没有教学任务的教师查询等教务场景也都有对应的设计方案。压缩包共 1 个 docx 文件约 503KB属于纯文档型资料便于直接打印或改写为实验报告。目前已有 607 人学习下载可作为课程设计阶段的参考框架帮助读者理清 ER 图到关系模式的转换、主键和组合主键的设置以及成绩取值范围等完整性约束的写法。1. 一份研一数据库大作业的真实入口三条教务需求定了系统骨架学生成绩管理系统听着像模板题但某高校研一这份数据库大作业真正难的地方不是把四张表建出来而是把教务科随口说的三句话翻译成能落库的结构授课教师录入成绩、学生自己查成绩、教务处统计各科不及格名单和没有教学任务的教师名单。这三句话直接决定了系统要有四个实体、一张独立的选课成绩联系表以及视图、存储过程、触发器这些看着像加分项、其实是必答题的数据库对象。它适合两类人正在赶数据库课设或大作业、需要一份从需求分析到 SQL 实现的完整文档的同学以及手里已经有题目想照着这套四表结构改成自己版本的人。下面按真实交付顺序拆需求怎么定、E-R 怎么画、表怎么建、对象怎么写、答辩怎么过。2. 需求拆分与概念建模三类角色、四个实体与两处联系怎么落图建模阶段返工成本最高。表建完再改字段前面写的视图、存储过程、触发器全得推倒重来所以这一步我一般会多花半天把需求按角色拆干净再动手画图。2.1 三类角色划出的功能边界教务科给的需求只有四条但每一条背后对应不同的使用者和不同的数据操作权限先按角色归类功能清单才不会漏授课教师录入和修改自己课程的成绩对应sc表的 INSERT / UPDATE 操作写入时必须带合法的cno和sno。学生按学号查询本人各科成绩对应sc与course的联表查询只读。教务处维护学生信息和教师信息统计各科不及格名单查询没有教学任务的教师属于全表读写加聚合统计。课设层面通常不实现真正的登录鉴权和权限控制这一点要提前想清楚并写进文档数据库只负责数据完整性角色权限交给应用层或直接由操作界面区分。把这句话写进需求分析章节答辩时被问权限怎么做就有得答而不是现场卡壳。反过来如果一开始就把四个角色、十几张表都设计进去交付周期内根本做不完最后连核心查询都跑不通这才是最常见的翻车方式。2.2 四个实体与属性抽取从需求里能抽出的实体只有四个属性也不多但每个属性都要能对上后面的表字段学生学号sno、姓名sname、性别ssex、专业smajor、班级sclass。学号是唯一标识长度 9 位够放下一届学生的编号。教师教师号tno、姓名tname、性别tsex、系别tdept。教师号是唯一标识。课程课程号cno、课程名cname、任课教师号tno。成绩学号sno、课程号cno、分数degree取值范围 0 到 100保留一位小数。这里有一处特别容易写错的细节课程表第三列在需求文档里被写成选课人数tno但从字段名tno和后面的插入示例看它实际存的是任课教师号。选课人数是派生数据——某门课有多少人选用COUNT从sc表统计就行绝对不能在课程表里存一个冗余计数。一旦存进去学生退课就得同步修改两个地方漏一次数据就不一致这是典型的反范式误用不是优化。2.3 两处联系选修画成 m:n讲授画成 1:n实体画完接着是联系。系统里有两条关系基数完全不同画错了后面建表就跟着错第一条是学生与课程之间的选修多对多。一个学生选多门课一门课被多个学生选这条联系必须单独转成一张联系表sc(sno, cno, degree)主键取(sno, cno)的组合两个字段又分别是学生表和课程表的外键。成绩这个属性既不属于学生也不属于课程只属于某个学生选某门课这一件事所以只能挂在这张联系表上不能拆到两边。第二条是教师与课程之间的讲授。E-R 图上常被画成多对多理由是一门课可能几个老师合上但落到表结构时course表里只有一个tno字段实际上是按一对多处理的一位教师可以讲多门课一门课只对应一位任课教师。一对多的转换规则很简单——把一端的主键放进多端当外键所以teacher.tno进了course表。这两种画法没有对错只有取舍。要保留一门课多位教师合上的能力就得再拆一张teaching(tno, cno)联系表课程表里不再放tno不拆就老老实实写清楚本系统假设一门课程由单一教师负责。我一般会在文档里明确写出这条假设答辩时老师追问一门课两个老师怎么办回答当前按一对多建模扩展方案是增加授课联系表即可比含糊其辞强得多。提示E-R 图里的联系基数必须和最终表结构一致。图上画 m:n、表里按 1:n 建是这类大作业被扣分的常见原因评审一眼就能看出来。3. 逻辑结构设计四张表的数据字典与第三范式校验概念模型转关系模型这一步交付物是一份能直接照着建表的字段清单外加一段说明为什么这么拆表的范式论证。文档里这两块缺一不可只有表没有论证等于把设计过程藏起来了。3.1 四张表的数据字典数据字典要把字段名、数据类型、长度、小数位、是否允许空、约束说明全部列清楚建表脚本照抄即可。下面这张表是按最终交付版本整理的表名字段类型长度可空说明studentsnochar9否主键学号studentsnamevarchar8是姓名studentssexchar2是取值 男 / 女studentsmajorvarchar20是专业studentsclasschar10是班级teachertnochar3否主键教师号teachertnamevarchar8是姓名teachertsexchar2是取值 男 / 女teachertdeptvarchar16是所属系别coursecnochar5否主键课程号coursecnamevarchar20否课程名coursetnochar3是外键任课教师号scsnochar9否组合主键外键sccnochar5否组合主键外键scdegreedecimal4,1是成绩0 到 100有两处长度必须统一否则外键建不起来sc.sno一定要和student.sno一样是char(9)sc.cno一定要和course.cno一样是char(5)。早期文档里sc.sno写成char(10)和student.sno的 9 位对不上建外键时会直接报错改起来还得先清空数据。这类字符长度不一致的问题最后都归到建表前先对一遍长度这条检查项上。degree用decimal(4,1)而不是float是因为成绩要精确到 0.1 且不能出现 59.9999 这种浮点误差用定点小数比较稳妥。sname用varchar而不是定长char是为了避免姓名不足长度时补空格查询和显示都得额外处理。3.2 函数依赖与第三范式校验范式论证不用写得多深把每张表的函数依赖列出来再说明不存在部分依赖和传递依赖就够了studentsno → sname, ssex, smajor, sclass。主键是单属性不存在部分依赖其余属性都直接依赖sno没有传递依赖满足 3NF。teachertno → tname, tsex, tdept。同理满足 3NF。coursecno → cname, tno。tno直接依赖课程号不存在课程号 → 教师号 → 教师姓名这样的链式依赖因为教师姓名留在teacher表里没有塞进course满足 3NF。sc(sno, cno) → degree。degree依赖的是组合主键整体缺少任何一个都无法确定成绩不存在部分依赖满足 3NF。这里最值得在文档里点一句的是course表如果图省事把教师姓名也放进来形成cno → tno → tname的传递依赖就降到了 2NF。教师改名要改多行一旦漏改就出现同一教师两个名字。拆成两张表改一处即可。这段分析写进文档比单纯写一句本设计满足第三范式有说服力得多。3.3 完整性约束的三层落点约束分三类分别落在不同位置文档里分开写清楚实体完整性靠主键。student主键sno、teacher主键tno、course主键cno、sc组合主键(sno, cno)。组合主键保证同一个学生同一门课只能有一条成绩记录从结构上杜绝重复录入。参照完整性靠外键。sc.sno参照student.snosc.cno参照course.cnocourse.tno参照teacher.tno。参照动作要想明白学生退学删除记录时sc里对应成绩是级联删除还是禁止删除课设里通常选级联删除把孤儿数据一并清掉避免统计时出现查不到学生的成绩记录。用户定义完整性靠取值范围。性别只能是男或女成绩必须落在 0 到 100 之间。这一层在 MySQL 里最容易被忽略因为CHECK约束在 5.5 和 5.7 版本中只是被解析、不会真正生效写上去看着很规范实际一条 120 分的成绩照样能插进去。后面第五章会专门讲这个坑怎么补。4. 物理实现建表约束、视图、存储过程与统计查询的完整落地到这一章就是能直接跑的部分。所有脚本按执行顺序排列先建库、再建被引用的表、最后建引用别人的表顺序反了外键会报错。4.1 建库建表把约束写进 DDL-- 建库统一字符集避免中文姓名乱码 CREATE DATABASE IF NOT EXISTS grade_mgmt DEFAULT CHARACTER SET utf8; USE grade_mgmt; -- 先建 teacher因为 course 要引用它 CREATE TABLE teacher ( tno CHAR(3) NOT NULL COMMENT 教师号, tname VARCHAR(8) NULL COMMENT 姓名, tsex CHAR(2) NULL COMMENT 性别, tdept VARCHAR(16) NULL COMMENT 系别, CONSTRAINT pk_teacher PRIMARY KEY (tno), CONSTRAINT ck_teacher_sex CHECK (tsex IN (男,女)) ) ENGINEInnoDB; CREATE TABLE course ( cno CHAR(5) NOT NULL COMMENT 课程号, cname VARCHAR(20) NOT NULL COMMENT 课程名, tno CHAR(3) NULL COMMENT 任课教师号, CONSTRAINT pk_course PRIMARY KEY (cno), CONSTRAINT fk_course_teacher FOREIGN KEY (tno) REFERENCES teacher(tno) ) ENGINEInnoDB; CREATE TABLE student ( sno CHAR(9) NOT NULL COMMENT 学号, sname VARCHAR(8) NULL COMMENT 姓名, ssex CHAR(2) NULL COMMENT 性别, smajor VARCHAR(20) NULL COMMENT 专业, sclass CHAR(10) NULL COMMENT 班级, CONSTRAINT pk_student PRIMARY KEY (sno), CONSTRAINT ck_student_sex CHECK (ssex IN (男,女)) ) ENGINEInnoDB; -- sc 最后建同时引用 student 和 course CREATE TABLE sc ( sno CHAR(9) NOT NULL COMMENT 学号, cno CHAR(5) NOT NULL COMMENT 课程号, degree DECIMAL(4,1) NULL COMMENT 成绩, CONSTRAINT pk_sc PRIMARY KEY (sno, cno), CONSTRAINT fk_sc_student FOREIGN KEY (sno) REFERENCES student(sno) ON DELETE CASCADE, CONSTRAINT fk_sc_course FOREIGN KEY (cno) REFERENCES course(cno), CONSTRAINT ck_sc_degree CHECK (degree 0 AND degree 100) ) ENGINEInnoDB;建表顺序不是随便排的course的外键指向teachersc的外键同时指向student和course被引用的表必须先存在否则 MySQL 会直接报 1215 错误。存储引擎显式写ENGINEInnoDB是因为只有它支持外键和事务默认引擎虽然通常就是 InnoDB但写死更稳妥。ON DELETE CASCADE加在sc.sno上含义是删学生时他的成绩记录自动清除。如果不加删除学生会因为外键约束失败如果加在sc.cno上删课程也会连带清掉成绩课设阶段通常不这么做因为课程记录一般不允许物理删除。参数上的这个区别要在文档里写清楚答辩问为什么一个加一个不加时就有话讲。至于两个CHECK约束MySQL 5.5 建表时不会报错但插入 120 分也不会被拦住。真正的兜底方案是触发器或应用层校验第五章展开。4.2 视图联表查询封成接口单表视图负责写入视图在课设里通常要演示两个用法一个是把复杂的联表查询封装起来方便复用另一个是借视图向基表插数据。-- 多表联查视图把学生、课程、成绩拼成一张宽表 CREATE VIEW v_student_course AS SELECT s.sno, s.sname, s.sclass, c.cno, c.cname, sc.degree FROM student s JOIN sc ON sc.sno s.sno JOIN course c ON c.cno sc.cno; -- 查某门课的所有选课记录不用再写三表 JOIN SELECT * FROM v_student_course WHERE cname 科学导论;这个视图把三张表的连接逻辑固化下来后续统计某门课多少人不及格可以直接在视图上过滤SQL 短很多。注意它包含 JOIN属于不可更新视图往里 INSERT 会报错只能读。需要演示通过视图写数据时要另建一个单表视图-- 单表、无聚合、无 DISTINCT属于可更新视图 CREATE VIEW view_sc AS SELECT sno, cno, degree FROM sc; -- 借视图插入一条成绩最终落到 sc 基表 INSERT INTO view_sc (sno, cno, degree) VALUES (120210332, C01, 86.0); -- 改视图定义不丢数据只是重新声明列 ALTER VIEW view_sc AS SELECT sno, cno, degree FROM sc WHERE degree IS NOT NULL; -- 用完删掉 DROP VIEW view_sc;可更新视图的判断标准要记牢单张基表、不含聚合函数、不含DISTINCT、不含GROUP BY满足这几条才能 INSERT / UPDATE。ALTER VIEW只改视图定义不影响基表数据DROP VIEW只删视图本身sc表里的数据一条不少。这三点是演示时的标准考点最好在文档里逐条对应说明。4.3 存储过程与触发器把常用查询和删除留痕固化下来存储过程的价值在于把带参数的查询封装成可重复调用的单元。第一个按班级查学生DELIMITER // -- 按班级精确查询学生名单p_class 为入参 CREATE PROCEDURE proc_class_stud(IN p_class CHAR(10)) READS SQL DATA BEGIN SELECT sno, sname, smajor FROM student WHERE sclass p_class ORDER BY sno; END // DELIMITER ;这里有个细节值得说原始写法用的是WHERE sclass LIKE %4412%前导通配符会让索引彻底失效而且语义也不准——班级14412会被%4412%一起匹配进来。改成等值比较参数从调用方传入既走索引又不会误伤。调用方式是CALL proc_class_stud(4412);参数类型要和字段一致传数字会触发隐式转换。第二个存储过程带出参统计某个学生修了几门课DELIMITER // -- 入参学号出参课程门数结果通过 OUT 参数带回 CREATE PROCEDURE num_sc(IN p_sno CHAR(9), OUT p_count INT) READS SQL DATA BEGIN SELECT COUNT(*) INTO p_count FROM sc WHERE sno p_sno; END // DELIMITER ;调用要分两步先执行再取变量CALL num_sc(120210332, cnt); SELECT cnt AS course_count;DELIMITER //的作用是把语句结束符临时从分号改成//否则存储过程体内每条 SQL 后的分号都会被客户端当成过程结束导致创建失败。结束符用完记得改回;这是新手最容易卡住的地方。触发器用来做删除留痕。先建一张结构完整的备份表不要用CREATE TABLE ... SELECT ... WHERE 10那种写法那样建出来的表没有主键也没有约束-- 删除留痕表字段与 student 对齐并记录删除时间 CREATE TABLE delstudent ( sno CHAR(9) NOT NULL, sname VARCHAR(8) NULL, deleted_at DATETIME NULL, CONSTRAINT pk_delstudent PRIMARY KEY (sno, deleted_at) ) ENGINEInnoDB; DELIMITER // CREATE TRIGGER trg_student_after_delete AFTER DELETE ON student FOR EACH ROW BEGIN INSERT INTO delstudent (sno, sname, deleted_at) VALUES (OLD.sno, OLD.sname, NOW()); END // DELIMITER ;FOR EACH ROW表示行级触发OLD.sno取的是被删除那一行的旧值NOW()记录删除时间便于追溯。验证方式很直接DELETE FROM student WHERE sno 120210332;之后查delstudent新记录应该立刻出现。因为sc表加了ON DELETE CASCADE删学生会连带清掉成绩触发器只负责留痕不负责清理职责分得清楚。如果外键没加级联删学生时会先被sc的外键拦住触发器根本不会触发——这是第五章要展开的坑。4.4 索引设计与三条高频统计 SQL索引不是越多越好按查询模式建才有效。系统的查询主要集中在三个方向按课程查成绩、按班级查学生、按分数筛不及格。-- sc 的主键 (sno, cno) 已覆盖按学号查按课程查需要单独的 cno 索引 CREATE INDEX idx_sc_cno ON sc (cno); -- 不及格名单按分数过滤degree 上建索引 CREATE INDEX idx_sc_degree ON sc (degree); -- 教务处按班级查学生 CREATE INDEX idx_student_class ON student (sclass);组合主键(sno, cno)满足最左前缀按sno单独查能走索引按cno单独查走不了所以cno需要补一个单列索引。这是组合索引最常被忽略的一点答辩问为什么主键里已经有 cno 还要再建索引答最左前缀原则就够了。第一条统计各科不及格名单-- 按课程分组输出不及格学生degree 60 SELECT c.cno, c.cname, s.sno, s.sname, s.sclass, sc.degree FROM sc JOIN student s ON s.sno sc.sno JOIN course c ON c.cno sc.cno WHERE sc.degree 60 ORDER BY c.cno, sc.degree;第二条没有教学任务的教师。这里用LEFT JOIN加IS NULL判断比NOT IN更稳-- 左连接后课程号为空说明该教师没有任何授课记录 SELECT t.tno, t.tname, t.tdept FROM teacher t LEFT JOIN course c ON c.tno t.tno WHERE c.cno IS NULL;为什么不用NOT IN因为course.tno允许为空子查询里出现NULL会导致NOT IN整体返回空集这是很隐蔽的坑。LEFT JOIN ... IS NULL对NULL值免疫结果永远可靠。第三条课程维度的汇总统计一张表把选课人数、平均分、不及格人数全带出来-- 课程维度汇总LEFT JOIN 保证没人选的课也能出现在结果里 SELECT c.cno, c.cname, COUNT(sc.sno) AS student_cnt, ROUND(AVG(sc.degree), 1) AS avg_degree, SUM(CASE WHEN sc.degree 60 THEN 1 ELSE 0 END) AS fail_cnt FROM course c LEFT JOIN sc ON sc.cno c.cno GROUP BY c.cno, c.cname ORDER BY fail_cnt DESC;COUNT(sc.sno)而不是COUNT(*)是因为没人选的课程左连接后右边全为NULLCOUNT(*)会算成 1COUNT(字段)只统计非空值结果才对。SUM(CASE WHEN ...)是条件计数在 MySQL 里的标准写法比跑两条 SQL 再手工相减省事。这几条查询跑通需求分析里的四类功能就都有对应实现了。5. 常见问题排查五处最容易在答辩现场被问穿的坑这一章按现象 → 原因 → 解决方案整理都是跑不起来或跑起来但结果不对的真实问题提前踩一遍比现场被追问强。5.1 CHECK 约束写了但拦不住非法数据现象建表时明明写了CHECK (degree 0 AND degree 100)插入一条 150 分的成绩照样成功没有任何报错。原因MySQL 在 5.5 和 5.7 版本中只是解析CHECK子句并不真正执行校验语法合法但约束无效直到 8.0.16 之后才正式支持。解决要么在插入前由应用层判断要么用触发器兜底DELIMITER // CREATE TRIGGER trg_sc_degree_check BEFORE INSERT ON sc FOR EACH ROW BEGIN IF NEW.degree 0 OR NEW.degree 100 THEN SIGNAL SQLSTATE 45000 SET MESSAGE_TEXT 成绩必须在0到100之间; END IF; END // DELIMITER ;BEFORE INSERT保证在写入前拦截SIGNAL SQLSTATE 45000抛出自定义错误信息客户端能看到明确提示。更新成绩也要拦需要再加一个BEFORE UPDATE触发器。文档里把这条写进去说明你知道CHECK在目标版本上的局限比假装它有效要加分。5.2 外键建不起来报 1215 或 1005 错误现象执行ALTER TABLE sc ADD FOREIGN KEY (sno) REFERENCES student(sno);直接失败提示无法添加外键约束。原因有三类一是两边字段类型或长度不一致比如sc.sno是char(10)、student.sno是char(9)二是被引用的列没有索引或不是主键三是字符集不同比如一边utf8一边utf8mb4。解决建表前统一对照数据字典把所有外键字段的类型、长度、字符集和被引用列写成完全一致。长度这一点尤其隐蔽——9 位和 10 位在肉眼里几乎一样只能靠逐字段比对。教师号也有类似问题表里定义char(3)测试数据却塞了 9 位的编号插入时被静默截断成前 3 位外键看着能建关联结果却是错的。测试数据必须和字段长度对齐。5.3 删除学生时报外键冲突或者删完统计冒出孤儿数据现象执行DELETE FROM student WHERE sname 某某;报Cannot delete or update a parent row或者反过来学生删掉了但sc表里还留着这个学号的成绩做统计时这些记录被算进总人数里。原因sc.sno的外键没有指定参照动作。默认是RESTRICT父表删除直接被拒绝如果当初建表时干脆没加外键就会留下孤儿记录。解决建表时明确写ON DELETE CASCADE让成绩跟随学生一起删除如果业务上要求先留档再删就改成先插delstudent备份表、再手动删sc、最后删student三步放在一个事务里START TRANSACTION; INSERT INTO delstudent (sno, sname, deleted_at) SELECT sno, sname, NOW() FROM student WHERE sno 120210332; DELETE FROM sc WHERE sno 120210332; DELETE FROM student WHERE sno 120210332; COMMIT;顺序不能颠倒必须先删子表再删父表否则中途被外键挡住事务回滚前面的备份也白做了。5.4 往视图里插数据报不可插入现象INSERT INTO v_student_course VALUES (...)报错提示视图不可更新但换成view_sc同样的语句就成功了。原因v_student_course是三表 JOIN 的视图列来自多个基表数据库无法确定一条插入该落到哪张表属于不可更新视图。view_sc只来自sc一张表没有聚合、没有DISTINCT是可更新视图。解决写数据一律走单表视图或直接对基表操作联表视图只用来读。文档里最好把可更新视图的四个条件列出来单基表、无聚合函数、无DISTINCT、无GROUP BY。答辩时被问视图能不能当表用按这四条回答再补一句含 JOIN 的视图只读就完整了。5.5 存储过程和触发器创建失败报语法错误现象粘贴一段存储过程代码执行报You have an error in your SQL syntax但看起来每行都没问题。原因有三类一是没写DELIMITER过程体里的分号被客户端当成了语句结束二是FOR EACH ROW被误敲成FOR EACH R0W字母 O 打成数字 0肉眼极难发现三是过程体里有语法正确但权限不足的语句报错信息会误导人。解决创建前先执行DELIMITER //结束后立刻DELIMITER ;恢复粘贴后逐字检查关键字拼写尤其是ROW、BEGIN、END创建完成后用SHOW CREATE PROCEDURE 过程名;或SHOW TRIGGERS;确认对象真的存在别只看客户端提示执行成功就以为完事。命令行和图形化工具对分隔符的处理不完全一致同一段脚本在两边表现可能不同交付前在目标环境里跑一遍最保险。6. 验收与答辩一份 15 分钟能跑完的演示脚本答辩不是把文档念一遍而是当场证明系统能跑、数据对得上、设计有依据。我一般会按固定顺序准备一条演示动线每步都有一条 SQL 和一张预期结果截图中途任何一步失败都能立刻定位到是哪张表的问题。时间演示动作关键语句预期结果0-2 分钟展示四张表结构SHOW TABLES;DESC sc;四张表齐全主外键清晰可见2-4 分钟演示成绩录入与查询INSERT INTO sc ...后SELECT新增记录能查到非法分数被拦4-6 分钟联表视图查询SELECT * FROM v_student_course WHERE cname科学导论;返回学号、姓名、成绩三列6-8 分钟视图写入演示对view_sc执行INSERT基表sc多出一条记录8-10 分钟存储过程调用CALL num_sc(120210332, cnt);出参返回该生课程门数10-12 分钟触发器验证删一个学生后查delstudent备份表出现对应记录12-15 分钟两条教务统计不及格名单 SQL、无教学任务教师 SQL结果条数与手工核对一致演示前有四项必须自查第一所有测试数据的字段长度和表定义严格对齐尤其是学号 9 位、教师号 3 位、课程号 5 位第二每张表至少准备 10 条数据只有两三行数据的统计结果看不出对错也没法证明GROUP BY真的生效第三把删除类操作放在事务里演练一遍确认级联和触发器都按预期工作第四提前想好三个必被追问的问题——为什么sc要单独建表多对多联系必须转独立关系模式、为什么满足第三范式逐表列函数依赖、索引用在哪最左前缀和查询模式。有个细节容易被忽略答辩现场最好用命令行跑一遍核心 SQL再切图形化工具展示数据。图形化工具点两下出结果很快但老师更想看你手写 SQL 的能力两条路都准备口头说明图形界面用于批量录入关键查询用命令行验证反而显得你两种环境都摸过。我头一次交课程设计时所有 SQL 在本地跑得好好的现场换台机器一执行中文全变问号原因是建库时没指定字符集表跟着服务器的默认编码走。从那以后我每交一次数据库作业都会强制自己在一台干净环境里从CREATE DATABASE开始重跑一遍删除、统计、触发器这三条最容易崩的路径各走一次确认无误再交。这套四表结构加视图、存储过程、触发器和统计 SQL 的完整脚本与文档我整理在同一份资源里建库顺序和执行注释都标好了照着替换课程名和班级号就能改成自己的题目。希望帮到你。本文还有配套的精品资源点击获取
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →