数据库实验二全流程:ER图设计、关系模式转换与SQL实操详解

发布时间:2026/10/13 9:50:44

数据库实验二全流程:ER图设计、关系模式转换与SQL实操详解 数据库这门课学到实验二这个节点算是真正开始上手干活了。如果实验一还在跟创建数据库、建个简单表较劲那实验二个人版要面对的基本就是一套完整的数据库设计流程再加SQL实操。很多同学做到这里会觉得东西突然变多其实拆开看核心就两件事把现实世界的业务规则翻译成关系模型再用SQL把关系模型落地成能跑的表和数据。这篇文章我按自己做实验的完整顺序来讲把每一步为什么要这么干、干了有什么效果、坑在哪里都说清楚。1. 实验整体设计与需求拆解实验二个人版名目上虽然是“个人版”但它考核的内容一点都不缩水。个人版的核心限制通常体现在数据规模和数据来源上——不需要像团队项目那样接多人协同、并发控制、复杂权限这些数据量也是自己可控的几十条到几百条级别。但正因为它是一个人独立完成整个数据库设计从需求分析到逻辑设计、物理设计、实施维护每一环都得你自己把关反而是把数据库设计的全流程走一遍的最佳时机。1.1 核心需求解析我的实验题是做一个“学生选课管理系统”这个题目在数据库实验里属于经典中的经典因为实体间的关系足够典型学生Student和课程Course是多对多关系中间必须靠选课记录SC来衔接同时选课记录里还承载着成绩Grade这个关键属性。题目要求拆解下来大致是这么几点数据库名选一个有意义的名字比如StudentCourseDB。表数量至少三张核心表学生表、课程表、选课表。字段要求每张表要有主键字段类型合理能够体现完整性约束。数据操作插入、修改、删除、查询都要覆盖查询部分要包含多表连接、分组统计、排序等常用操作。进阶要求加分项视图、索引、存储过程、事务处理等。这里有个容易被忽略的点就是为什么要用选课表而不是直接给学生表加一个“课程ID”字段。如果只考虑一个学生选一门课那直接加字段确实省事但现实是一个学生可以选多门课一门课也有多个学生选这就构成了多对多联系。多对多联系在关系模型中不能直接用两张表的外键表示必须拆出第三张表这张表叫“联系表”或“中间表”里面同时存放学生外键和课程外键再附上这个联系特有的属性比如成绩、选课时间。1.2 方案选型与设计思路数据库管理系统我选了SQL Server来练习。也有同学用MySQL或者SQLite各有优势。SQL Server的图形化界面在实验阶段比较友好建表、设计约束、看执行计划都可以点点鼠标完成对初学者来说能减少很多挫败感。而且实验环境的数据库引擎就是它保持一致方便调试。如果是自己电脑上装开发版跟学校实验室的环境也基本一致。表结构设计上我的初始方案是这样的学生表 StudentSno学号主键、Sname姓名、Ssex性别、Sage年龄、Sdept系别。课程表 CourseCno课程号主键、Cname课程名、Cpno先修课号、Ccredit学分。选课表 SCSno外键、Cno外键、Grade成绩。实体属性为什么这样取舍背后是有讲究的。比如学生表里学号用字符型而不是数值型因为学号虽然长得像数字但它不参与任何算术运算而且可能存在前导零的情况如果用整数类型前导零会被自动吞掉学号就失真了。再比如性别这种字段用CHAR(1)加检查约束就够了不需要搞成定长字符串更不用说用大文本类型。这些都是实验里面老师不会明说、但实际操作中一定会遇到的选择。设计完成后下一步就是把这些设计思想落到实体关系图上也就是常说的 ER 图。2. 概念结构与逻辑结构设计从 ER 图到关系模式数据库设计最怕上来就写建表语句。哪怕题目只要求你去实施你也要先在纸上把实体、属性和联系理清楚。很多实验报告写到最后发现逻辑矛盾比如明明是多对多却只建了两张表根本原因都是跳过了概念设计这一步直接写 SQL。2.1 ER 图设计要点ER 图里包含实体、属性和联系三要素符号约定是矩形表示实体、椭圆表示属性、菱形表示联系。学生选课系统的 ER 图核心是两个实体、一个联系学生实体学号、姓名、性别、年龄、系别。课程实体课程号、课程名、先修课号、学分。“选修”联系一个学生可以选择多门课一门课可以被多个学生选择所以是 M:N 联系。这个联系本身有属性“成绩”因为成绩既不属于学生也不属于课程它是选这个动作产生的结果只能挂在联系上。画 ER 图时要特别注意联系上的属性最容易漏。我当时就漏掉了成绩属性先把它画成了课程的属性后来发现如果成绩挂在课程上那所有选这门课的同学成绩都一样这显然不对。成绩必须挂在“选修”联系上因为不同学生同一门课的成绩不同同一学生不同课程的成绩也不同。这一改后面建表结构就顺了。2.2 关系模式转换与范式验证ER 图转换成关系模式有固定的规则实体转成关系表属性转成字段实体的标识符作为主键。1:N 联系可以将“1”这一侧的主键放到“N”这一侧的关系中作为外键。M:N 联系必须独立转换成一张新的关系表表的主键是两端实体的主键组合。所以选课表的主键是SnoCno联合主键因为一个学生的选课记录里只有学号和课程号合在一起才能唯一定位一条选课记录。成绩字段放在选课表中符合前面 ER 图的逻辑转换规则。转完关系模式要用范式理论检验设计质量1NF所有属性都是不可再分的原子值这一点只要不把多个值塞进一个字段就满足。2NF在 1NF 基础上消除非主属性对码的部分函数依赖。选课表里主键是SnoCnoGrade 对这个联合主键是完全依赖的因为只有当 Sno 和 Cno 都确定Grade 才能确定。这里要注意的是不能让某个非主属性只依赖主键的一部分比如如果把课程名放到选课表里那课程名只依赖 Cno这就是部分依赖违反 2NF会产生数据冗余和更新异常。3NF消除传递函数依赖。比如在学生表里加一个“系办公室电话”字段它依赖“系别”而“系别”依赖“学号”这就是传递依赖应该把系别单独拆成一张系表或者至少将系别信息独立存放。我们课程里的三张表设计都符合 3NF这是数据库设计的基本及格线。高于这个标准的进一步拆分会增加查询复杂度实验阶段做到 3NF 就够了。2.3 为什么主键和外键的设计如此关键主键和外键是关系数据库的骨架它们的正确性直接决定了数据的完整性和一致性。主键要满足两个特性唯一性和非空性。学号是学生表的主键任何两个学生的学号不能相同也不允许为空。联合主键SnoCno则由两个字段共同保证唯一性任何一个字段单独都不足以唯一标识一条记录。外键的作用是维护引用完整性。选课表中的 Sno 必须是学生表里真实存在的学号Cno 必须是课程表里真实存在的课程号否则就出现选了课但学生不存在的情况这在逻辑上是不允许的。数据库管理系统会在你定义外键约束后自动检查这些规则不满足条件的插入和删除会直接报错。这是关系型数据库区别于文本文件最核心的一个能力。外键设计时还要考虑一个问题删除父表记录时子表记录怎么办实验阶段一般用默认的 禁止删除 策略即学生表里有人选过课就不允许直接删这个学生必须先把选课记录删干净。也可以设计成级联删除删学生时自动把他的选课记录一起删掉。两种策略各有适用场景实验报告里最好能说明你选择某种策略的理由。3. 物理实现建库建表与完整性约束落地概念设计和逻辑设计完成后终于可以动手敲 SQL 了。建库建表看起来是最机械的步骤但里面藏着的细节足够让大部分人改上好几轮。3.1 建库与建表语句的核心细节创建数据库这一步比较简单但有几个命名和配置上的习惯值得养成CREATE DATABASE StudentCourseDB; GO USE StudentCourseDB; GO如果你的实验环境是 SQL ServerGO是批处理分隔符意味着前面的语句作为一个批次提交。USE语句则是切换当前上下文告诉数据库引擎接下来在哪个库里面操作。这两句是后续所有操作的起点。建表语句有讲究我最初版本是这样写的CREATE TABLE Student ( Sno CHAR(10) PRIMARY KEY, Sname VARCHAR(20) NOT NULL, Ssex CHAR(2) DEFAULT 男 CHECK (Ssex IN (男,女)), Sage TINYINT, Sdept VARCHAR(30) );几个细节说明一下Sno CHAR(10)学号用定长字符串长度按实际学号的位数来定。定长 CHAR 比变长 VARCHAR 在检索时略快特别是主键经常被拿来等值查询时。Sname VARCHAR(20)姓名用变长因为不同人的名字长度不一样用定长会浪费空间。Ssex CHAR(2)加 CHECK 约束让数据库来把关性别的合法性不合法数据根本进不来。Sage TINYINT年龄用 TINYINT 而不是 INT因为正常学生年龄在 0~255 之间TINYINT 一个字节就够了省空间而且语义明确。课程表和选课表定义时要注意先修课这个字段它是自引用外键CREATE TABLE Course ( Cno CHAR(6) PRIMARY KEY, Cname VARCHAR(50) NOT NULL, Cpno CHAR(6), Ccredit NUMERIC(3,1) CHECK (Ccredit 0), FOREIGN KEY (Cpno) REFERENCES Course(Cno) ); CREATE TABLE SC ( Sno CHAR(10), Cno CHAR(6), Grade DECIMAL(4,1) CHECK (Grade 0 AND Grade 100), PRIMARY KEY (Sno, Cno), FOREIGN KEY (Sno) REFERENCES Student(Sno), FOREIGN KEY (Cno) REFERENCES Course(Cno) );自引用外键在课程表里表示“这门课的先修课是哪门”先修课的课程号必须是课程表中已有记录的课程号这个约束可以保证不会出现先修课不存在的脏数据。建表顺序也容易踩坑。必须先建父表再建子表因为子表的外键引用了父表的主键。如果先建 SC 表它会找不到 Student 和 Course 表而直接报错。同理删除表的时候顺序反着来先删子表再删父表。3.2 数据类型选择的经验与禁忌实验报告中常出现的数据类型选择问题集中在几个点上字段场景错误示例正确做法原因学号INTCHAR(10)学号不参与运算可能有前导零性别VARCHAR(20)CHAR(2)CHECK长度够用即可约束保证合法值成绩INTDECIMAL(4,1)可能有小数如 87.5年龄INTTINYINT够用且省空间课程名TEXTVARCHAR(50)TEXT 不适合做等值/排序场景很多人会习惯性把所有字符字段都定义成 VARCHAR(255)省事是真省事但带来的问题是数据库无法有效约束数据长度而且在索引场景下过长的变长字段会影响索引性能。设计字段类型时的一条黄金准则是够用就好能短不长能用约束就不裸奔。3.3 完整性约束的实施细节约束是数据库保护数据质量的最后一道防线它比应用程序里做校验更可靠因为任何客户端绕过应用直连数据库时约束依然生效。SQL Server 里约束分这么几类主键约束 PRIMARY KEY唯一且非空自动创建唯一索引。默认值约束 DEFAULT不显式提供值时的备用值。检查约束 CHECK限定取值范围。外键约束 FOREIGN KEY限定引用来源。唯一约束 UNIQUE字段值不允许重复但允许单个 NULL。定义约束有两种方式建表时内联定义或者建表后通过ALTER TABLE追加。我建议在建表语句里直接写全一方面结构清晰一目了然另一方面也避免刚建完表就插入数据却发现约束漏了的情况。ALTER TABLE SC ADD CONSTRAINT FK_SC_Sno FOREIGN KEY (Sno) REFERENCES Student(Sno);这种方式适合后期补充约束。但如果你是在实验过程中发现表结构已经建好、数据已导入再追加约束时如果已有数据不满足约束条件数据库会直接报错不会帮你清理数据。所以先想清楚约束再建表比事后修补省事得多。4. SQL 实操增删改查与进阶功能的完整实现表建好之后就到了数据操作环节。实验二通常要求你把增删改查、多表连接、分组统计、视图、索引这些内容都做一遍。这部分代码量大而且每类操作都有它的注意事项。4.1 基础数据操作INSERT、UPDATE、DELETE 的书写规范插入数据时可以先往 Student 表插入几条测试数据。生产中插入数据要注意字段顺序严格按表结构来写避免省略字段列表导致数据错位。更稳妥的方式是显式列出字段名INSERT INTO Student (Sno, Sname, Ssex, Sage, Sdept) VALUES (2024001, 张三, 男, 20, 计算机系); INSERT INTO Student (Sno, Sname, Ssex, Sage, Sdept) VALUES (2024002, 李四, 女, 19, 计算机系);批量插入可以用合并写法注意 SQL Server 和老版 MySQL 的语法不同SQL Server 从 2008 开始支持表值构造函数可以用多行 VALUES 一次性插入多条INSERT INTO Course (Cno, Cname, Cpno, Ccredit) VALUES (C001, 数据库原理, NULL, 4), (C002, 数据结构, C001, 3), (C003, 操作系统, C002, 3);这里注意到一个点Cpno对 C001 是 NULL因为数据库原理这门课没有先修课。NULL 表示未知而不是空字符串。这两者的区别在关系数据库里非常关键后者是长度为 0 的字符串前者是什么都没有它参与逻辑运算时的结果通常是 UNKNOWN而不是 TRUE 或 FALSE。修改数据用 UPDATE必须带 WHERE 条件否则会更新全表。这是所有数据库开发者踩过的最深的坑之一。我在实验时故意练习了一下不带条件的 UPDATE然后立刻用 SELECT 看了一眼全表数据发现所有学生的系别全变成了同一个这种错误如果发生在真实生产环境后果不堪设想。所以养成习惯执行 UPDATE 和 DELETE 之前先用同条件的 SELECT 看一眼影响范围确认无误再执行。删除数据的规则更严格因为外键的存在直接删父表记录可能报错DELETE FROM Student WHERE Sno 2024001;如果这个学生有选课记录SQL Server 会返回外键冲突错误拒绝删除。正确做法是先删除选课表中对应的记录再删除学生记录。这也是现实中常用的处理逻辑——先清理子表再动父表。4.2 查询语句从单表查询到多表连接查询是 SQL 的精华所在也是实验二考核的重头戏。单表查询比较简单重点讲两个容易出错的地方一是 WHERE 条件的书写顺序虽然逻辑上条件顺序不影响结果但要注意 AND、OR 的优先级问题。OR 会破坏条件组合产生意料之外的结果。SELECT Sno, Grade FROM SC WHERE Cno C001 AND Grade 60 OR Cno C002 AND Grade 60;上面这个查询看起来是要找 C001 或 C002 中及格的学生但实际执行的逻辑是(CnoC001 AND Grade60) OR (CnoC002 AND Grade60)如果这就是意图那没问题。但如果你想找的是两个课都及格那就得用括号明确优先级。括号在 SQL 里不是可选项而是语义的一部分。二是模糊查询的通配符。LIKE %数据%表示包含“数据”二字的字符串%代表任意长度字符串_代表单个字符。通配符使用起来很方便但它会阻止索引的使用在大表上性能会很差。实验数据量小感觉不出来但要养成一个意识能用等值查询就别用模糊查询。多表连接查询是重点。内连接只返回两个表中匹配的记录SELECT Student.Sno, Student.Sname, Course.Cname, SC.Grade FROM Student INNER JOIN SC ON Student.Sno SC.Sno INNER JOIN Course ON SC.Cno Course.Cno;左外连接LEFT JOIN则保留左表所有记录右表没有匹配就返回 NULLSELECT Student.Sno, Student.Sname, SC.Cno, SC.Grade FROM Student LEFT JOIN SC ON Student.Sno SC.Sno;这个查询可以找出所有学生包括那些没有选任何课的学生他们的 Cno 和 Grade 会是 NULL。这在统计选课覆盖率时非常有用。连接查询最容易犯的错误是漏掉连接条件导致笛卡尔积。比如忘了写ON SC.Sno Student.Sno结果会是学生数和选课记录数的乘积数据多到让你怀疑人生。排查这种问题时先看结果的行数是否合理再逐步加条件缩小范围。4.3 聚合、分组与排序的常见误区分组统计是实验二的必考内容典型需求如“查询各门课程的选课人数和平均成绩”SELECT Cno, COUNT(*) AS 选课人数, AVG(Grade) AS 平均成绩 FROM SC GROUP BY Cno;GROUP BY 有个铁律SELECT 中出现的非聚合列必须出现在 GROUP BY 子句中。刚才的查询如果改成SELECT Cno, Sno, COUNT(*) ... GROUP BY CnoSno 不在分组里数据库会直接报错。如果数据库允许你写那它返回的 Sno 也是不确定的没有任何意义。HAVING 和 WHERE 的分工问题也经常搞混。WHERE 在分组前过滤行HAVING 在分组后过滤组SELECT Cno, AVG(Grade) AS 平均成绩 FROM SC WHERE Grade IS NOT NULL GROUP BY Cno HAVING AVG(Grade) 60;这个查询先排除成绩为空的行然后按课程分组最后只保留平均成绩在 60 分以上的组。执行顺序是 WHERE 先于 GROUP BYHAVING 后于 GROUP BY理解这个顺序对排查错误至关重要。排序用 ORDER BY注意多字段排序的优先级先排第一个字段相同再排第二个SELECT Sno, Cno, Grade FROM SC ORDER BY Sno ASC, Grade DESC;4.4 视图、索引与存储过程的实操要点视图是虚拟表它不存储数据只是一条保存的查询语句。实验里创建视图的意义在于展示你对逻辑数据独立性的理解。比如创建一个“计算机系学生选课成绩视图”CREATE VIEW CS_Student_Grade AS SELECT Student.Sno, Student.Sname, Course.Cname, SC.Grade FROM Student JOIN SC ON Student.Sno SC.Sno JOIN Course ON SC.Cno Course.Cno WHERE Student.Sdept 计算机系;创建完视图后可以像查表一样查询它。视图的一个实用场景是权限控制比如给助教一个视图他只能看成绩但不能看其他敏感字段。另一个场景是简化复杂查询把固定的连接逻辑封装起来业务侧直接查视图就行。索引这块实验要求不高但理解它的原理很有价值。索引就像书的目录没有目录时要一页页翻有目录就能直接定位。在 SELECT 频繁的字段上建索引在 UPDATE/DELETE/INSERT 频繁的字段上要谨慎建索引因为每次写操作都要同步更新索引反而拖慢性能。实验里可以演示一下创建和维护索引的语法CREATE INDEX idx_SC_Grade ON SC(Grade);注意主键和外键字段在 SQL Server 里默认会自动建立索引不需要手动重复创建。手工创建索引时不要建立在数据区分度很低的字段上比如性别这种只有“男”“女”两值的字段索引帮助不大。这个经验在真实工作中非常实用。存储过程是实验的可选加分项它的核心价值在于封装业务逻辑。比如实现一个“根据学号查询学生已修学分总数”的存储过程CREATE PROCEDURE GetTotalCredits Sno CHAR(10) AS BEGIN SELECT Student.Sno, Student.Sname, SUM(Course.Ccredit) AS 总学分 FROM Student JOIN SC ON Student.Sno SC.Sno JOIN Course ON SC.Cno Course.Cno WHERE Student.Sno Sno GROUP BY Student.Sno, Student.Sname; END;调用存储过程用EXEC GetTotalCredits 2024001。存储过程和视图的区别在于它不仅能查询还能执行包含事务的复杂逻辑比如选课操作检查学分、检查先修课、插入选课记录可以放在一个存储过程里通过事务保证一致性。5. 常见问题与排查技巧实录实验做得再顺利也免不了遇到一些让人头疼的报错。这里把我在实践中遇到的典型问题整理成速查清单几乎每个数据库初学者都会碰到。5.1 常见报错信息速查表报错现象根本原因解决方案建表失败提示外键不存在子表先于父表创建先建父表再建子表或先建表后加外键插入数据报主键重复主键字段重复或未设自增检查主键字段值是否重复必要时清空表重插删除父表记录报冲突子表存在引用该记录的外键先删除子表相关记录再删父表或改用级联删除UPDATE 影响行数远大于预期漏写 WHERE 条件立即回滚事务或从备份恢复养成先 SELECT 再 UPDATE 的习惯分组查询报错列不在 GROUP BY违反分组规则将非聚合列加入 GROUP BY或去掉该列中文乱码数据库/表/列字符集不一致建库时统一使用简体中文兼容的字符集模糊查询查不到结果使用了中文通配符而非英文百分号检查%是否为英文半角符号视图创建失败权限不足或查询语句有语法错误检查权限先跑 SELECT 语句验证逻辑5.2 三个最容易踩的隐蔽坑第一个是 NULL 值引发的连锁问题。COUNT(Grade)和COUNT(*)结果可能不一样前者不统计 NULL后者统计全部行。求平均分时如果把缺考学生的成绩设为 NULLAVG自动跳过 NULL结果会偏高。如果要把缺考当成 0 分处理就得用ISNULL或COALESCE函数显式转SELECT AVG(ISNULL(Grade, 0)) FROM SC;第二个是隐式类型转换。比如学号字段是 CHAR(10)而你在查询时传入的是整数 2024001数据库会尝试把整型转换成字符型再比较。数据量小的时候感觉不到数据量大时这种转换会让索引失效查询性能直线下降。保持字段类型和查询参数类型一致是最基本的素养。第三个是外键约束的方向性问题。选课表中 Sno 是学生表主键的引用但它本身也可以被其他表引用。比如如果要建一个“退课记录”表它里面的 Sno、Cno 又要引用选课表里的 Sno、Cno。这种链式引用在删除时会造成联动问题需要格外小心。实验阶段不做这么复杂但要意识到外键关系不是单向的它的维护成本是向两边延伸的。5.3 实验报告的检查清单做完整套实验后正式提交之前我建议按这个清单自查一遍三张表的主键、外键、CHECK、DEFAULT、UNIQUE 约束是否齐全。每张表至少插入 5 条以上有效数据且数据类型符合定义。查询语句是否覆盖了等值查询、范围查询、模糊查询、排序。是否至少包含一个多表连接查询连接条件有没有缺漏。是否包含一个带 GROUP BY 和 HAVING 的分组统计查询。是否创建了至少一个视图并用视图执行了一次查询。是否说明了索引选择的理由不能为了建索引而建索引。删除操作是否体现了外键约束的引用完整性不能全表删除。所有 SQL 语句都能重新连贯执行不要有粘贴一半的情况。这个清单其实就是实验考核评分点的映射。数据库实验的分数差异往往不是差在代码量上而是差在这些规范性和完整性细节上。建了三张表但没有外键约束和建了三张表但约束完备同样的问题看上去差不多得分差距却是档次性的。6. 深度扩展从实验二通向真实项目开发的三个关键认知实验二做完数据库原理这门课最核心的技术点基本都过了一遍。但站在一个从业者角度回头看这个实验我想补三个可能超出课程要求、但对后续开发非常有价值的认知。6.1 事务管理为什么实验里没用到但生产里离不开事务是数据库保证数据一致性的核心机制。先修课、状态修改、选课扣学分等操作真实的业务场景中都是多条 SQL 一起执行比如“扣库存生成订单更新余额”任何一步失败整个操作都应该回滚不能出现库存扣了但订单没生成的情况。实验里的数据量小单条语句失败了大不了删掉重来。但真实系统中必须把所有关联操作包在事务里BEGIN TRANSACTION; UPDATE SC SET Grade 90 WHERE Sno 2024001 AND Cno C001; UPDATE Student SET Sage Sage 1 WHERE Sno 2024001; COMMIT TRANSACTION;中间任何一句报错执行ROLLBACK TRANSACTION就能回滚到事务开始之前。这个机制在并发场景下尤其重要多个用户同时操作同一份数据时事务的隔离级别决定了你能否避免读到脏数据或幻读。6.2 日志与备份从删库到跑路的距离只有一条命令做实验时一条DROP DATABASE就能让三张表全部消失你只需要用脚本重新建库建表几分钟就恢复。但在真实环境数据库里存的是用户数据、订单记录、财务流水一次误操作可能就是灾难。实验阶段养成一个习惯关键操作之前先备份。在 SQL Server 里备份只需要一句BACKUP DATABASE StudentCourseDB TO DISK D:\backup\StudentCourseDB.bak;恢复也简单RESTORE DATABASE StudentCourseDB FROM DISK D:\backup\StudentCourseDB.bak;有备份兜底很多操作你才敢放手去做。这个习惯比学多少 SQL 技巧都重要。6.3 索引思维查询优化从实验阶段就要建立实验数据量小一条没索引的查询也是毫秒级返回你根本察觉不到性能差异。但真实生产环境千万行级别的表没有索引的查询可能从毫秒变成几十秒接口直接超时。理解索引核心是理解 B 树和主键索引与非主键索引的区别。主键索引聚簇索引决定了数据在磁盘上的物理存储顺序非主键索引二级索引保存的是主键值查到后再回表取数据。这也是为什么建议主键用自增整数而不是随机字符串的原因之一自增让新数据追加写入而不是随机插入减少页分裂提升写入性能。实验里建索引时可以故意对比一下有索引和没索引的执行计划差异这个习惯会让你在以后写复杂查询时主动去想这个 WHERE 条件能不能用索引函数包裹字段后索引还能不能用前缀查询用 LIKE abc% 能用索引LIKE %abc 就用不了。这些知识课本上有但只有亲手实践过印象才真正深刻。写在最后这个实验二做下来最大的体会是数据库设计像盖房子需求分析是打地基ER 图是画图纸建表和 SQL 才是砌砖。很多人一上来就砌砖地基没打牢图纸也没画最后房子歪了都不知道问题在哪。认真把 ER 图画明白、把关系模式转换规则吃透、把三种范式验证走一遍后面写 SQL 完全是水到渠成的事。再分享一个小技巧实验过程中所有 SQL 脚本都用文本文件保存下来按“建库、建表、插入、查询、视图、存储过程”分节存放每执行成功一段就在头部加一行注释说明这段的用途。提交实验时直接把脚本文件附上报告里对应截图也方便。更重要的是你自己的脚本以后做复习或者面试前手写 SQL翻出来就是一份极好的资料比临时翻书高效得多。数据库这门课实验二是一个真正的分水岭。跨过它你对“数据”二字的理解就不再是 Excel 表格而是一套有约束、有关系、有逻辑的系统工程。后面的实验还有权限管理、并发控制、数据库恢复这些更深入的内容但基础打在这里后面每一步都会顺很多。
延伸阅读

