news 2026/10/12 1:01:02

数据库课程设计实战:药店管理系统从E-R图到触发器的完整拆解

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
数据库课程设计实战:药店管理系统从E-R图到触发器的完整拆解

简介:数据库课程设计报告-药店管理系统.doc 是一份面向计算机相关专业学生的课程设计范文,以药店管理系统为完整案例,展示数据库设计从需求分析到物理实现的规范流程。报告基于 SQL Server 2008 与 PowerDesigner 工具,详细说明开发背景、信息要求、角色权限、功能模块、数据流图与数据字典;随后依次展开概念结构设计、逻辑结构设计和物理结构设计,包含局部 E-R 图、综合 ER 图、关系模式优化及数据库表结构定义,并覆盖药品进货、上柜、库存查询、销售业绩统计、交接班结处理等典型业务场景。资源为单个 doc 文档,共 1 个文件,压缩包大小 353KB,适合作为课程设计报告模板或数据库建模参考,尤其对需要完成类似管理信息系统设计的初学者有直接帮助。目前已有 673 人学习,读者可参考其章节组织、图表绘制与文字表述,快速搭建自己的课程设计报告框架,节省整理和排版时间。

1. 数据库课程设计报告:药店管理系统这份模板能拆出什么

临近期末才想起数据库课程设计还没着落,下载了一份《数据库课程设计报告-药店管理系统.doc》,本以为又是一份凑字数的文档,翻完才发现它把教材里的六个设计阶段都串起来了:从需求分析、数据字典,到局部E-R图、综合E-R图,再到关系模式转换、建表SQL、触发器和权限管理,是一条完整的数据库课设链路。花了一个下午按这份报告在 SQL Server 2008 里重建了库之后,我的判断是:模板骨架能用,适合数据库初学者拿来当课程设计的框架,也适合答辩前补数据流图和规范化说明的人参考,但里面的SQL不能直接抄——药品进货触发器会把库存加错,医生表的更新触发器会自己触发自己。这类问题不提前改掉,答辩被追问时很容易穿帮。

2. 需求分析:六个功能模块、四类角色和数据字典怎么一次定清

2.1 功能模块:从药店销售业务拆出六块可落地的操作

报告把药店管理系统拆成了六块功能:基础数据处理、药品信息管理、营业数据处理、查询功能、用户权限管理和系统维护。这个拆分方式比较典型,没有按“增删改查”这种技术视角来分,而是按药店业务视角分的,后面写表结构时会发现这个视角的好处——每个功能块都能对应到具体的表操作。

基础数据处理管的是医生和药剂师名单的录入、修改、删除及查询,对应医生表和药剂师表。药品信息管理管的是药品进货、上柜、临时存货,对应药品表和柜台表。营业数据处理包含柜存药品查询、处方综合查询、交接班结处理,这块跨了柜台表、购买表和药品表。查询功能最重,药品库存、柜上药品、日/周/月/季度销售查询、药品销量和销售业绩查询,全都要落到药品表那一串以「xiaoshouzongliang、rixiaoshouliang、zhouxiaoshouliang、yuexiaoshouliang、jiduxiaoshouliang」结尾的字段上。

也就是说,这份报告把统计指标直接做成了药品表的列,而不是单独建销售明细表。这样查询时确实简单,一条 select 就能出日报周报月报,但代价是每次发生销售都要同步维护多个字段,冗余明显。写课程设计报告时可以这么写,因为逻辑清楚、容易讲;如果做实际系统,我一般会把销售流水单独拆一张表,再用视图或汇总表去算周期销量。

2.2 角色权限:医生、药剂师、销售职工、客户各自能干什么

系统角色需求定义了四类角色:医生和药剂师负责开药配药,销售职工负责出售商品,客户负责采购。这个划分直接决定了后面用户权限管理怎么写,也决定了 grant 语句该发给谁。

医生和药剂师都跟“开药、配药”打交道,但他们操作的侧重点不同。医生面向的是处方,涉及医生表、药品表、购买表;药剂师更多是配药和库存操作,涉及药剂师表、药品表的 stock 字段。销售职工管出售,需要读药品价格、写购买表,还要查自己的销售业绩。客户在真实系统中往往是消费者角色,报告里没有给客户建表,客户只是通过购买表间接出现。

这份报告在权限管理上只给了三条 grant 语句,分别授权 guest 修改医生姓名、药剂师姓名和药品库存。说实话,这个设计很粗糙——guest 是 SQL Server 的默认匿名用户,生产环境通常直接禁用;而且按最小权限原则,医生只能改自己的信息,销售职工只能动 stock,不应该用同一个 guest 账号统一授权。但作为课程设计,能体现“不同角色不同权限”的意识就够及格了。如果你想往高分做,就把角色和登录名一一对应,再给每个角色单独授权。

