文章目录
软件开发定制一节复一节,软件开发定制千枝攒万叶。软件开发定制我自不开花,软件开发定制免撩蜂与蝶。
软件开发定制皓首犹贪学,软件开发定制谦虚德益丰。软件开发定制潜神无朕际,软件开发定制悟物不言中。
前言
软件开发定制我将其开源.软件开发定制但希望你能从中学习到软件开发定制数据库设计思想.
诚然,软件开发定制我不是一名DBA,软件开发定制我仅仅读过半本高性能MySQL(第3版)软件开发定制和一本数据库系统概论(第5版),一本java开发手册(华山版).软件开发定制我从中掌握了一些知识软件开发定制将他们运用在了课程设计中.软件开发定制也许我的数据库课程设软件开发定制计对于这个项目结构来软件开发定制说不是最好,最优秀的.
软件开发定制但是凭借这几本书的经验,软件开发定制我觉得还是有可取之处的.在本次数据库系统设计中我时刻希望以一名优秀的DBA标准要求自己.
不为别的.只希望做一次,就要做好!
由于做之前就萌生了开源的想法.我就完全将mysql表设计思想,避免约束加锁,避免触发器,存储过程…等问题全部考虑到了.
所以本次课程设计不仅有逻辑操作思想,还有学校以教学为目的,对于触发器,存储过程的枷锁要求.
我也因此希望能够做全面:存储引擎的考虑,表设计,采用方案的对比,索引优化,数据库在windows下压力测试和linux下时延响应时间的测试.
这几个方面都囊括其中.
希望共同学习,共同进步.
可以加入我的qq群:287048847 一起交流数据库设计和Java的开发!这里的人都充满激情!
想要更深一步了解mysql数据库,请移步此处
提示:以下是本篇文章正文内容,下面案例可供参考
医院信息管理系统
摘要
随着人们生活水平的不断提高,人们更重视医疗设施,医院的业务也不断增加,而对于医院来讲,信息管理系统属于其重要组成部分,确保系统高效、稳定且安全的运行是医院应关注和解决的问题,为使信息系统稳定、安全,高可用,工作人员需管理好信息系统,重视数据库安全,进而使信息数据将自身作用与价值充分发挥出来。医疗关系民脂民生,人民健康.设计人员应当格外小心谨慎,做好零失误.
1.概述
依据数据库课程设计要求,我将以DBA标准,参照mysql高性能,java开发手册,数据库系统概论等编写设计本系统.由于考虑诸多因素,对数据库的了解结合我目前的经验水平,我将使用java连接mysql数据库.shell脚本,jmeter测试工具进行测试.本系统使用mysql的原因是其在Linux下比sql server更成熟,同时它具有更高的灵活性.选用java作为数据库连接,因为我对它相较其他语言足够熟悉,同时它也足够强大.shell和jmeter都能很好的辅助我进行基准测试.以DBA的要求,应当多使用逻辑外键,少,存储过程和外键级联操作.但我会将两种方案一并给出.具体设计方案详见下文.
运行环境
mysql-connector-java-8.0.22.jar
Window10
IntelliJ IDEA 2021.2.1
apache-jmeter-5.4.1
linux-centos7
spring配bean连接池
2. 1需求分析
2.1.1基本分类需求分析
1. 控制中心
人员管理: | 实现对员工,病人的增删改; |
药品管理: | 实现对药品的入库,出库操作和处方药的登记以及药品类型,药品信息的登记 |
收费管理: | 对药品营收的统计; |
2. 查询
员工,病人的基本信息查询;
药品信息的查询;
收费情况的查询;
2.1.2 主要关系流程分析
病人看病,先挂号等待分配科室.然后医师给患者看病开票据.病人拿票凭去前台充值,接着去药房拿药.药师根据患者的票凭刷卡取药,完成药品交付和收费流程.
2.2
该系统主要包括基本数据维护、基本业务、数据库管理和信息查询四部分。
1、基本数据维护部份应包括提供管理员添加、修改并维护基本的数据途径。例如添加修改医院和办理病人入住与搬出或者换病房,管理医院里的基本设备。
2、数据库管理部分是对这个数据库的管理,包括医生,病人详细信息等。
3、该系统的技术可行性分析:在系统维护中包括医生和病人信息检索,数据库信息维护。
4、系统技术的可行性分析:
基于jvm和mysql下本系统可以运行于windows和Linux操作系统当中,可以为系统提供一个稳定的运行环境。该系统应该说有开发的必要性。
该系统主要由两大部分组成即管理维护和查询。
3.1概念结构设计
3.1.1 抽象出系统的实体
涉及的目标对象:患者,科室,医师,药师,前台收银,药品,挂号单,处方信息.
3.2 设计分E-R图
设计分E-R图
3.3.1 全局E-R图
4.1逻辑结构设计
病人病史 | (身份证号、姓名、性别、年龄、病例); |
药品存放记录 | (药品编号、药品名、进价、售价、药品数量、生产日期、有效期,存储位置); |
挂号 | (挂号编号、病人编号、性别、挂号科室、医生编号); |
收费 | (收费员编号,收费员姓名,病人编号,药品编号,数量,金额); |
医生 | (医生员工号,医生姓名,医生性别,医生年龄,科室,电话); |
处方 | (医生员工号,药品编号,数量); |
支付 | (支付编号,收费编号,价格); |
5.1数据库物理设计与实施
挂号
医师信息
病人信息
药品信息
缴费信息
取药票单
处方信息
支付凭据
6.数据操作要求及实现
6.1.1 数据查询、更新操作
select * from register where register.is_delete=0;
- 1
select * from doctor where doctor.is_delete=0;
- 1
select * from patient where patient.is_delete=0;
- 1
SELECT * FROM drugs WHERE is_delete=0;
- 1
select * from charge WHERE is_delete=0;
- 1
select * from PGM WHERE is_delete=0;
- 1
select * from recipel WHERE is_delete=0;
- 1
select * from pay WHERE is_delete=0;
- 1
6.1.2实现药品的入库、出库管理;
1. INSERT INTO drugs(drug_id, drug_name, drug_price, drug_quantity, drug_storage, drug_date, usefull_life) 2. VALUES ('1000237', '长生不老丹', 9999.00, '821', 'C-8-291', '2021-09-01', '2022-09-01'); 3. 4. SELECT * FROM drugs WHERE drug_name = '长生不老丹' AND is_delete=0;
- 1
- 2
- 3
- 4
1. UPDATE drugs SET drug_name = '聪明草' WHERE drug_id = '1000237'; 2. 3. UPDATE drugs SET IS_DELETE=1 WHERE drug_name='聪明草';
- 1
- 2
- 3
对应的java后端实现
1. 增删改操作 2. package com.vector.hospital_information; 3. 4. import com.vector.config.SpringConfiguration; 5. import org.junit.Test; 6. 7. import org.junit.runner.RunWith; 8. import org.springframework.context.ApplicationContext; 9. import org.springframework.context.annotation.AnnotationConfigApplicationContext; 10. import org.springframework.stereotype.Component; 11. import org.springframework.test.context.ContextConfiguration; 12. import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 13. 14. import javax.annotation.Resource; 15. import javax.sql.DataSource; 16. import java.sql.Connection; 17. import java.sql.PreparedStatement; 18. import java.sql.SQLException; 19. 20. @RunWith(SpringJUnit4ClassRunner.class) 21. @ContextConfiguration(classes = {SpringConfiguration.class}) 22. @Component("Update_test") 23. public class Update_test { 24. @Resource(name = "dataSource") 25. DataSource dataSource; 26. @Resource(name = "Update_test") 27. Update_test modify; 28. @Test 29. /** 30. * 测试增删改 31. */ 32. public void TestUpdate() throws SQLException { 33. 34. /** 35. * 测试增添数据 36. */ 37. String sql1 = "INSERT INTO drugs(drug_id,drug_name,drug_price,drug_quantity,drug_storage,drug_date,usefull_life) VALUES (?, ?, ?, ?, ?, ?, ?)"; 38. modify.update(sql1,"1000237", "长生不老丹", 9999.00, "821", "A-8-291", "2021-09-01", "2022-09-01"); 39. 40. /** 41. * 测试修改数据 42. */ 43. // String sql2 = "UPDATE drugs SET drug_name = ? WHERE drug_id = ?"; 44. // modify.update(sql2,"聪明草","1000237"); 45. // /** 46. // * 测试删除数据 47. // */ 48. // String sql3 = "DELETE FROM drugs WHERE drug_name=?"; 49. // modify.update(sql3,"聪明草"); 50. } 51. /** 52. * 王佳慧 53. * 通用增删改 54. * @param sql 55. * @param args 56. * @throws SQLException 57. */ 58. 59. //通用的增删改操作 60. public void update(String sql, Object... args) throws SQLException {//sql当中占位符个数与可变形参的长度一致 61. 62. Connection conn = null; 63. PreparedStatement ps = null; 64. //ApplicationContext app = null; 65. try { 66. //app = new AnnotationConfigApplicationContext(SpringConfiguration.class) 67. //1.获取数据库连接 68. conn = dataSource.getConnection(); 69. //2.预编译sql语句,返回PreparedStatement实例 70. ps = conn.prepareStatement(sql); 71. //3.填充占位符 72. for (int i = 0; i < args.length; i++) { 73. ps.setObject(i + 1, args[i]); 74. } 75. //4.执行sql语句 76. ps.execute(); 77. System.out.println("添加记录成功"); 78. } catch (Exception e) { 79. e.printStackTrace(); 80. } finally { 81. //5.资源的关闭 82. conn.close(); 83. } 84. } 85. 86. } 1. Sql查询 2. package com.vector.hospital_information; 3. 4. import com.vector.config.SpringConfiguration; 5. import com.vector.test.DataSourceTest; 6. import org.junit.Test; 7. import org.junit.runner.RunWith; 8. import org.springframework.stereotype.Component; 9. import org.springframework.test.context.ContextConfiguration; 10. import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 11. 12. import javax.annotation.Resource; 13. import javax.sql.DataSource; 14. import java.lang.reflect.Field; 15. import java.sql.*; 16. 17. @RunWith(SpringJUnit4ClassRunner.class) 18. @ContextConfiguration(classes = {SpringConfiguration.class}) 19. @Component("PreparedStatementQueryTest") 20. public class PreparedStatementQueryTest { 21. 22. @Resource(name = "dataSource") 23. DataSource dataSource; 24. @Resource(name = "PreparedStatementQueryTest") 25. PreparedStatementQueryTest queryTest ; 26. 27. 28. @Test 29. /** 30. * 测试查询 31. */ 32. public void TestQuery() throws SQLException { 33. 34. 35. /** 36. * 测试查询一条记录 37. */ 38. String sql = "SELECT * from drugs where drug_name=?"; 39. Drugs drugs = queryTest.getInstance(Drugs.class,sql,"长生不老丹"); 40. System.out.println(drugs); 41. 42. 43. } 44. /** 45. * 王佳慧 46. * 针对于不同的表的通用查询操作,返回表中的一条记录 47. * @param clazz 48. * @param sql 49. * @param args 50. * @param <T> 51. * @return 52. */ 53. public <T>T getInstance(Class<T> clazz,String sql,Object ...args) throws SQLException { 54. Connection conn = null; 55. PreparedStatement ps = null; 56. ResultSet rs = null; 57. try { 58. conn = dataSource.getConnection();//加载数据库 59. ps = conn.prepareStatement(sql); 60. for (int i = 0; i < args.length; i++) { 61. ps.setObject(i + 1, args[i]); 62. } 63. //执行,获取结果集 64. rs = ps.executeQuery(); 65. //获取结果集的元数据 66. ResultSetMetaData rsmd = rs.getMetaData(); 67. //获取列数 68. int columuCount = rsmd.getColumnCount(); 69. if (rs.next()) { 70. T t = clazz.newInstance(); 71. for (int i = 0; i < columuCount; i++) { 72. //获取每个列的列值,通过ResultSet 73. Object columnValue = rs.getObject(i + 1); 74. //获取每个列的列名,通过ResultSetMetaData 75. //获取列的列名:getColumnName() ---不推荐使用 76. //获取列的别名:getColumnLabel() 77. String columnLabel = rsmd.getColumnLabel(i+1); 78. //通过反射,将对象指定名columnName的属性值赋值给columnValue 79. Field field = clazz.getDeclaredField(columnLabel); 80. field.setAccessible(true); 81. field.set(t, columnValue); 82. } 83. return t; 84. } 85. } catch (Exception e) { 86. e.printStackTrace(); 87. } finally { 88. conn.close(); 89. } 90. 91. return null; 92. } 93. 94. 95. }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 165
- 166
- 167
- 168
- 169
- 170
- 171
- 172
- 173
- 174
- 175
- 176
- 177
- 178
- 179
- 180
- 181
- 182
- 183
6.1.3实现科室、医生、病人的管理;
(1) 逻辑增删改
1. INSERT INTO register(r_num, r_patient_id, r_sex, r_dept, r_name) 2. VALUES ('222', '411282xxxxxxx1182', '女', '肛肠科', '尘思宇'); 3. 4. SELECT * from register where r_patient_id='41128220230304554X WHERE IS_DELETE=0'; 5. 6. START TRANSACTION; 7. BEGIN; 8. UPDATE patient SET p_name = '病人1' WHERE p_atient_id = '41128220230304554X AND IS_DELETE=0; 9. UPDATE register SET r_name = '病人1' WHERE r_patient_id = '41128220230304554X' AND; 10. IS_DELETE=0; 11. 12. UPDATE register SET IS_DELETE=1 WHERE r_num='222';
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
Java相关事务提交核心代码1. try {2. //app = new AnnotationConfigApplicationContext(SpringConfiguration.class)3. //1.获取数据库连接4. conn = dataSource.getConnection();5. conn.setAutoCommit(false);6. //2.预编译sql语句,返回PreparedStatement实例7. ps = conn.prepareStatement(sql);8. //3.填充占位符9. for (int i = 0; i < args.length; i++) {10. ps.setObject(i + 1, args[i]);11. }12. //4.执行sql语句13. ps.execute();14. conn.commit();15. System.out.println("添加记录成功");16. } catch (Exception e) {17. conn.rollback();18. e.printStackTrace();19. } finally {20. //5.资源的关闭21. conn.close();22. }23. }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
(2) 级联操作1. -- 级联操作 2. alter table patient add 3. constraint patient_register_dept 4. foreign key(p_atient_id) references register(r_patient_id) on delete cascade; 5. DELETE FROM patient WHERE p_atient_id='41128220230304554X';
- 1
- 2
- 3
- 4
- 5
- 6
- 7
6.1.4实现处方的登记管理
1. /**2. * 测试增添数据3. */4. String sql1 = "INSERT INTO recipel(id,doctor_id,drug_id,count,patient_name) VALUES (?,?,?,?,?);";5. modify.update(sql1,1,"001", "100023", "2盒","病人1");
- 1
- 2
- 3
- 4
- 5
- 6
6.1.5实现收费管理;
6.2 视图
创建视图查询各种药品的库存总数;
1. SELECT drug_name,sum(drug_quantity) FROM drug_view GROUP BY drug_name ;
- 1
6.3 触发器
药品出库操作
1. -- 创建触发器,当药品入库、出库时自动修改库存; 2. # 药品出库操作 3. delimiter $$ -- 自定义结束符号 4. create trigger recipel_update 5. before insert 6. on recipel 7. for EACH ROW 8. BEGIN 9. SELECT @quantity=drug_quantity into @str 10. FROM drugs WHERE NEW.drug_id = drugs.drug_id; 11. IF @quantity <= 0 || NEW.count > @quantity THEN 12. SIGNAL SQLSTATE '02000' SET MESSAGE_TEXT = 'Warning: 药品数量为零!'; 13. ELSE 14. UPDATE drugs SET drug_quantity = drug_quantity - NEW.count WHERE drug_id=NEW.drug_id AND IS_dELETE=0; 15. end if; 16. end 17. $$ -- 自定义触发器结束 18. delimiter ;
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
插入前
插入后
药品入库操作
插入前
插入后
6.4
创建存储过程统计某段时间内,各科室的就诊人数和输入情况;
#存储过程drop procedure count_people_date;DELIMITER $$CREATE PROCEDURE count_people_date(#IN @begin_date datetime, 这样写是错误的 IN begin_date datetime, IN end_date datetime )BEGIN SELECT r_dept '科室',count(*) '问诊人数' FROM register WHERE update_time BETWEEN begin_date AND end_date AND is_delete=0 GROUP BY r_dept ;end $$DELIMITER ;CALL count_people_date('2021-12-04','2021-12-05');
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
7.基准测试
压力测试:
时间延迟测试:
8.总结
对于本次课程设计,考虑到做事就要做完美,做一次了,那就给他开源,设计,优化,调试,测试,对比都做一遍.当然在进行数据库操作的时候,难度最大的有
1.触发器 由于我使用了mysql,这与sql service有着高度的隔离.这部分内容是完全不一样的.做迁移时耗费了很大力气.有很多问题摸索了很久,有些问题是stackoverflow,百度,csdn都解决不了的.比如我使用了update触发器,但是在触发器中执行插入操作,总是插不进去!困扰了我很久,寻访各个dba群中大佬,都无能为力.总之,有些是耗费很长时间都无法解决的,很挫败.但虽然挫败,但我也收获了很多,对于基本的sql操作,以及mysql,sql service都有了深刻认识.
2.新思想 同时在设计数据库的过程中,也触发了很多新思想,有了新思想,眼前豁然开朗,逻辑删除思想解决了一对多,牵一发而动全身的难题.也保证了数据的永久存储.
3.Linux下的数据时延测试. 本以为靠两个shell自动化脚本很容易做.但是错误也是频繁发生.但在解决问题的过程中,我了解到了sh -x 脚本调试.这让我捕获了错误.完成了数据采集,以及qbs在时间维度的测试.
9.参考文献
[1]高性能MySQL:第3版/(美)Schwartz,B.(美)Zaitsev,P.,(美)Tkachenko,V.著;宁海元等译.-北京:电子工业出版社,2013.5 书名原文:High Performance MySQL,Third Edition.
[2]数据库系统概论/王珊,萨师煊编著.—5版.—北京:高等教育出版社,2014.9 ISBN 978-7-04-040664-1
[3]java开发手册社区开发者集体智慧的结晶-(华山版)v1.5.0.-杭州:阿里巴巴,2019.06
写在最后
开源连接
时间 | 更新次数 |
---|---|
2021-12-10 | 第一次更新,更新优化了部分表和github仓库的表 |