更多相关文章

2026/10/13 9:50:44

低压配电网WLS状态估计器设计与性能优化

1. 项目背景与核心问题低压配电网作为电力系统的"最后一公里",其运行状态直接影响终端用户的供电质量。单相接地故障是低压电网中最常见的故障类型之一,但由于低压电网结构复杂、测量点分散、环境干扰大,传统监测方法往往难以准确定…

2026/10/13 11:01:05

C++数组指针字符串:从内存视角彻底搞懂核心难点

我知道很多人第一次翻开郑莉这本《C语言程序设计》,到第六章"数组、指针和字符串"就开始心里打鼓。说实话,我当年也是这样:前面的流程控制、函数调用,照着抄总能写出来,可数组和指针一上来,什么&…

2026/10/13 11:01:05

智能PDU:从车间排插到智慧工厂电力神经中枢

1. 先聊聊为什么车间里要装“智能排插”前阵子去一个做汽车零部件的工厂看产线改造,走到车间角落的配电柜旁边,正好看到一位老师傅拿着红外测温枪对着一个满负载的插线板在测温度。那个插线板上插着三台设备的电源,线缆摸上去已经有些发烫了&…

2026/10/13 11:01:05

OpenClaw跨平台安装指南:让《Captain Claw》在现代系统重生

