
简介这是一份数据库课程设计完整报告以企业人事管理系统为实战案例系统讲解从需求分析、概念结构设计到逻辑/物理结构设计、视图设计、数据保护与系统实现的全流程。内容覆盖员工、考勤、薪资、用户四类核心数据表并给出字段约束、表结构汇总、密码加密与角色权限等安全设计适合高校计算机相关专业学生完成《数据库应用》期末大作业或课程设计时参考对照。资源共1个doc文档压缩包约2.58MB单文件便于下载后直接查阅、修改和复用。目前已有6645人学习使用可从中获取完整课程设计报告的结构范式、数据库表设计与安全保护方案辅助快速搭建同类人事管理系统的数据库模型。1. 数据库期末大作业怎么抄作业企业人事管理系统这份报告能给你的不止是表结构MySQL 课程设计是最容易翻车也最容易出彩的一门大作业尤其是《数据库应用》期末要交“系统设计报告可运行库”这种组合。这份企业人事管理系统的课程设计报告覆盖了从需求分析、概念结构设计、逻辑结构设计、物理建表到视图、MD5 加密、角色权限和 Python 查询界面的完整链路四张表把员工、考勤、薪资、系统用户四个维度全串起来了。它适合两类人一类是还在纠结“大作业到底要交什么”的在校生照着它的结构能少走一半弯路另一类是刚接触 MySQL 想快速搭一套人事库练手的开发者可以直接拿它的表设计做底子改造成自己的项目。全文最值得细看的不是建表语句本身而是它暴露出来的一组真实设计矛盾——比如密码字段长度和 MD5 密文长度的冲突。2. 从需求到表结构四张表是怎么一步步立起来的2.1 需求分析先定边界信息、处理、安全三类要求各管什么这一章是整个课程设计的起点原文写得比较像课程报告格式但拆开看其实就三件事信息要求、处理要求、安全性与完整性要求。信息要求解决的是“系统里要存什么”员工姓名、工号、部门、职位、学历、身份证号这些是人事系统的基础数据考勤数据涉及日期、通勤、出差、加班薪资数据涉及基本工资、补助、奖金、代扣保险、实发工资用户数据涉及登录账号、密码和权限。处理要求解决的是“用户能对这些数据做什么”增删改查是底线考勤要能统计结算工资要能算实发金额。安全性与完整性要求解决的是“谁有资格碰这些数据”这里原文提到的思路是用户只能通过应用软件访问数据库不能直接操作数据库表同时表与表之间要有合理的关联约束。把这三类要求列完系统边界基本上就清楚了。原文在需求分析末尾给了一张功能结构图功能模块大概分为员工信息管理、考勤管理、薪资管理、系统用户管理四个方向这四个方向后来直接映射成了四张表。这里有个经验做课程设计最容易犯的错是一上来就写建表语句写到一半发现字段不够用或者表之间关联不上回头再改需求分析就要动一堆东西。先花半天把需求边界划清楚后面写表结构会顺很多。2.2 概念结构与逻辑结构实体、属性和关系模式怎么落地概念结构设计在原文里没有展开太多只用了实体描述来交代但从逻辑结构设计的内容可以反向推出来员工实体对应员工表考勤实体对应考勤表薪资实体对应薪资表用户实体对应用户表。这四个实体之间是有天然关联的员工和考勤是一对多关系一个员工有多条考勤记录员工和薪资也是一对多关系一个员工在不同结算周期有多条工资记录用户和员工是一对一关系一个用户账号绑定一个员工身份和职位。逻辑结构设计就是把上面的概念实体转成关系模式。原文列的关系模式有几个值得注意的细节员工关系里有“员工姓名、工号、性别、身份证号、出生日期、年龄、民族、邮箱、学历、毕业学校、所学专业、入职时间、部门名称、部门编号、职位、司龄”考勤关系里有“员工姓名、工号、日期、通勤、出差、加班”薪资关系里有“工资编号、员工姓名、工号、基本工资、补助、奖金、代扣保险、实发工资”用户关系里有“用户名、用户密码、用户权限、员工姓名、职位”。这就是典型的关系模式一个实体一张表实体之间用共享字段比如工号来建立关联。这里我一般会补充一个建模习惯关系模式的字段名最好和物理表结构的列名保持一一对应避免设计文档一套名字、建表时另一套名字。原文在这一点上其实做得不算好——逻辑设计里用中文描述物理设计里用 Sname、Sno、IDcard 这种英文列名答辩时老师一问“Sname 是什么的缩写”答不上来就尴尬了。所以如果你要引用这份设计建议在自己报告里加一张字段对照表把中文属性和英文列名映射列清楚。2.3 从 ER 图到关系模式的转换规则一对多、多对一怎么处理概念结构到逻辑结构的转换是有固定套路可循的。一对一关系可以选择把一方的外键放到另一方表中比如用户表和员工表可以在 Puser 表里放 Sname 和 Job 两个字段来关联员工一对多关系一般在多的一方放外键比如考勤表里放 Sno 来指向员工表薪资表里也可以放 Sno 指向员工表。原文的逻辑结构设计里每个关系都出现了“员工姓名”和“工号”这对组合这其实反映了课程设计里常见的一个问题为了查询方便在子表里冗余了父表的多个字段。理论上考勤表只需要工号 Sno 作为外键姓名 Sname 可以通过 JOIN 从 Staff 表拿但为了减少联表查询原文把姓名也冗余进去了。这种做法在数据量小、性能不是瓶颈的课程设计里可以接受但要在报告里写明“这是为了提高查询效率做的设计决策”否则会被当成范式没学扎实。3. 物理结构设计与建表 SQL四张表全量拆解3.1 Staff 员工表身份证号做主键、工号加唯一约束的真实考量Staff 表是整套系统的核心表原文给出的字段列表里有 15 列从 Sname 到 jage覆盖了员工基本信息的方方面面。建表时约束条件的设置逻辑很有意思Sno 工号标了 UniqueIDcard 身份证号标了 Unique 且作为主键 Primary Key。也就是说工号不重复、身份证号不重复且是主键。这在逻辑上是说得通的——身份证号天然唯一适合做逻辑主键工号虽然也唯一但业务上可能会调整所以只做唯一约束不做主键给未来留了修改余地。建表 SQL 大概是这样的CREATE TABLE Staff ( Sname CHAR(10) NOT NULL COMMENT 员工姓名, Sno CHAR(5) NOT NULL UNIQUE COMMENT 员工工号, Ssex CHAR(1) NOT NULL COMMENT 员工性别, IDcard CHAR(18) NOT NULL PRIMARY KEY COMMENT 身份证号, Birthday DATE NOT NULL COMMENT 出生日期, Sage SMALLINT NOT NULL COMMENT 年龄, Snation CHAR(10) NOT NULL COMMENT 民族, Mail CHAR(40) NOT NULL COMMENT 邮箱, Education CHAR(10) NOT NULL COMMENT 学历, School CHAR(20) NOT NULL COMMENT 毕业学校, Sdept CHAR(20) NOT NULL COMMENT 所学专业, Etime DATE NOT NULL COMMENT 入职时间, Dname CHAR(20) NOT NULL COMMENT 部门名称, Dno CHAR(5) NOT NULL COMMENT 部门编号, Job CHAR(20) NOT NULL COMMENT 职位, jage CHAR(10) NOT NULL COMMENT 司龄 ) COMMENT员工基本信息表;建表逻辑说明主键选了 IDcard 而不是 Sno这个取舍值得展开。身份证号在业务上永远唯一且不会变更作为主键稳定工号虽然也唯一但企业换工号体系的情况不算罕见比如组织架构调整后重新编号如果拿工号做主键后续牵一发动全身所有关联表的外键都要改。所以原文把工号设为 UNIQUE 约束保留唯一性但不让它承担主键职责这是合理的设计。Sage 年龄和 jage 司龄两个字段是冗余存储年龄可以从 Birthday 算出来司龄可以从 Etime 算出来这个后面避坑章再细说。3.2 Attendance 考勤表日期用 Char(10)、主键设计的取舍Attendance 表原文列了 5 个字段Sname、Sno、Adate、Ac、Business、Overtime补充说明里的中文含义写的是姓名、编号、月份、在岗天数、加班天数、出差天数。这里有个明显的问题补充说明的顺序和字段顺序对不上而且 Adate 的注释到底是“月份”还是“日期”原文前后说法不一致。物理结构设计里 Adate 的类型是 Char(10)补充说明里写的是“月份”但逻辑结构设计里写的是“日期”。建表 SQL 按照 MySQL 8.0 的语法可以写成这样CREATE TABLE Attendance ( Sname CHAR(10) NOT NULL COMMENT 员工姓名, Sno CHAR(5) NOT NULL COMMENT 员工工号, Adate CHAR(10) NOT NULL COMMENT 考勤日期, Ac SMALLINT NOT NULL COMMENT 在岗天数, Business SMALLINT NOT NULL COMMENT 出差天数, Overtime SMALLINT NOT NULL COMMENT 加班天数, PRIMARY KEY (Sno, Adate) ) COMMENT员工考勤表;参数说明Sno 不单独做 UNIQUE因为一个员工会有多条考勤记录单值唯一没有意义主键采用 Sno 和 Adate 的组合语义是“同一个员工同一天的考勤记录只有一条”这在人事场景里是合理约束。Adate 用 CHAR(10) 存日期匹配 2025-06-03 这种固定长度写法查询时字符串比较也直观但缺点是无法用 MySQL 的日期函数直接做区间运算需要 STR_TO_DATE 转换。SMALLINT 字段用来存天数最大 32767 足够。这里如果你把表里的某列设成了 PRIMARY KEY 但列定义里没写 UNIQUEMySQL 会自动加上如果像原文那样一列同时标了 UNIQUE 和 PRIMARY KEY也不会报错但语义上有冗余。实际建表时要注意一个表只能有一个 PRIMARY KEY但可以有多个 UNIQUE。3.3 Salary 薪资表工资编号主键与工号唯一约束的取舍Salary 表原文有 8 列SaNo、Sname、Sno、Bp、Subsiby、bonus、Insurance、pay对应工资编号、姓名、工号、基本工资、补助、奖金、代扣保险、实发工资。这里主键选了 SaNo 工资编号Sno 加了 Unique 约束。这个设计的逻辑是一个月发一次工资一个员工一条工资记录所以 Sno 天然唯一加 UNIQUE 约束保证数据层面不会出现同一个人有两条月工资记录SaNo 作为逻辑主键和业务解耦方便未来调整。但这里有一个容易踩的坑原文在逻辑结构设计里明确写了“员工薪资工资编号员工姓名工号基本工资补助奖金带扣保险实发工资”注意原文写的是“带扣保险”而不是“代扣保险”同音错别字。你在自己的报告里如果直接复制粘贴这段答辩时会被挑出来。建表时字段名建议统一用小写加下划线或者驼峰原文的 bonus 是小写开头其他字段是驼峰风格混搭。建表语句参考CREATE TABLE Salary ( SaNo CHAR(5) NOT NULL PRIMARY KEY COMMENT 工资编号, Sname CHAR(10) NOT NULL COMMENT 员工姓名, Sno CHAR(5) NOT NULL UNIQUE COMMENT 员工工号, Bp CHAR(10) NOT NULL COMMENT 基本工资, Subsiby CHAR(10) NOT NULL COMMENT 补助, bonus CHAR(10) NOT NULL COMMENT 奖金, Insurance CHAR(10) NOT NULL COMMENT 代扣保险, pay CHAR(10) NOT NULL COMMENT 实发工资 ) COMMENT员工薪资表;这里的设计我持保留意见工资相关字段用的是 CHAR(10)不是 DECIMAL。CHAR 类型存数字会带来两个问题——排序时按字典序排9999 会排在 10000 前面做数值运算时 MySQL 会做隐式转换性能不是问题但可读性差。课程设计里用 CHAR 存工资数字能通过因为数据量小如果是真实项目DECIMAL(10,2) 才是标准答案。你在自己的设计文档里如果保留 CHAR要准备好解释为什么不用 DECIMAL哪怕理由只是“题目要求的”。3.4 Puser 用户表六位密码字段是全文最大的隐患Puser 表原文只有 4 列uname、Upassword、Authority、Sname、Job。等一下原文标题写的是 4 个字段但实际上列了 5 个——uname、Upassword、Authority、Sname、Job补充说明写的是“编号、密码、权限、姓名、职位”。这是文档里的又一笔糊涂账字段列表 4 个实际列了 5 个编号到底对应 uname 还是另有字段没写清楚。从数据保护设计的描述来看密码是要做 MD5 加密的。MD5 加密后的密文是 32 位十六进制字符串但原文给 Upassword 定的类型是 CHAR(6)。这个长度根本存不下 MD5 输出——一旦插入时用了 MD5() 函数字符串会被截断到 6 位登录时用 MD5 算出来的 32 位密文和库里存的 6 位密文永远对不上这就是典型的“设计与实现脱节”。CREATE TABLE Puser ( uname CHAR(5) NOT NULL PRIMARY KEY COMMENT 用户名, Upassword CHAR(32) NOT NULL COMMENT 密码(MD5密文), Authority CHAR(10) NOT NULL COMMENT 用户权限, Sname CHAR(10) NOT NULL COMMENT 员工姓名, Job CHAR(20) NOT NULL COMMENT 职位 ) COMMENT系统用户表;注意这里我把 Upassword 改成了 CHAR(32) 来容纳 MD5 密文同时加了注释标明存储的是密文。如果你要做登录校验SQL 大概是WHERE uname xxx AND Upassword MD5(输入密码)。MD5 虽然现在不算安全的加密算法但作为课程设计演示“密码不存明文”这个理念完全够用了。原文档里还有一张图提到插入时用 md5() 函数加密配合这建表语句就能自洽。4. 视图与数据保护MD5 加密、角色权限和查询隔离的落地方式4.1 视图设计把身份证、工资这类敏感字段从日常查询里拆出去原文视图设计部分没有给出具体 SQL只讲了思路不同职位的人看同一个数据时角度不同普通员工不应该看到其他人的私密信息所以要通过视图把敏感字段过滤掉。这是一个典型的安全设计手段——视图层做列级权限控制比在应用层拼查询条件更可靠。按原文的思路可以做三个视图。第一个是员工基础信息视图把身份证号、出生日期这些敏感字段去掉只保留姓名、工号、性别、部门、职位给普通员工用CREATE VIEW v_emp_basic AS SELECT Sname, Sno, Ssex, Dname, Dno, Job FROM Staff;第二个是薪资查询视图把员工姓名、工号、基本工资、补助、奖金、实发工资暴露出来但隐藏工资编号和代扣保险明细给财务和部门主管用CREATE VIEW v_salary_detail AS SELECT s.Sname, s.Sno, sa.Bp, sa.Subsiby, sa.bonus, sa.pay FROM Staff s JOIN Salary sa ON s.Sno sa.Sno;第三个是考勤统计视图把考勤表汇总成按月统计的报表给人事部用来做月度结算CREATE VIEW v_attendance_month AS SELECT Sno, Sname, SUBSTRING(Adate, 1, 7) AS month, SUM(Ac), SUM(Business), SUM(Overtime) FROM Attendance GROUP BY Sno, Sname, SUBSTRING(Adate, 1, 7);视图的逻辑说明第一个视图解决了“员工只能看同事的基本信息看不到身份证号”的需求第二个视图通过 JOIN 把员工表和薪资表关联起来让高层可以在一个视图里直接看到员工薪资概况第三个视图用 SUBSTRING 截取年月做分组把流水明细聚合成月度报表。这里用视图而不是直接建汇总表的好处是数据实时同步不会出现汇总数据过期问题——代价是每次查询都要实时聚合数据量大时视图会成为性能瓶颈课程设计场景下完全没问题。4.2 MD5 密码加密原理、插入语句和长度匹配问题原文在数据保护设计里明确写了用 MD5() 对密码加密还配了插入语句的示意图。原理是用户注册时输入明文密码插入数据库前用 MD5() 函数算成 32 位十六进制密文存进去用户登录时再次对输入值做 MD5拿结果和库里存的密文比对。这样即使数据库文件泄露拿到手的也只是密文无法直接反推明文。插入加密后的用户数据参考写法INSERT INTO Puser (uname, Upassword, Authority, Sname, Job) VALUES (admin, MD5(123456), admin, 张三, 人事经理);执行逻辑MD5(123456) 在 MySQL 里直接返回 32 位十六进制字符串比如 e10adc3949ba59abbe56e057f20f883e这条插入语句写入 Puser 表的是密文而不是明文。这里要特别注意如果 Upassword 字段是 CHAR(6)MySQL 在插入时不会报错但会把密文静默截断成前 6 位 e10adc下次登录用 MD5(123456) 算出的完整密文和库里的 6 位密文比对必然失败。这个坑前面提过这里再强调一次字段长度和加密算法输出长度必须匹配。MD5 是 32 位SHA-1 是 40 位SHA-256 是 64 位建表前先定好加密方案再定字段类型。4.3 角色与权限GRANT 授权语句与“权限全部放开”的补救思路原文角色权限部分给了一张表角色 A 对 Staff、Attendance、Salary、Puser 四张表都有 delete、update、select、insert 权限但实际上没有细化到每个角色的差异化授权。原文自己在系统实现部分也承认了想把不同职位的用户权限分开但因为建表和用户创建操作不熟练最后把所有数据的增删改查都授权给了所有用户。这个问题的本质是没理解 MySQL 的用户和权限体系。正确的做法是先创建角色再给角色授权最后把角色分配给用户。如果你只想让普通员工只能查询员工基础信息视图、不能直接操作底层表可以这样写-- 创建只读用户并授权视图查询 CREATE USER readonly_userlocalhost IDENTIFIED BY readonly123; GRANT SELECT ON company_db.v_emp_basic TO readonly_userlocalhost; -- 创建人事管理员并授权增删改 CREATE USER hr_userlocalhost IDENTIFIED BY hr123456; GRANT SELECT, INSERT, UPDATE, DELETE ON company_db.Staff, company_db.Attendance, company_db.Salary TO hr_userlocalhost; FLUSH PRIVILEGES;权限分配场景说明只读用户只能查视图连底层表都看不到这比在应用里加一堆判断条件要安全得多人事管理员有实体表的写权限但 Puser 表不给他权限避免管理员能改自己的密码和权限。原文做了第一步——用户登录后才能操作数据库但没做好第二步——不同用户操作范围不同。如果你在自己的课程设计里把这两步都做全答辩时就是一个加分项。5. 避坑与常见问题课程设计翻车现场的五条血泪记录5.1 密码字段长度不够导致 MD5 密文被截断现象按原文 Puser 表设计建表后插入用户数据时明明写了 MD5(123456)但登录时用同样的 MD5 值去查死活查不到匹配记录。原因Upassword 字段类型是 CHAR(6)MD5 密文有 32 位。MySQL 在插入时不会因为字符串超长而报错非严格模式下而是直接截断存进去的只有前 6 位。登录时拿完整 32 位密文去和 6 位密文比永远不相等。这个坑不显眼因为插入和查询都“成功”了只是结果不对。解决把 Upassword 字段长度改到 CHAR(32)然后重新插入用户数据。建表时就要先想清楚加密方案——用 MD5 就留 32 位用 SHA1 就留 40 位用 SHA256 就留 64 位。顺便把非严格模式下的字符串截断告警打开SET sql_mode STRICT_ALL_TABLES以后超长插入会直接报错而不是静默截断能少踩很多类似坑。5.2 主键与 Unique 混用导致建表报错和逻辑混乱现象按原文给 Staff 表同时设置 Sno 和 IDcard 两个 UNIQUE 约束再把 IDcard 设为主键建表执行时报错或者在别的数据库里一个表出现两个主键。原因MySQL 规定一个表只能有一个 PRIMARY KEY但可以有多个 UNIQUE KEY。原文的“Unique\primary key”写法本身有歧义一方面表示 Sno 是 UNIQUE另一方面 IDcard 是 UNIQUE 且是 PRIMARY KEY物理设计文档里是把两列约束混写在一行了照抄容易抄错。解决先想清楚哪一列是逻辑主键。在这个场景里推荐 Sno 做 UNIQUE 约束、IDcard 做 PRIMARY KEY因为身份证号一辈子不变如果你更想用自增主键就加一列id INT AUTO_INCREMENT PRIMARY KEY然后给 Sno 和 IDcard 都设置 UNIQUE KEY。自己的报告里要用表格把每列的主键/唯一约束分开列不要学原文混写。5.3 补充说明和实际字段对不上答辩时被问住现象原文 Staff 表补充说明写“分别代表的是用户名、编号、性别、身份证号…”但实际字段顺序是 Sname姓名、Sno工号、Ssex性别…“用户名”说成“员工姓名”“编号”说成“工号”Adate 到底是日期还是月份前后描述不一致。原因课程设计报告是多人协作写的概念设计、逻辑设计、物理设计各部分可能是不同人完成的术语没有统一。答辩时导师挑刺是小事如果照着错误说明去查数据写 Python 查询界面时字段名对应的中文含义就可能对错列。解决写完报告后做一次“字段一致性核查”把逻辑设计的关系模式、物理设计的表结构、补充说明、系统实现部分的截图四者放在一起逐列对照确保每个字段的中文名、英文列名、类型、约束四处完全一致。特别是复制粘贴别人的模板时这种不一致几乎必然存在认真查一遍就能在答辩前把雷排掉。5.4 权限授太宽违背最小权限原则现象系统实现部分最终把所有表的增删改查权限授予了所有用户也就是说任何登录用户都能删数据、改工资、改自己的密码和权限。安全设计文档写得挺好实现时完全没落地。原因原文作者自己也承认对用户创建和授权操作不熟为了先跑通功能就一刀切地把所有权限给了所有用户。这在课程演示时没问题但和前面数据保护设计部分自相矛盾——设计文档说要做角色权限区分实现却说“所有用户都有所有权限”。解决至少做一个区分——只读用户和可写用户。用CREATE USER创建两个账号只读账号只授 SELECT 权限可写账号才授 INSERT/UPDATE/DELETE。如果时间紧最低限度是别把 Puser 表的权限给普通用户否则登录用户能把别人的密码改掉。5.5 年龄和司龄用冗余字段存储数据更新不同步现象Staff 表里同时有 Birthday、Sage年龄和 Etime、jage司龄。员工过生日后 Sage 不会自动增长员工在职满一年后 jage 也不会自动更新数据永远是过期状态。原因Sage 和 jage 是典型的“可由其他字段推导的冗余字段”。建表时手工录入一次之后没人维护时间一长全部失真。课程设计里要展示“能算出来的字段尽量不存”这个原则这两个字段就是反面教材。解决两个方案任选。一是删掉 Sage 和 jage查询时用 TIMESTAMPDIFF 函数现算SELECT Sname, TIMESTAMPDIFF(YEAR, Birthday, CURDATE()) AS age FROM Staff;。二是保留字段但通过触发器或应用层在写入时自动计算比如插入员工记录时用SET Sage TIMESTAMPDIFF(YEAR, Birthday, CURDATE())。方案一更干净方案二能展示触发器技术各有侧重答辩时选一个讲清楚理由就行。6. 把课程设计再往前推一步Python 查询端的验证与权限细化6.1 用 pymysql 验证视图和权限是否按预期工作原文在系统实现部分提到了 Python 查看功能但只说了实现方式是在 Python 里连接数据库查询数据。一个合格的课程设计应该把“数据库设计”和“界面验证”打通而不只是把表建出来截图。用 Python 验证权限设计是否生效是我常用的收尾操作。import pymysql # 连接 MySQL用只读账号验证视图权限 conn pymysql.connect( hostlocalhost, userreadonly_user, passwordreadonly123, databasecompany_db, charsetutf8mb4 ) cursor conn.cursor() # 只读用户查询员工基础信息视图 cursor.execute(SELECT Sname, Sno, Dname, Job FROM v_emp_basic) for row in cursor.fetchall(): print(row) # 尝试用只读用户访问 Salary 表预期会被拒绝 try: cursor.execute(SELECT * FROM Salary) except pymysql.err.ProgrammingError as e: print(f权限拦截生效: {e})逻辑说明和参数说明第一个查询验证只读账号能正常查视图第二个查询故意对 Salary 表执行 SELECT预期的结果是报权限不足的异常。pymysql.connect里的参数分别是数据库地址、账号、密码、库名和字符集注意charsetutf8mb4可以正确处理中文不加这一项查出来的中文大概率是乱码。这样一条链路下来既验证了视图是真的能查也验证了权限是真的拦得住。6.2 补一个细化的角色权限闭环把设计文档里的承诺兑现原文数据保护设计里写了“每个角色拥有刚好能够完成任务的权限不多也不少”但实现没有跟上。最后的收尾操作就是把这个缺口补上。最常见的做法是分成三个角色普通员工只读视图部门主管能查本部门薪资人事管理员能改员工数据。每个角色建一个数据库账号应用层按登录用户的身份选择账号连接数据库。从那次以后我养成了一个习惯每次大作业做到最后都强制走一遍“查询视图 → 越权访问 → 权限拦截”的三步验证把设计文档里的安全承诺变成可以演示的脚本。很多课程设计吃亏就吃在理论和实现脱节——论文写得再漂亮演示时越权访问没拦住老师一眼就看穿。希望这个验证思路帮到你让你的期末大作业不只是“能跑”而是“经得起问”。# 人事管理员账号写入新员工执行前确认 Staff 表结构一致 conn_hr pymysql.connect( hostlocalhost, userhr_user, passwordhr123456, databasecompany_db, charsetutf8mb4 ) cur conn_hr.cursor() cur.execute( INSERT INTO Staff (Sname, Sno, Ssex, IDcard, Birthday, Sage, Snation, Mail, Education, School, Sdept, Etime, Dname, Dno, Job, jage) VALUES (王五, 10006, 男, 330106199901011234, 1999-01-01, 26, 汉, wangwucompany.com, 本科, 浙江大学, 计算机科学, 2023-07-01, 技术部, T03, 开发工程师, 2) ) conn_hr.commit() cur.close() conn_hr.close()参数说明插入语句里的 Sage 和 jage 是手工算好填进去的这就是冗余字段的维护成本——每次写入都要保证这两个值和其他字段一致。课程设计里为了演示功能可以接受但如果你想让方案更完整可以把这两个字段设计成触发器自动计算或者在 Python 里用 TIMESTAMPDIFF 算好再插入。这个细节一旦在答辩时被问到你能说出“我知道是冗余字段、也知道可以自动化”这一层就已经在大多数同学之上。本文还有配套的精品资源点击获取