存储过程参与的前后端结构
1.前言
学MySQL的时候都会介绍一下存储过程,但听下来似乎也就是把一些SQL语句预先存储好然后一键调用,鲜有详细描述存储过程具体能实现什么功能,它的边界在什么地方的文章。以至于大部分人学完数据库之后只是使用了SQL的存储功能以及它提供的高性能的查找,从来没有用过存储过程,本系列将详细描述存储过程的常见用法
2.存储过程能做什么
后端的主要工作主要就是计算和数据存取,而相对于Java或者其他后端程序,存储过程是更接近于数据库的可编程逻辑,对于数据的存取有天然的性能优势。而且事实上,在存储过程里面能够完成常见的条件判断,循环等各种各样的非计算逻辑。合理的使用存储过程,能极大的降低后端查询数据的成本,把在Java里面做的业务逻辑判断转移到存储过程里面处理,Java里面只需要关心有什么数据,需要取什么数据,然后一股脑的传给数据库的存储过程,让存储过程处理后取出对应的数据。
举个常见的学校、学生的例子,有个学生要从学校A转学到学校B
-
在关系型数据库里,一般会在学生表里有个字段记录该学生所在的学校,理想情况下转学只要把这个字段更新一下就好了,但在实际的业务中往往需要做很多错误处理,比如要检查学校B是否有名额可以转入,学生在学校A的手续是否已经办理完结,这就可能涉及到学籍,权限等各种表的查询检查。
-
在常见的面向对象的设计中,可能已经对用到的所有的表就建立了实体类,并且常见的需求都封装成了方法可以调用,那么可能在转学这个逻辑里面要这么写
- 确定转学需要的手续
- 依次判断每个手续是否办理完结
- 查询B学校是否可以转入,哪个班级可以转入
- 执行update操作
这么做是没什么问题的,但是在这个过程中需要启动多次查询操作,Java在线程内又是同步的,如果是系统和网络性能好没有传输延迟还好,但如果Java和MySQL不在同一台服务器有网络延迟,那么N次查询就会带来2N次延迟的时间消耗
-
如果Java只是将转学的指令发给数据库,在数据库封装好一个存储过程,原地进行逻辑处理,处理好之后返回结果,那么是不是效率就高多了,毕竟数据库自己对于数据的存取才是最快的
可能你会觉得这好像也没什么啊,延迟损耗不大,不至于差这几百毫秒。那么如果说需要新增几万的学生数据,是在Java里面循环insert,还是一次丢给数据库处理更好呢
3.使用存储过程的系统架构
当下前端发展势头猛烈,对于大部分普通业务而言,后端真的只是做个数据存取的工作,并不需要一个厚重的Java框架来处理,这也催生了serverLess的发展,比如使用微信小程序云处理的话,后端,只需要定义几个数据存取的方法就行了,主要的业务逻辑都用JavaScript来写了。
使用存储过程是类似的选择,都是轻后端的架构,前端负责页面展现,存储过程负责数据存取,而中间只需要使用Java或者NodeJS的轻量级框架提供个api即可,大大简化了系统的开发流程
4.使用存储过程的缺陷
如果存储过程真的这么好,为什么没有流行呢? 存储过程真的太方便了,更新的时候直接修改保存立马生效,连编译都不用,更不用停机更新,做到真的的快速迭代,敏捷开发。然而,这也导致了很难进行版本管理,谁在什么时候改了什么完全没有记录。而且两个人同时打开编辑一个存储过程,最终是以后面保存的人修改的版本为准,第一个保存的人修改的东西就丢了!这真是件可怕的事情,所以一定要做好权限控制,后面会介绍如果进行版本管理以避免此类问题发生。