前几天整理旧硬盘,翻出一个十年前的游戏存档文件夹,里面还躺着那只猫船长的记录。我试着双击当年的老游戏程序,Win11下直接黑屏闪退,连个报错都不给。正想放弃,朋友提了一句:“有没有试过OpenClaw&#xff…

2026/10/13 11:01:05

2026计算机职业规划:产品思维与新兴技术赛道

## 1. 计算机专业职业规划的现状与痛点2026年的计算机行业与十年前相比已经发生翻天覆地的变化。当我在某985高校计算机系担任企业导师时,发现超过70%的应届生仍在使用2015年的职业规划模板——这就像用Windows XP的操作手册来指导Windows 12的安装。最典型的认知偏…

2026/10/13 11:01:05

Java+SSM+Flask全栈实现在线奶茶店系统

1. 项目概述:在线奶茶店系统的全栈实现这个基于JavaSSMFlask的网上奶茶店系统,是我为连锁奶茶品牌开发的一套完整的线上销售解决方案。系统采用前后端分离架构,后端使用JavaSSM框架处理核心业务逻辑,Flask则负责轻量级的API服务和…

2026/10/13 10:56:04

三天搞定论文AI率:排查、深度改写与复测全攻略

如果你刷到了这篇文章,大概率正经历同一件事:导师把论文回传过来,批注栏里只有一句话——“AI率太高,自己回去改”,外加一张检测报告截图。2026年了,这已经不是什么新鲜事。随着生成式工具在学术写作里的使…

