1 绪论
一个好的管理系统应该具有如下功能:快速准确进行出院结算;实现高效的病房管理;提高病房使用率;方便管理者随时了解病床使用情况;减轻员工的工作负担;促使员工把更多的精力放在为病人提供更加优质的服务上等。本次课题将以此为目标,设计一个医院病房管理系统。我们将主要实现对病人的住院登记、出院结算、病人的信息管理、医院内部的信息管理以及系统安全管理的功能,从而使医院能够更好地利用信息来提高医院病房管理的效率,改善医院服务质量,更好的服务于患者和工作人员。
2 需求分析
需求分析阶段主要有两个方面的任务:分析用户的数据要求和分析用户的处理要求。
数据流程图如下:

2.1 功能分析
根据用户调查,系统应有以下功能需求:
(1)用户(医生、护士)登录需求
医生、护士只有输入正确的工作证号和密码才能登录系统,如果还没有注册,可联系系统管理人员输入相关信息进行注册。
(2)住院登记需求
病人住院前应当完成入院登记,登记信息包括:病人病历号、姓名、性别、民族、电话号码、家庭住址、诊断、主管医生、病房号、床位号、住院日期、出院日期。其中病房应由系统按照病房、病床余量以及病人主管医生所属科室、诊断情况合理分配。
(3)信息管理需求
信息管理需求应包括:病人信息管理、医院内部信息管理。管理员可通过此系统对病人信息、医生信息、护士信息、病房和病床信息进行更新和处理。
(4)出院结算需求
能够根据病人的入院日期、出院日期和所住病房的收费标准计算出病人所需支付的费用,以便病人快速办理出院。
(5)安全管理需求
能够保证系统的安全性,用户可通过对工作证号和旧密码的验证来修改登录密码。
2. 2 行为操作分析
系统功能模块图如下:

3 数据概念模型设计
经过以上分析,已经基本了解了用户对处理的要求,接下来要求做的工作是分析用户对数据的要求。最常用的表示概念性数据模型的方法是实体-联系方法,即E---R图。