2.3 数据字典:八张表的字段族谱与字段命名习惯

数据字典是这份报告里信息量最密集的部分,一共涉及六张业务表:医生表、药剂师表、药品表、柜台表、柜台职工表、购买表。字段的命名用的是拼音缩写,比如 jname 是生产厂家,jiage 是价格,xiaoshouzongliang 是销售总量。这种命名在课程设计里很常见,但它属于典型的“能跑但不好维护”的写法。下面按报告原文把核心字段整理成一张表:

表名核心字段类型含义
医生表name、age、sexchar(8)医生姓名、年龄、性别
药剂师表name、age、sexchar(8)药剂师姓名、年龄、性别
药品表medicineid、name、stock、period、jname、jiagechar(8)药品号、药名、库存、保质期、生产厂家、价格
药品表(统计)xiaoshouzongliang、rixiaoshouliang、zhouxiaoshouliang、yuexiaoshouliang、jiduxiaoshouliangchar(8)总销量、日/周/月/季度销量
柜台表counterid、ename、eid、counternamechar(8)柜台号、职工名、职工编号、柜台名
柜台职工表eid、sex、age、ename、counterid、salchar(8)职工编号、性别、年龄、姓名、柜台号、工资
购买表medicineid、buydatechar(8)药品号、购买日期

你可以直接拿这张表去对照报告中第 3 章和第 6 章的建表语句。需要提醒的是:data dictionary 里没有出现“产地”字段,但第 4 章逻辑结构设计里药品关系模式突然多了“产地”属性。这种前后不一致在答辩时很容易被老师抓出来——后面第 5 章我会把这个问题放入避坑清单,改文档时务必统一。

3. 概念结构设计:从局部E-R图到综合E-R图的合并与冲突处理

3.1 为什么先画局部E-R图:选择中层数据流入手

概念结构设计的目标是把需求分析得到的用户需求抽象成信息结构,这一阶段产出的就是E-R图。报告给出的任务顺序是:先选择中层数据流为切入点,再设计各子模块的分E-R图,最后合并生成初步E-R图和全局E-R图。

这里有个经验:不要一上来就画整张系统的E-R图。药店管理系统实体虽然不多,但医生、药品、柜台、购买、药剂师之间的关系有开药、取药、上柜、出售、购买,混在一张图里很难理清。先按子系统拆成局部图,每张图只表达两到三个实体之间的关系,合并时再逐对消除冗余和冲突,这样的设计过程在答辩时也更容易讲清楚——老师问“这张图怎么来的”,你可以直接说先分了模块再合并。

3.2 药品、购买、柜台等局部图的实体与属性划分

报告里的局部E-R图包括药品E-R图、医生E-R图、药剂师E-R图、购买E-R图、柜台表E-R图、柜台职工表E-R图。实体和属性的划分逻辑很直白:一个实体对应未来的一张表,实体的属性对应表的列。

药品实体的属性最多,包括药品号、药名、生产厂家、保质期、库存、价格,以及总销量、日销量、周销量、月销量、季度销量。把统计指标作为药品的属性,这个设计在概念层面讲得通,因为报告的目标就是做销售查询;但在规范化分析时,这些统计字段其实可以从购买数据推导出来,严格说属于传递依赖的隐患。课程设计里这样写没问题,但你要知道它和“第三范式”之间存在张力——报告后面说关系模式满足BCNF,其实指的是去掉统计字段后的核心属性。

购买实体把药品号和购买日期作为属性,这里没有引入购买数量字段,是一个明显的简化。实际药店不可能不记录一次买了几盒,但为了保持报告简单,购买实体只保留了关联信息。如果你要扩展这个项目,第一件事就是给购买表加上 quantity 和 price 字段。

3.3 综合E-R图:合并实体、消除冗余与命名冲突

综合E-R图把局部图合并成了一个大的实体关系网络,核心联系包括:医生和药剂师开药、客户取药、药品上柜到柜台、柜台职工出售药品。合并的工程量不在“连线”,而在属性归并和冗余消除。

最常见的冗余情形是同一个属性在不同局部图中重复出现。比如职工编号 eid 同时出现在柜台表和柜台职工表中,合并时要去掉柜台表中的 eid,只保留柜台职工表到柜台表的联系。还有“姓名”属性在医生表和药剂师表中都存在,合并时如果两个实体都有 name,就要考虑加角色前缀做区分,否则全局E-R图里会出现两个含义不同的同名属性。命名冲突是E-R图合并的标准考点,报告里虽然没有专门写冲突处理过程,但你在答辩时可以主动补充:同名属性看含义,同义属性看命名,谁作为主键保留在谁那边。