2026/10/13 5:19:27

Python调用Gemini Structured Outputs实现工单路由门禁

客服工单最怕的不是模型“答错一句话”,而是它给出一段看起来合理的说明,程序却从中猜错优先级。通俗做法是:要求模型只交 JSON(JavaScript Object Notation,轻量数据格式),再让代码验证它。Gem…

2026/10/12 12:01:26

Spring Boot超市进销存系统毕设实战:从需求拆解到答辩通关

最近带的一个学生项目组里,有A同学跑来问我:选什么毕设题目最稳妥,既能让评审老师觉得工作量够,又不会在答辩时被问到语无伦次。我第一反应就是推荐基于Spring Boot的超市仓库管理系统——也就是超市进销存系统。这个题目乍一看平…

2026/10/12 12:54:07

Flutter StatefulWidget 生命周期核心解析

很多刚开始接触 Flutter 的朋友,在看完一堆“Hello World”和基础组件之后,大概率都会撞上同一堵墙:StatefulWidget 里那堆 initState、build、dispose 方法,到底什么时候被调用?为什么顺序是那样?在里面到…

2026/10/13 0:04:41

基于Triton部署YOLO目标检测:从训练脚本到线上服务

简介:这份资源面向希望将目标检测模型落地到生产环境的深度学习开发者与算法工程师,聚焦于用 Triton Inference Server 部署 YOLOv9 的完整实战方案,解决从训练权重到线上推理服务之间的工程化难题。压缩包共 16 个文件,约 886KB&…

2026/10/13 0:04:41

手把手教你云端部署Qwen-Image-2.1:从GPU选型到在线文生图服务

Qwen-Image-2.1 这个开源的图像生成模型,最近在内容创作和 AI 应用圈子里热度相当高。它属于通义 Qwen 系列里的视觉生成分支,让我眼前一亮的是它对中文长文本的理解能力——以前用那些老方案生成带中文文字的图,十个里九个是“乱码印刷体”&…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