4 数据逻辑结构的设计
4.1 将E-R图转化为关系数据模型
根据以上各实体图和E-R 图。经过转换,可以导出各个关系。其转换现则为:首先每个实体应该化为一个关系,有属性的联系也应转化为一个关系,然后需要给出每个关系的关键字。根据以上规则,直接给出所有关系。
- 医生(++++工作证号++++,姓名,性别,年龄,职称,科室名,密码)
- 病人(++++病历号++++,姓名,性別,年龄,民族,电话号码,家庭住址,病房号,床位号,住院日期,出院日期)
- 治疗(++++工作证号,病历号++++,诊断)
- 护士(++++护士号++++,姓名,密码)
- 科室(++++科室名++++,科室地址,科室电话)
- 病房(++++病房号++++,护士号,科室名,收费标准)
- 病床(++++床位号,病房号++++,目前状态)
4.2 关系模式的规范化
将E-R图转换为以上的关系模式后,需要完成规范化,即确定各关系模式是否是第三范式。
(1)分析关系模式"医生",存在下列函数依赖:
(姓名,性别,年龄,职称,科室名,密码)完全函数依赖于工作证号;
(2)分析关系模式"病人",存在下列函数依赖:
病历号函数决定(病房号,床位号);
(病房号,床位号)函数决定(姓名,性別,年龄,民族,电话号码,家庭住址,病房号,床位号,住院日期,出院日期);
所以病历号传递函数决定(姓名,性別,民族,电话号码,家庭住址,病房号,床位号,住院日期,出院日期)。
分解为:
病人(++++病历号++++,病房号,床位号)
住院(++++病房号,床位号++++,姓名,性別,民族,电话号码,家庭住址,住院日期,出院日期)
(3)分析关系模式"治疗",存在下列函数依赖:
(工作证号,病历号)函数决定诊断;
病历号函数决定诊断;
分解为:治疗(++++病历号++++,诊断);
(4)分析关系模式"护士",存在下列函数依赖:
护士号完全函数决定(姓名,密码);
(5)分析关系模式"科室",存在下列函数依赖:
科室名完全函数决定(科室地址,科室电话);
(6)分析关系模式"病房",存在下列函数依赖:
病房号完全函数决定(护士号,科室名,收费标准);
(7)分析关系模式"病床",存在下列函数依赖:
床位号,病房号完全函数决定目前状态;
(8)关系模式"医生"、"病人"、"住院"、"治疗"、"护士"、"科室"、"病房"、"病床"不存在部分和传递依赖关系,因些属于第三范式。
至此,所有关系模式都符合第三范式要求。
4.3 关系模式的优化
(1)根据第2章"需求分析"中病人信息管理的需求,需要多次查询病人信息,而由病历号直接查询到其他信息是最为快捷的方式,所以即使:病人(++++病历号++++,姓名,性別,民族,电话号码,家庭住址,病房号,床位号,住院日期,出院日期)这个关系模式存在传递函数依赖,我们也准备采取这个关系模式;
(2)考虑到对医生---病人信息查询的需求,该医院病床系统还需要生成医生---病人信息报表,因此在此设计出"医生---病人表":
sql
CREATE VIEW doctor_patient
AS
SELECT doctor.Dcode,Dname,Dsex,Dage,Dtitle,Departname,patient.Pcode,Pname,Psex,Paage,Pnation,
Pphone,Proom,Pbed,Pdiagnosis,Pinhospital,Pleavehospital
FROM treatment JOIN doctor ON treatment.Dcode = doctor.Dcode
JOIN patient ON treatment.Pcode = patient.Pcode;
SELECT * INTO doc_pat FROM doctor_patient;
SELECT * FROM doc_pat;
(3)考虑到病人出院结算打印收据的需求,可利用住院日期、出院日期和病房日收费计算总费用,因此设计"收据表":
sql
CREATE VIEW receipt_view
AS
SELECT Pcode,Pname,Psex,DATEDIFF(DAY,Pinhospital,Pleavehospital) * Fees fees FROM patient
JOIN patientroom ON patient.Proom = patientroom.Proom WHERE Pleavehospital IS NOT NULL ;
SELECT * INTO receipts FROM receipt_view;
SELECT * FROM receipts;
5 物理实现和操作
本次设计采用了SQL Server 2019为工具软件,完成表的建立和操作。
5.1 数据库的建立
sql
CREATE DATABASE HPMS;
5.2 表的建立
本次设计一共建立了7张表,下面给出创建这些表的SQL语句和实现图。
sql
(1)department表
CREATE TABLE department(
Departname varchar(20) PRIMARY KEY,
Departadress varchar(40) NOT NULL,
Departphone char(11)
)
(2)nurse表
CREATE TABLE nurse(
Ncode char(8) PRIMARY KEY,
Nname varchar(10) NOT NULL,
Npass varchar(15)
)
(3)patientroom表
CREATE TABLE patientroom(
Proom char(4) PRIMARY KEY,
Ncode char(8) NOT NULL,
Departname varchar(20) NOT NULL,
Fees char(7),
FOREIGN KEY (Ncode) REFERENCES nurse (Ncode),
FOREIGN KEY (Departname) REFERENCES department (Departname)
)
(4)patientbed表
CREATE TABLE patientbed(
Pbed char(4) NOT NULL,
Proom char(4) NOT NULL,
Pstatus char(2),
PRIMARY KEY (Pbed,Proom),
FOREIGN KEY (Proom) REFERENCES patientroom (Proom)
)
(5)doctor表
CREATE TABLE doctor(
Dcode char(8) PRIMARY KEY,
Dname char(10) not null,
Dsex char(2),
Dage tinyint,
Dtitle Char(10),
Departname varchar(20) not null,
Dpass varchar(15),
FOREIGN KEY (Departname) REFERENCES department (Departname)
)
(6)patient表
CREATE TABLE patient(
Pcode char(8) PRIMARY KEY,
Pname char(10) not null,
Psex char(2),
Paage tinyint,
Pnation Char(8),
Pphone char(11),
Paddress varchar(40),
Proom char(4) not null,
Pbed char(4) not null,
Pinhospital date not null,
Pleavehospital date,
FOREIGN KEY (Proom) REFERENCES patientroom (Proom)
)
(7)treatment表
CREATE TABLE treatment(
Dcode char(8) ,
Pcode char(8),
Pdiagnosis varchar(40),
primary key(Dcode,Pcode),
FOREIGN KEY (Dcode) REFERENCES doctor (Dcode),
FOREIGN KEY (Pcode) REFERENCES patient (Pcode)
)
关系图如下所示:

5.3 操作
(1)排序操作:日收费为40元的为普通病房,100元的为VIP病房,将病房日收费按从大到小排序:
sql
SELECT patientroom.Proom,Pcode,Pname,Fees FROM patientroom JOIN patient ON patientroom.Proom = patient.Proom
WHERE FEES IN(100,40)
ORDER BY FEES;
(2) 子查询:建立医生信息视图,因为医生表中有一列属性是密码,所以当查询医生信息时,不应显示出来:
sql
GO
CREATE VIEW V_DOCTOR
AS
SELECT Dcode,Dname,Dsex,Dage,Dtitle,Departname
FROM doctor;
GO
SELECT * FROM V_DOCTOR;
(3)联表查询:建立医生-病人视图,可查询相关医生信息和病人信息:
sql
GO
CREATE VIEW doctor_patient
AS
SELECT doctor.Dcode,Dname,Dsex,Dage,Dtitle,Departname,patient.Pcode,Pname,Psex,Paage,Pnation,
Pphone,Proom,Pbed,Pdiagnosis,Pinhospital,Pleavehospital
FROM treatment JOIN doctor ON treatment.Dcode = doctor.Dcode
JOIN patient ON treatment.Pcode = patient.Pcode;
GO
SELECT * FROM doctor_patient;
(4)出院结算:依据住院日期、出院日期以及病房日收费即可结算出院费用:
sql
SELECT Pcode,Pname,Psex,DATEDIFF(DAY,Pinhospital,Pleavehospital) * Fees fees FROM patient
JOIN patientroom ON patient.Proom = patientroom.Proom WHERE Pleavehospital IS NOT NULL ;
(5)修改、删除操作:病人出院后,首先通过出院日期查询出院病人的病房号和病床号,然后将此病人所住病房的病床状态改为空,然后即可删除治疗表以及病人表的该病人相关信息:
sql
SELECT Proom,Pbed FROM patient
WHERE Pcode=(SELECT Pcode FROM PATIENT
WHERE Pleavehospital IS NOT NULL);
UPDATE patientbed SET Pstatus = NULL WHERE (Proom = 5101 and Pbed = 3);
SELECT * FROM patientbed;
ALTER TABLE treatment
DROP CONSTRAINT [FK__treatment__Pcode__35BCFE0A];
ALTER TABLE treatment
ADD FOREIGN KEY(Pcode) REFERENCES patient(Pcode)
ON DELETE CASCADE;
DELETE FROM patient
WHERE Pcode=(SELECT Pcode FROM PATIENT
WHERE Pleavehospital IS NOT NULL);
SELECT * FROM patient;
(6)查询、修改操作:假定病历号为05060211的病人想要由普通病房换到VIP病房,则先查询病房日收费为100元且病床状态为空的病床,然后查询该病人所住病房病床,将该病人所住病房病床修改为查询到的VIP病房空床,然后将该VIP病房病床状态改为满。
sql
SELECT Proom,Pbed FROM patient WHERE Pcode = '05060211';
SELECT patientroom.Proom,Pbed FROM patientbed JOIN patientroom ON patientbed.Proom = patientroom.Proom
WHERE Pstatus IS NULL AND Fees = '100';
UPDATE patient SET Proom = 5101,Pbed = 3 WHERE Pcode = '05060211';
SELECT * FROM patient;
UPDATE patientbed SET Pstatus = '满' WHERE (Proom = '5101' AND Pbed = '3');
SELECT * FROM patientbed;
(7)数据库备份操作
sql
BACKUP DATABASE HPMS
TO disk = 'D:\HPMSfile.bak'
WITH FORMAT,
NAME = 'HPMS备份'
扩展:触发器
(1)在病人表上创建一个insert_patient触发器
在插入新的病人记录前先判断记录中的床位状态,若状态为"满",则回滚到插入操作前并提示操作人员该床位已满;否则成功插入该记录,防止操作失误。
sql
CREATE TRIGGER insert_patient
ON patient
INSTEAD OF INSERT
AS
BEGIN
DECLARE @bed char(4),@room char(4),@code char(8) ,@name char(10),@sex char(2),@nation Char(8),@phone char(11);
DECLARE @age tinyint;
DECLARE @address varchar(40);
DECLARE @inhospital date,@leavehospital date;
SELECT @bed=Pbed,@room=Proom,@code=Pcode,@name=Pname,@sex=Psex,@nation=Pnation,@phone=Pphone,@age=Paage,@address=Paddress,@inhospital=Pinhospital,@leavehospital=Pleavehospital FROM inserted
IF ( (SELECT Pstatus FROM patientbed WHERE (Pbed=@bed AND Proom=@room) )= '满')
BEGIN
PRINT '该床位已满'
ROLLBACK TRANSACTION
END
ELSE
BEGIN
INSERT INTO patient VALUES(@code,@name,@sex,@age,@nation,@phone,@address,@room,@bed,@inhospital,@leavehospital)
END
END
(2)在病人表上创建一个UPDATE_patient触发器
病人可能会出现更换床位的情况,在修改病人记录前判断记录中的床位状态,若状态为"满",则回滚到修改操作前并提示操作人员该床位已满;否则成功修改该床位记录。
sql
CREATE TRIGGER UPDATE_patientbed
ON patient
INSTEAD OF UPDATE
AS
BEGIN
DECLARE @bed char(4),@room char(4),@code char(8)
SELECT @bed=Pbed,@room=Proom,@code=Pcode FROM inserted
IF ( (SELECT Pstatus FROM patientbed WHERE (Pbed=@bed AND Proom=@room) )= '满')
BEGIN
PRINT '该床位已满'
ROLLBACK TRANSACTION
END
ELSE
BEGIN
UPDATE patient SET Proom=@room,Pbed=@bed WHERE Pcode=@code
END
END
(3)在病人表上创建一个input_bed触发器
当插入新的病人记录或病人更换床位后,将插入病人记录对应床位或更换后的床位的状态修改为"满"。
sql
CREATE TRIGGER input_bed
ON patient
AFTER INSERT,UPDATE
AS
BEGIN
DECLARE @bed char(4),@room char(4)
SELECT @bed=Pbed,@room=Proom FROM inserted
UPDATE patientbed
SET Pstatus='满'
WHERE Pbed=@bed AND Proom=@room
END
(4)在病人表上创建一个dele_bed触发器
当病人出院后删除病人记录或病人更换床位后,将删除病人记录对应的床位或更换前的床位的状态修改为"NULL"(释放床位)。
sql
CREATE TRIGGER dele_bed
ON patient
AFTER DELETE,UPDATE
AS
BEGIN
DECLARE @bed char(4),@room char(4)
SELECT @bed=Pbed,@room=Proom FROM deleted
UPDATE patientbed
SET Pstatus=NULL
WHERE Pbed=@bed AND Proom=@room
END
6 设计总结
本次数据库设计围绕医院病房管理系统展开,核心目标是提升医院病房管理效率,实现病人住院登记、出院结算、信息管理、医院内部信息管理及系统安全管理等核心功能。
设计过程中,主要面临功能分析不全面、数据流程图不完善、关系模式规范化与实际需求冲突、物理操作代码繁琐等问题。通过查阅资料,不仅夯实了已有知识,还掌握了触发器使用等额外技能。
此次设计实践让我深刻认识到:数据库设计需重视需求分析,全面深入考量以避免实现中的不合理性;需严格遵循实体完整性、参照完整性及用户定义完整性;建表需符合设计、索引、SQL语句等规范;代码编写需兼顾使用者实际,降低操作难度。此外,为增强系统可靠性,本次设计对医院病房管理系统进行备份,提升其容错能力,保障数据安全。