很多朋友习惯以阿里禁止使用存储过程,来鼓吹项目中不该使用它。
我想问的是,阿里那帮程序员,为了不用存储过程,做过的那些努力,你看到了吗?在去 SP 的过程中,所使用的技术与编程模式,你会吗?
SP: Stored Procedure. 即存储过程
人云己不亦云,一直是我对自己的要求。
程序员的独立思考习惯,与其他行业从业人员相比,我认为一直占据上风。出现其他行业“群氓”的惯性思维,概率很低。这是一帮只认 0 和 1 的清醒思考份子。他们谁都不信,只相信自己经手的代码和逻辑。
该不该用存储过程,取决于很多因素。有项目本身因素,也有人员配置因素。
抛开项目说策略,就跟不以结婚为目的的谈恋爱一样。一个简单的匿名留言板,用贵上天的 Oracle 干吗,用 MongoDB,用 ElasticSearch,甚至用 Redis,不香嘛!
对信息系统理解不全面,脑袋里只有 OLTP 系统, 眼里只有 CRUD 一类的 M-I-O 应用,那么自然会觉得存储过程没有用的必要。用 Java, PHP 完全能胜任数据一进一出的功能。甚至能做得更好。
比如在迁移数据库的时候,在更换数据库软件的时候,只需在前端的 Helper, Utility 类中,更改下数据库驱动和连接,即可实现无缝转换。假如此时要把存储过程从 SQL Server 迁移到 Oracle 上,那必然得重招一批数据库开发。成本巨大,且不宜长久的事,哪家公司会做这样的好人?
再比如,在对接异构分布式数据库的时候,由前端语言接口,封装好对数据库的访问以及路由,就能自动承接各数据库来的各类型数据结构。关系型也好,半关系型,甚至离散数据,都能友好地组织起来。要用存储过程来实现,那必然要在数据库动态库上编程,使其适应各类平台的连接,参考 SQL Server HDInsight 对接 Spark 引擎的实现。
显然,动态链接库增加了数据库的复杂性和脆弱性,且不如前端实现,那么灵活与可扩展。写一个连接服务,部署到 10 台应用服务器中,就能扛起 10 倍的流量。而写一个动态链接库,放一台数据库服务器中,撑起的流量不变。
OLTP: Online Transaction Processing, 在线交易系统, 在线事务处理系统 CRUD:Create Retrieve Update Delete 即增删改查 M-I-O: Message IN And Out 消息输入输出
看到这,似乎没有一条有利于存储过程的存在。那是不是小编我就鼓吹不用存储过程了呢?我把开头的话,再讲一遍,抛开项目说策略,就跟不以结婚为目的的谈恋爱一样。
时刻保持脑子可以清醒思考,是程序员的重要素质。
除了 OLTP,这世界上还有一种叫做 OLAP 的应用。OLTP 系统运行多年后,承载了大量的用户数据,订单数据,行为数据。像用户画像,漏斗分析,运营决策这样的应用,大家耳朵上的茧子都听得长厚了。
这些需求一旦展开,往往牵扯到跨时长达3,5年的查询,数据量巨大,引起大量 CPU, Memory,IO 的开销,足够摧毁正常业务操作。说人话,一张报表拖死一个应用,常有的事儿。
OLAP 技术便应运而生,除了要给足这些应用硬件资源,还要搭配一些软件设计模式。在这个成熟的 OLAP 领域,不得不提 Kimball 和 Inmon 的维度建模思维和实战。广为大家所知的,便是 ETL ,Reporting 和 Data Modelling. 在整个数据管道的过程中,如果计算下聚合,都要跑前台应用程序过一遍,那么数据的流入流出,就已经花费极大的宽带流量和时间了。所以落地这些大型计算和存储,必定要存储过程来承担。
可能大家都知道,就连 Hadoop/Spark 都强调数据本地性的调优法则。这大概正是从数据库的存储过程中得到的启发。
OLAP: Online Analysis Processing, 在线分析处理
存储过程将会在很长一段时间内,继续占据商业数据库应用市场。但 NoSQL 以及分布式大数据平台 (可看成 NewSQL)这支力量,也不可小觑。很多应用不再以数据库为中心,更多采用去中心化设计。
比如以往记录日志,会选择以数据库为存储,不仅耗费大量昂贵的数据库存储空间,还加大数据库的开销。自从 MongoDB,ElasticSearch 出现之后,日志类文件最佳使用方法,便是记录到这些 NewSQL 数据库中。
这些数据库不仅仅以廉价的机器作为存储,更可以负担一些以往落在数据库上的操作。并且,这些系统出现时,就瞄准了传统商业数据库难以水平扩展的难题,他们的架构使得水平扩展集群性能变得容易。
配以这幅图,这肯定不难理解。
当中央数据库被划分为 5 大地区数据库后,服务能力提升是明显的。但传统数据库就没有这么好的扩展性。所以各家数据库服务商拼命地都往云上赶,就是这个道理。云服务扩展的便利,简单得令人发指,千百台机器,点击便可完成。前提当然是,甲方爸爸非常有钱。
那么,存储过程在这个时候,就不得不让位于分布式编程。如果写SQL的朋友,一直不往其他领域扩展,等到有大数据分布式相关项目的时候,就只能眼睁睁看着机会溜走。岂不可惜?
但,是不是这些 NoSQL,NewSQL 能直接取代传统数据库了呢,并不是。举个例子,他们现阶段难以掌控的事务控制,像MongoDB, ElasticSearch,事务控制加在了文档一层,单个文档可以保证ACID,但多个文档就需要程序员自己控制。像Redis这样的缓存级数据层,在多表聚合这类操作上,还要大大依赖前端开发人员的编程实现。
即使有程序库可以完成这些操作,那也将是类存储过程的这种实现,像MongoDB用 JavaScript 模板。那么为什么要放弃团队中会存储过程,这种已经熟得不能再熟的技术呢?这不是每个程序员必会的技能么。
程序本质上是人类思考的结果,无论用存储过程还是Java,PHP前端语言(与数据库后端相比,其他语言都可划为前端),我们完成的始终是业务的计算。那么自然是哪个方便,用哪个;哪个最有效率,用哪个。
与其纠结于用什么实现业务逻辑,倒不如考虑业务复杂度和团队协作便利性。如果有全栈工程师,从前到后,都可以玩得来,那么就让他快速迭代产品。如果前端工程师对数据库有认识上的偏差,对于调优和事务不能很好控制,又或者项目紧张,一个全栈工程师忙不过来,那么就把前端和后端独立开来,招两端各自优秀的工程师,各司其职就好。
但无论怎么样,我们最好前后及后都懂些,然后选一个精通。这可以完美避免,互相指着鼻子骂对方是猪队友的尴尬情况。
前:除了数据库, 其他都可称前端; 后:存储基础业务库的数据库端; 及后的后:服务 OLAP 的数据平台,即包括数据库,还有分布式大数据平台。 Lenis,公众号:有关SQLBI, 数据仓库,ETL, 数据开发,有什么区别?