首页 > 数据库 > MySQL存储过程使用建议 慎用存储过程,不要使用触发器,不使用外键

MySQL存储过程使用建议 慎用存储过程,不要使用触发器,不使用外键

2012年7月24日 9,519 views 发表评论 阅读评论

这是10年发在公司内部论坛上的. 分享给大家.

我们看下传统的说法:
1. http://mysql.lamphost.net/tech-r … oredprocedures.html
If you have a repetitive task that requires checking, looping, multiple statements, and no user interaction, do it with a single call to a procedure that’s stored on the server. Then there won’t be messages going back and forth between server and client, for every step of the task.
存储过程,外键,触发器这些东东,在传统行业,用得比较多, 许多复杂的业务逻辑用存储过程来实现,可保证安全,进行权限控制, 集中控制业务逻辑,客户端可大大简化, 如果业务逻辑变更,只需要修改下存储过程即可,而不需要繁琐地升级大量的客户端(一些编译发布的程序的很麻烦). 而且数据库服务器往往更强劲,也执行得更快更有效率, 网络通信来回往返传输的开销也可以节省.
虽然存储过程,外键,触发器有这么许多的好处,但现实中却存在许多问题, 随着业务规模的扩大,数据库会逐渐成为系统的瓶颈, 在客户端和数据库中间增加应用服务器(应用层)实现业务逻辑,用应用服务器(客户端)来确保数据完整性和一致性, 是伸缩性更好的方案,
如今的计算模式也已经和以前有了很大不同,特别是互联网,廉价的PC服务器集群大量应用,硬盘容量更大,价格更低,更倾向水平扩展,而没有必要把负荷都堆积到中心的数据库服务器上.所以对于我们互联网应用,存储过程,外键约束,触发器这些东东不再凸显重要性,许多项目基本不用.
分析:
1. 安全:
理论上来说,业务逻辑,各种约束越靠近数据库,会越安全, 也能最大化的充分利用数据库.但对于我们互联网应用,一般没有那么高的数据安全,不需要很强的数据完整性和一致性,如果确实有非常严苛的数据一致性需求,你也可以专门实现一个”数据访问层”,其他应用通过它来访问数据库.
2. 性能和扩展性:
mysql(5.1)的触发器只支持行级别((for each row)一种方式,对于大数据量表的处理很低效.触发器没有when条件,不能控制何时触发,可能造成性能瓶颈.无谓消耗资源.
外键,对并发性能的影响很大,因为每次修改数据都需要去另外一个表检查数据,需要获取额外的锁,高并发的环境下很容易出性能问题. 而级联更新删除之类的特性也比我们正常执行批量更新删除要慢得多. 所以更好的办法是在应用层实现外键约束.
应用层实现业务逻辑的网络通信的成本可能高了点, 但这是一个相对的概念,在距离很遥远的情况下,客户端和服务器端通信成本比较大,这个时候存储过程更显优势,但app服务器和数据库服务器一般位于同一个集群的内网,网络交互很快很稳定成本也很低.
数据库实现存储过程,触发器,外键很大一个背景是数据库服务器很强劲,传统行业一般是昂贵小型机,有非常强劲的处理能力,配备的是oracle等商业产品,业务需求相对稳定,需要充分利用数据库的能力而不仅仅当作一个数据的容器. 而互联网行业一般使用的是mysql数据库,相对廉价的PC, 业务的增长不确定,甚至是爆炸式的,如果数据构架不足,数据库很可能成为整个系统的瓶颈,数据库的资源一般比较紧张(服务器和人),扩展性不强,更昂贵, 而web服务器相对来说更便宜,更容易水平扩展, 把业务逻辑放到web服务器上去实现可以保证系统有良好的伸缩性.
3. 迁移
如果需要在不同的数据库产品间迁移,虽然有一些文档,各种各样的迁移方案供我们选择,但存储过程,触发器的迁移是一个难题.往往需要投入巨大的精力开发和测试.
4. 升级,维护,诊断,调优
降低了上线,升级的效率,dba和研发同学需要高度协调.以前一般是分离的, 或者升级代码或者升级数据库结构, 而现在需要升级存储在数据库服务器上的代码,但dba往往并不熟悉业务.
升级失败不易马上恢复.影响面太大. 而升级web服务器,可以一台一台升级. (一般情况下是可以做到一台一台升级的)

业务非常繁忙的系统, 升级存储过程可能导致系统出现异常,因为要升级的存储过程可能正被频繁访问. 或者应用系统足够复杂,存储过程互相调用,升级单个存储需要特别小心,以免影响了整个系统.
开发(测试)环境和生产环境可能不一致,导致开发开发环境的存储过程,触发器需要经过修改,才能升级到生产环境.(存储过程,视图,触发器等附加了一些额外不一致的信息)

备份恢复不方便.
存储过程,触发器debug不易.且触发器隐藏了实际执行的步骤,不易发现问题

mysql不能临时禁用,启用触发器,这点如果做数据迁移,修复会比较麻烦,需要临时drop触发器,可能影响到生产环境.
由于存储过程,触发器不易测试,或者未做充分测试,一旦升级失败可能导致数据错误,因为已经先drop了存储过程或者触发器.
不易分析存储过程,触发器的性能.不能通过慢查询日志去分析存储过程,触发器的具体执行情况.仅仅记录call procedure_name();这样简单的信息;
触发器可能导致死锁;
以上只是列举一些问题,具体的使用过程中,mysql的存储过程和触发器离商业产品的距离还有很远.

5. 开发

  • 存储过程,触发器的调试比较困难,没有什么好的工具和方法.
  • 触发器一个表同类型触发器只能建立一个,可能导致代码逻辑很复杂,不易阅读和维护,因为你需要把许多不相关的逻辑都写在一个触发器代码内.(MySQL doesn’t yet support ‘multiple triggers with the same action time and event for one table’)
  • 存储过程有诸多限制: 官方文档的存储过程的一些限制参考:http://dev.mysql.com/doc/refman/ … rigger-restrictions
  • 如果没有完善的,一致的文档,开发人员往往不熟悉(遗漏)数据库上的存储过程.
  • 存储过程比较简单,功能很有限,而程序代码可以实现更多的功能, 实现更复杂的业务逻辑.

小结: 存储过程慎用,业务逻辑不要放在存储过程中,;
不要使用触发器.
不要用外键,在高并发情况下,会大大降低并发性,外键自身的维护性管理性也欠佳.

 

 » 如果喜欢可以: 点此订阅本站
  1. 2012年7月24日05:17 | #1
  1. 本文目前尚无任何 trackbacks 和 pingbacks.