文章目录
- 什么是存储过程:数据库中的“瑞士军刀”
- 阿里巴巴为什么对存储过程“零容忍”?
- 1. 维护的“噩梦”
- 2. 扩展性的“死穴”
- 3. 性能的“双刃剑”
- 4. 移植性的“灾难”
- 存储过程与Java代码的Performance PK
- 什么情况下还可以考虑使用存储过程?
- 分布式数据库时代存储过程的命运
- 结语:工程化优于技术特性
- 参考文献
大家好,我是你们的技术老友科威舟,今天给大家分享一下为什么存储过程在互联网时代失宠了?
一次存储过程引发的血案,让阿里工程师们彻底放弃了这种单机时代的“遗产”
为什么《阿里巴巴Java开发手册》里明令禁止使用存储过程?这背后到底藏着怎样的技术思考和血泪教训?
什么是存储过程:数据库中的“瑞士军刀”
存储过程,简单来说,就是预编译的SQL语句集,存储在数据库中,可以被客户端应用程序调用。它像是一把数据库中的“瑞士军刀”,能完成各种复杂操作。
存储过程有着辉煌的历史。在C/S架构盛行的时代,它是绝对的明星。数据库不仅承担数据存储、计算功能,还要运行很重的业务逻辑,相当于同时承担应用服务器的大多数功能。
存储过程的主要特点:封装性、可重用性、可编程性和安全性。乍一看,这简直完美!但正是这把“瑞士军刀”,在互联网时代却变成了“烫手山芋”。
阿里巴巴为什么对存储过程“零容忍”?
1. 维护的“噩梦”
想象一下这样的场景:你接手了一个老系统,其中有一个1200行的存储过程。某天底层数据结构稍有变动,你发现这个存储过程报错了,只提示"ERROR:1064",却无法定位具体错误点。
这就是存储过程调试的日常。与传统Java代码相比,存储过程的调试工具极其有限。在应用层,你可以在任何一步打日志,但存储过程的执行过程难以跟踪。
实战案例:某系统需要校验用户是否有Job、Certification、Disclosure等业务数据。这些逻辑写在存储过程中,当新需求需要复用这些逻辑时,开发人员陷入了困境:如果每一处都重写业务逻辑,维护困难;如果调用现有存储过程,又会导致接口返回大量不必要的数据。
2. 扩展性的“死穴”
在互联网公司,数据库会有专人维护,开发人员通常无法直接访问生产库。当业务逻辑写在存储过程中,每次业务升级都需要同步升级存储过程,导致工作职能冲突。
更致命的是,存储过程不利于分库分表。在数据量急剧增长的互联网场景下,数据库往往需要水平拆分。而存储过程对此无能为力——它不知道数据在哪个数据库中。
幽默比喻:存储过程就像是在高速公路上设置的固定路障,当车流量(数据量)小时还能应付,但当需要扩建车道(分库分表)时,它就成为了致命的障碍。
3. 性能的“双刃剑”
是的,存储过程在某些场景下性能出色。对于数据密集型操作,由于没有网络传输开销,存储过程往往比应用层代码更快。
有人做过实验:一个需要追溯业务实体间影响关系的功能,Java代码实现跑了30分钟,而存储过程仅用了20多秒。
但这是有条件的优势。在分布式环境中,存储过程的性能优势可能荡然无存。曾经有个案例,一个在测试环境运行5秒的存储过程,在分布式环境中却要11分钟才执行完毕,问题出在中间件服务器与数据库服务器的通讯性能上。
4. 移植性的“灾难”
在数据库迁移或版本变更时,存储过程可能成为噩梦。不同的数据库对存储过程的支持差异很大,用MySQL写的存储过程在SQLServer上可能完全无法运行。
现实案例:一个使用Oracle存储过程的系统,在递归层次很深的场景下运行良好。但当需要移植到TDB数据库时,由于TDB只支持有限递归层次,存储过程直接失败退出。
相比之下,应用层的基础SQL基本上是通用的,修改下连接串就能适配不同数据库。
存储过程与Java代码的Performance PK
既然存储过程有这么多问题,为什么还有人在用?因为在某些场景下,它的性能确实出色。
实验数据显示,在不同数据量下,存储过程的效率都显著高于JDBC、Hibernate和iBatis。在处理10万条数据时,存储过程耗时6秒,而JDBC需要11秒,Hibernate需要17秒。
但关键在于,这种性能优势是有代价的:可维护性、可扩展性和可调试性的牺牲。
什么情况下还可以考虑使用存储过程?
尽管阿里禁止使用存储过程,但技术从不是绝对的。在以下场景中,存储过程可能仍是合理选择:
- 数据密集型计算:当算法需要频繁读写大量数据,且业务逻辑相对稳定时
- 遗留系统兼容:对接现有系统,特别是那些大量使用存储过程的系统(如Oracle ERP)
- 特定性能优化:在性能关键且其他优化手段无效时,作为最终手段
但即使在这些场景下,也需要清醒认识存储过程的代价,并采取适当措施降低风险。
分布式数据库时代存储过程的命运
大多数NewSQL分布式数据库(如TiDB、CockroachDB)仍不支持存储过程。OceanBase是个例外,但它的存储过程功能还不满足生产要求。
Google的F1论文提出了独立UDF Server的思路,将存储过程从数据库层抽离出来。VoltDB则支持用Java语言编写存储过程,使其更易调试和维护。
这些创新试图在保留存储过程优势的同时,克服其工程化缺陷。但总体来看,存储过程在分布式环境中的支持仍然有限。
结语:工程化优于技术特性
阿里巴巴禁止使用存储过程,本质上是工程化考虑优于单纯技术特性的选择。
在大型互联网系统中,可维护性、可扩展性和团队协作效率比单纯的性能指标更重要。存储过程虽然在某些场景下有性能优势,但它难以与现代DevOps工具链集成,无法适应快速迭代的开发节奏。
正如《阿里巴巴JAVA开发手册》主要作者孤尽所说:“存储过程是单机时代的产物,并不适合互联网时代。”
技术选型如同城市规划和建设:我们不仅要考虑建筑的坚固美观,更要考虑交通网络、市政设施等整体生态系统。存储过程就像一栋豪华但孤立的建筑,而微服务、ORM等现代技术则是四通八达的城市规划。
各位技术同仁,下次当你想使用存储过程时,不妨问问自己:这个选择是否有利于系统长期可维护性?是否适应团队的技术栈和工程能力?
在互联网时代,顺应技术发展趋势的选择,往往比单纯追求技术特性更为明智。
参考文献
- https://blog.51cto.com/u_14540126/6209601
- http://mp.weixin.qq.com/s?__biz=MzI0MzI1Mjg5Nw==&mid=2247486621&idx=1&sn=e153142d26058eba43c958fbbb161751&chksm=e8b6bed88317082cfc8ec8fd8c728a6dd66d467e5617645bf523023f200b5ba08c4ce23a1ea2#rd
- https://blog.51cto.com/u_39029/10745419
- https://blog.csdn.net/qq_33589510/article/details/132229106
- https://blog.csdn.net/H_Sino/article/details/136755754
本文主要观点基于以上参考资料,仅代表个人观点,欢迎交流讨论。如果你有存储过程的“血泪史”或成功案例,欢迎在评论区分享!
更多技术干货欢迎关注微信公众号科威舟的AI笔记~
【转载须知】:转载请注明原文出处及作者信息