4. 逻辑结构设计:联系转换规则与BCNF规范化检查

4.1 三种联系类型转换为关系模式的规则

逻辑结构设计的核心任务,是把E-R图中的实体和联系转换为关系模式。报告里给的标准规则可以压缩成一张表:

联系类型转换策略关系模式构成
1:1 联系转换为独立关系模式,或与任意一端合并加入另一端的码和联系自身属性
1:n 联系转换为独立关系模式,或与 n 端合并加入 1 端的码;独立时码取 n 端主键
m:n 联系必须转换为独立关系模式两端实体码组合作为联合主键,再加上联系自身属性
多元联系转换为独立关系模式各实体码组合作为联合主键

这条规则是数据库课设答辩的高频问题。你只要记住一个口诀:m:n 一定要拆,1:n 跟着 n 端走,1:1 随便挂一边。报告的药店系统里“购买”联系就是典型的 m:n 或多元联系转化,药品号和购买日期构成购买表;如果药品和购买记录之间需要记录数量,还要把数量一并放进购买关系模式。

4.2 函数依赖与BCNF判断:以药品表和柜台职工表为例

报告在第 4.3 节列出了各关系模式的函数依赖,全部声明满足 BCNF。以药品表为例,它的函数依赖是 药品号→药名、药品号→生产厂家、药品号→保质期、药品号→库存、药品号→价格。这些依赖的左边都是主键药品号,所以药品表满足 BCNF 的条件——每一个非平凡函数依赖的决定因素都是超键。

柜台职工表同理:职工号→姓名、职工号→年龄、职工号→工资、职工号→性别、职工号→所在柜台,全部依赖职工号,满足 BCNF。注意报告原文里有句话写的是“表均满足第三范式”,但后面又写“满足的是 BCNF”,这两者不是一回事——BCNF 比第三范式更严格。你写报告或答辩时,建议直接说 BCNF,并把函数依赖列出来证明,而不是含混地说“第三范式”。

这里给一个自检方法:把每张表写出来,列出所有非主属性,检查每个属性是否只依赖主键、不依赖其他非主属性。如果出现“药品价格→生产厂家”这类依赖,说明有传递依赖,就要拆表。这份报告的核心表都能通过检查,但前提是你把统计销量字段暂时忽略——那些字段之间其实存在互相依赖,比如 月销量 可以由 日销量 聚合得到,只是报告没有把它们写成函数依赖而已。

4.3 完整逻辑模型:从关系模式到物理表的对应

报告给出的完整逻辑模型包括六组关系模式:药品、购买、柜台、柜台职工、药剂师、医生。加上数据字典里提到的表和字段,最终在实施阶段一共要建六张表。

这里你会注意到一个细节:逻辑模型里“柜台表”的属性是(柜台号、职工名、职工编号、柜台名),主键是柜台号;但“柜台职工表”的属性是(姓名、年龄、工资、性别、所在柜台、职工号),主键是职工号。两张表都出现了职工信息,说明柜台和柜台职工之间是 1:n 的联系,柜台号作为外键出现在职工表中。建表时要把这个外键关系补上,否则第 6 章的建表脚本就只是“建了六张孤立的表”,没体现关系模型。

5. 实施与避坑:建表、触发器、权限的可复现写法与三个翻车点

5.1 建表SQL逐段解读:use、go、char(8) 带来的隐患

报告第 6 章的建表脚本可以直接在 SQL Server 2008 里跑,结构是标准的 use + create table + go。以医生表为例:

use sql go create table Yisheng( name char(8) not null, age char(8), sex char(8) ) go

第一行的use sql是选择目标数据库。原报告里的库名就是sql,如果你在自己的实例上跑,要改成实际库名。go是 SQL Server Management Studio 的批处理分隔符,表示把前面的语句作为一个批次提交,注意它不是 SQL 语法,所以在应用程序里嵌入时要去掉。

这段脚本最大的问题不是语法,而是字段类型全用char(8)。年龄、库存、工资、价格这些数字字段用定长字符串存,查询时无法按数值比较,stock > 10会变成字符串比较,9会被判定为大于10。而且char(8)是定长,长度不足右侧补空格,后续做字符串拼接或条件查询时要记得LTRIM(RTRIM(...))。如果是课程设计,至少把stock改成int,jiage改成decimal(10,2),buydate改成datetime。下面是推荐调整后的药品表结构:

create table yaopin( medicineid varchar(20) primary key, name nvarchar(50) not null, stock int default 0, period varchar(50), jname nvarchar(100), jiage decimal(10,2), xiaoshouzongliang int default 0 ) go

这里把主键显式加到medicineid上,并给库存和价格设置了默认值。原报告中六张表都没有定义主键,这在概念上站不住——E-R 图里明明标了码,建表时却不实现,触发器写起来也会因为没有主键而无法精准定位行。

5.2 触发器设计:医生更新、药剂师更新、药品进货的联动逻辑

报告中的触发器集中在三类操作:医生名单更新、药剂师名单更新、药品进货。以医生表更新触发器为例:

create trigger t_Yisheng on Yisheng for update as if update(name) begin declare @name_new char(8), @name_old char(8) select @name_new = name from inserted select @name_old = name from deleted update Yisheng set name = @name_new where name = @name_old end go

这段代码的意图是把更新后的姓名同步到关联位置。问题在于:for update触发器在Yisheng表被更新后触发,里面又执行了一次update Yisheng,这会导致触发器递归调用。SQL Server 默认允许嵌套触发器,连续触发可能让更新语句波及全表,甚至报错。正确做法是利用inserted和deleted两张虚拟表直接取得新旧值,然后把同步逻辑写到依赖这张表的下游表上,而不是回头再更新本表。

药品进货触发器的翻车更典型:

create trigger j_yaopin on yaopin for insert as declare @newstock char(8) select @newstock = stock from inserted update yaopin set stock = stock + 1 where stock = (select stock from inserted) go

这段代码的问题是先用stock作为匹配条件,而不是用medicineid。如果表里已经存在两条库存相同的药品,新插入一条记录后,两条旧记录都会被加 1。而且业务逻辑本身也不对——进货时插入的是新库存值,应该直接更新本行,而不是把表中所有相同库存的数据都加一遍。修改为按主键关联:

create trigger j_yaopin on yaopin for insert as update y set y.stock = y.stock + i.stock from yaopin y inner join inserted i on y.medicineid = i.medicineid go

这里的inner join inserted用主键精准匹配新插入的行,只有真正进货的药品库存会被更新。写触发器时记住一个原则:inserted和deleted保存的是受影响行的副本,所有逻辑应以它们为准,而不是重新查原表。

5.3 用户权限管理:给guest授权与最小权限原则

权限管理部分报告只给了三条授权语句:

use sql go grant update(name) on yisheng to guest go grant update(name) on yaojishi to guest go grant update(stock) on yaopin to guest go

这段脚本授权 guest 用户更新医生姓名、药剂师姓名和药品库存。grant update(列名) on 表名 to 用户名是列级授权,粒度比整表授权要细。但 guest 用户默认是所有数据库都会有的匿名账户,正规系统里通常要禁用,课程设计里演示列级授权没问题,答辩时要能说出“guest 仅作演示、生产环境应创建独立登录名并分配角色”这句话,就能把分拿回来。

5.4 五个常见问题:现象、原因、解决

第一条,更新医生姓名时数据库报“超出最大嵌套层数”。现象是执行一次 update 后,SQL Server 报错“Maximum stored procedure, function, trigger, or view nesting level exceeded”。原因是触发器t_Yisheng更新自身导致递归触发,嵌套层数被耗尽。解决方法是删掉触发器内部的update Yisheng语句,改为只做逻辑校验,或者把同步逻辑移到下游表对应的触发器里。

第二条,修改药剂师姓名,结果医生表的姓名也跟着变。现象是执行药剂师表 update 后,医生表数据被连带修改。原因是t_yaojishi触发器创建在yaojishi表上,内部却写了update Yisheng set name = ...,把更新目标写错了表。解决方法是把触发器内的Yisheng改成yaojishi,并按主键匹配。

第三条,插入一批药品后,多个药品的库存都多了 1。现象是执行一次 insert 后,原有库存相同的几条记录同时被加 1。原因是进货触发器用stock而不是medicineid做匹配条件。解决方法是用inner join inserted按主键关联更新。

第四条,库存和价格排序错乱。现象是查询stock > 10时结果包含了9、100之类的异常值,或价格排序变成字典序。原因是字段类型用了char(8),字符串比较按字符顺序进行。解决方法是在建表时把数字字段改为int或decimal,日期字段改为datetime。

第五条,数据字典和逻辑模型字段对不上。现象是数据字典里药品表没有“产地”字段,第 4 章逻辑模型里突然出现“产地”。原因是文档不同章节来源不一致,或直接从教材示例复制后忘了同步。解决方法是以数据字典为准,逐表核对字段清单,删除或补齐不一致的属性。

6. 验收与答辩:用检查清单验证这份报告能跑

6.1 按数据字典反查建表脚本

拿到这份报告后,我建议先做一次反查:拿着数据字典的字段清单,逐条核对第 6 章的 create table 语句,看是否每个字段都有对应、类型是否一致、主键外键是否齐全。网上流传的很多课设报告都存在“文档第二章说一套,第六章节代码另一套”的问题,这份也不例外。你可以写一条简单的元数据查询来核对:

select c.name as column_name, t.name as data_type, c.max_length from sys.columns c inner join sys.types t on c.user_type_id = t.user_type_id where c.object_id = object_id('yaopin') order by c.column_id

这段脚本会返回yaopin表当前真实的列名、数据类型和长度。把输出结果和数据字典一对比,缺失和类型不一致就全都现形了。检查之后,把主键、外键、默认值补上,再跑一次全部脚本,基本就能保证库是稳定可重建的。

6.2 触发器与权限的联动验证

触发器是这份报告最薄弱的部分,验证时按三个场景分别测。场景一:插入一条新药品,检查库存是否只有对应行被更新。场景二:修改医生姓名,确认没有触发递归错误。场景三:用 guest 用户执行越权操作,确认被拒绝。权限验证可以直接用执行上下文切换:

execute as user = 'guest' go update yaopin set jiage = 1 where medicineid = 'M001' go revert go

如果 guest 只有 update(stock) 权限,这条更新价格的语句会直接报权限错误。execute as user是 SQL Server 的模拟上下文命令,revert用来切回原来的身份。这一步验证通过,才说明权限设计在数据库层面是真的生效,而不是只写在文档里。

6.3 答辩前值得补的三处细节

第一处,把拼音字段名改成有意义的英文名。jname改成manufacturer,jiage改成price,答辩时不用解释“j 是生产厂家的‘家’拼音首字母”,更专业。第二处,在文档里补一张表与表之间的外键关系图,说明购买表的medicineid引用药品表主键、柜台职工表的counterid引用柜台表主键。第三处,把数据流图重新画一遍——报告里提到了顶层数据流图和一层数据流图,但文字部分没有把数据流的方向和存储描述完整,你用文档里的文字能说清楚“药剂师→药品库存→销售职工→购买记录”这条链路就够了。

这份数据库课程设计报告演完了从需求到建库的全过程,但真正让它变得可信的是实施阶段的验证。从那以后我每拿到一份课设报告,都会先按数据字典反查建表脚本、再把触发器逐条做插入更新删除测试、最后用 execute as 验证权限,这一套走完才敢说报告里的数据库真的能跑。希望帮到你。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/12 1:01:01

智能车硬件工程实践:电源噪声抑制与传感器时序对齐

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/12 0:44:30

共享自行车违停检测系统:YOLOv8s+PyQt5工程落地实践

简介:本资源是一套基于YOLOv8与PyQt5开发的共享自行车识别与违停检测系统,面向计算机、人工智能、自动化等专业学生及初学者,适用于课程设计、毕业设计、竞赛项目及实际告警场景落地。资源包含完整可运行工程:标注清晰的自行车图像…

作者头像 李华
网站建设 2026/10/12 0:43:00

张正友标定法+OpenCV实战:相机内参标定与畸变校正指南

简介:这份资源是张正友相机标定法的OpenCV完整实现工程,面向计算机视觉初学者、图像处理课程学习者以及需要快速搭建标定实验的开发者,用于解决相机内参、外参求解与镜头畸变矫正问题。压缩包共93个文件、约13.83MB,包含2个cpp源码…

作者头像 李华
网站建设 2026/10/12 0:30:29

331张图像小样本YOLO训练:行人车辆检测实战与部署边界

简介:这是一份面向YOLO系列目标检测学习者的行人车辆标注数据集,适用于yolov5、yolov8、yolov9、yolov7、yolov10及yolo11等主流算法,可直接用于模型训练与验证测试,适合入门练手或课程项目实践。资源包共994个文件,包…

作者头像 李华
网站建设 2026/10/12 0:24:55

Python深度学习驾驶员状态检测识别:从模型到工程落地

简介:这是一份Python基于深度学习的驾驶员状态检测识别项目源码与配套文档,适合计算机专业毕业生、开发者及需要项目实战的学习者。项目完整覆盖从数据预览、特征提取、模型微调到评估的流程,基于Keras实现多种经典卷积网络的迁移学习&#x…

作者头像 李华