简单的seo网站优化排名,wordpress整合vip解析,wordpress投稿收费,廊坊网站建设品牌存储过程很好呀#xff0c;那些用不好的人就是自己水平烂#xff0c;不接受反驳#xff01;我就有过这样念头#xff0c;但分布式数据库#xff0c;更倾向少用或不用存储过程。
1 我从C/S时代走来
C/S架构时代的末期最流行开发套件是PowerBuilder和Sybase数据库#xf…存储过程很好呀那些用不好的人就是自己水平烂不接受反驳我就有过这样念头但分布式数据库更倾向少用或不用存储过程。
1 我从C/S时代走来
C/S架构时代的末期最流行开发套件是PowerBuilder和Sybase数据库
PowerBuilder可视化开发工具像VB开发好的程序运行在用户的PC终端上通过驱动程序连接远端的数据库Sybase当时正与Oracle争夺数据库大头和SQL Server有很深渊源两者在架构和语言很像 这C/S架构中数据库不仅承担数据存储、计算功能还要运行很重的业务逻辑相当于数据库同时承担应用服务器Application Server的大多数功能。而这些业务逻辑的技术载体就是存储过程。所以不管是Sybase还是Oracle它们存储过程的功能都很强大。
2 触发器被抛弃
进入B/S大家对数据库理解变化了应用服务器承载服务器端主要业务逻辑那还用存储过程吗和今天问题一样。当时的主流观点认为存储过程还有存在价值但它同胞兄弟触发器则被彻底抛弃。 触发器和存储过程一样也是自定义函数但
它不是显式调用而是在操作数据表时被动触发即执行insert、update和delete时还可以选择触发时机是在操作前还是操作后即before和after的语义
听上去功能强大有点面向事件编程。但维护过触发器逻辑就发现这是大坑。随业务发展和变更触发器逻辑越来越复杂就有人会在触发器的逻辑里操纵另一张表而那张表上又有其他触发器牵连到其他表变成天网。踏错一小步经过一串连锁反应就变成大灾难。所以触发器退出历史舞台。感觉还是没有过多限制导致了滥用
3 存储过程的优点
调用清晰不存在触发器问题。优点明显逻辑运行在数据库没有网络传输数据的开销所以在进行数据密集型操作时性能优势突出。
当时要开发功能追溯业务实体间的影响关系如A影响BB又影响到C。这个功能就是要以A为输入把B和C都找出来当然这个影响关系不只是三层了一直要追溯到所有被影响实体。
典型的关联关系查询适合用图数据库。但那时候还没可用图数据库需在Oracle解决这问题。有一个比我更年轻的同事写了一段Java代码来实现这个功能我猜他没有经历过C/S时代。程序运行起来应用服务器不断地访问这张表处理每一条记录的关联关系。性能可想而知在一个数据量较少的测试环境上程序足足跑了三十分钟。这大大超出了用户的容忍范围必须要优化。
我换成存储过程来实现同样的逻辑因为不需要网络传输性能大幅度提升。最后存储过程花了大概二十几秒就得到了同样的结果。干得漂亮。
4 存储过程的问题
后来发现这方案移植性差。开发的产品要部署到客户环境受相关基础软件制约。
有次刚好碰到客户没使用Oracle所以其他同事将我写的逻辑翻写到客户使用的数据库。可移植到TDB之后的存储过程没跑出结果直接失败退出。跟踪了这段代码最后发现问题不在逻辑本身而在数据库。这段逻辑中我使用了递归算法因为Oracle支持很深的递归层次所以运行没问题而TDB只支持有限的递归层次而当时数据关联关系又比较多所以程序没跑多久就报错退出。
这段经历让我对存储过程的信心有一点动摇。存储过程对于环境有很重的依赖而这个环境并不是操作系统和Java虚拟机这样遵循统一标准、有大量技术资料的开放环境而是数据库这个不那么标准的黑盒子。
然而存储过程的问题还不止于此。当我在C/S架构下开发时就遇到了存储过程难以调试的问题只不过当时大家都认为这是必须付出的代价。但是随着B/S架构的到来Java代码的开发测试技术不断发展相比之下存储过程难调试的问题就显得更突出了。而到了今天敏捷开发日渐普及DevOps工具链迅速发展而存储过程呢还是“遗世独立”的样子。
说了这么多我希望你明白的是今天的存储过程和当年的触发器本质上面临的是同样的问题一种技术必须要匹配同时代的工程化水平与整个技术生态相融合否则它就要退出绝大多数应用场景。
你看《阿里巴巴Java开发手册》中也赫然写着“禁止使用存储过程存储过程难以调试和扩展更没有移植性。”我想他们大概是有和我类似的心路历程吧。
5 分布式数据库的支持情况
大多NewSQL分布式数据库仍不支持存储过程。OceanBase是例外它在2.2版本增加对Oracle存储过程的支持。我认为这是它全面兼容Oracle策略的产物。但OceanBase官方说明很清楚目前存储过程的功能还不满足生产要求。
对遗留系统的兼容可能就是今天存储过程最大意义。对那些从MySQL向分布式数据库迁移的系统这诉求可能没那么强烈因为这些系统没那么倚重存储过程。因为MySQL较晚版本才提供存储过程而且功能也没Oracle强大用户依赖小多了。存储过程没得到NewSQL广泛支持还因架构难题。
看看业界尝试。
Google 2018年VLDB上发布F1新论文” F1 Query: Declarative Querying at Scale”。提出通过独立UDF Server支持自定义函数即存储过程。这架构中因为F1完全独立于数据存储所以UDF Server自然也就被抽了出来。从论文提供的测试数据看这个设计保持较高性能但我觉得这和Google强大的网络设施有很大关系在普通企业网络条件下能否适用这还很难说。 UDF Server的设计
UDF实现了对通用语言的支持除了SQL还支持C、Java、Go等多种语言实现方式。这样不依赖于数据库的SQL方言逻辑表述的通用性更好。UDF并没有耦合在存储层。这意味着它的上下文环境可以更加开放。
这意味存储过程的调试问题可能得到明显改善使其与DevOps体系对接成为可能。
更早的VoltDB也已对存储过程改革。VoltDB是基于内存的分布式数据库由数据库领域传奇迈克尔 · 斯通布雷克Micheal Stonebraker主导开发。VoltDB将存储过程作为主要操作方式并支持Java语言编写。开发者可继承系统提供的父类VoltProcedure开发自己的存储过程
import org.voltdb.*;
public class LeastPopulated extends VoltProcedure {//待执行的SQL语句public final SQLStmt getLeast new SQLStmt( SELECT TOP 1 county, abbreviation, population FROM people, states WHERE people.state_num? AND people.state_numstates.state_num ORDER BY population ASC; );//执行入口public VoltTable[] run(int state_num) throws VoltAbortException {//赋输入参数voltQueueSQL( getLeast, state_num ); //SQL执行函数return voltExecuteSQL();}
}先定义SQL其中“state_num”是预留参数位置而后在入口函数run()中赋参并执行。
VoltDB设计理念与众不同很重视CPU使用效率。他们对传统数据库进行了分析认为普通数据库只有12%的CPU时间在做真正有意义的数据操作所以它的很多设计都是围绕着充分利用CPU资源。
存储过程实质上是预定义的事务没有人工交互过程也就避免CPU等待。同时因存储过程的内容可预知所以能尽早将数据加载到内存进一步减少网络和磁盘I/O带来的CPU等待。
正是由于存储过程和内存的使用VoltDB即使在单线程模型下也获得了很好的性能。反过来单线程本身也让事务控制更加简单避免了传统的锁管理的开销和CPU等待提升了VoltDB的性能。
与其他数据库相比存储过程对VoltDB意义已截然不同。
6 总结
存储过程移植差。高度依赖数据库环境而数据库环境不像操作系统或虚拟机那样遵循统一的标准。因为同样的原因存储过程调试也很复杂也没有跟上敏捷开发的步伐与今天工程化的要求不匹配。正是因为这两个工程化方面原因不用或少用存储过程分布式数据库角度多数NewSQL还不支持存储过程OceanBase作为唯一的例外已经支持Oracle存储过程但仍然没有达到生产级。F1的论文提出了独立UDF Server的思路是分布式架构下存储过程的一种实现方案但能不能适合普通的企业网络环境尚待观察。但这个方案中存储过程的实现语言不局限于SQL方言而是放宽到多种主流语言向标准兼容具备更好的开放性。这提升了存储过程技术与DevOps融合的可能性。VoltDB作为一款内存型分布式数据库以存储过程作为主要的操作定义方式支持使用Java语言开发。甚至可以说VoltDB的基础就是存储过程这种预定义事务方式。存储过程、内存存储、单线程三者互相影响使得VoltDB具备出色的性能表现。
对于任何一个程序员来说放弃一种已经熟练掌握而且执行高效的技术必然是一个艰难的决定。但是今天对于大型软件系统而言工程化要求远比某项技术本身更加重要。不能与整个技术生态协作的技术最终将无法避免被边缘化的命运。当你学习一门新技术前无论是分布式数据库还是微服务我都建议你要关注它与周边生态是否能够适配因为符合潮流的技术有机会变得更好而太过小众的技术则蕴藏了更大的不确定性。 参考
Bart Samwel: F1 Query: Declarative Querying at Scale
7 FAQ
VoltDB的设计思路很特别除了单线程、大量使用内存、存储过程支持Java语言外它在数据的复制上的设计也是别出心裁既不是NewSQL的Paxos协议也不是PGXC的主从复制你能想到是如何设计的吗复制机制和存储过程是有一定关系的。
1.业务代码跟技术代码应该要分离我们需要保证业务逻辑到业务代码的翻译简单而纯粹。这既是在实现阶段降低对具体技术的耦合也是在保证业务代码的可测试性以及业务代码的简单和内聚。 2.具体技术的特性(比如存储过程)往往能起到杰出的性能。但这也增加了实现阶段的复杂性而复杂意味着难维护意味着成本和风险。虽然实现了软件行为价值但架构质量上的健康却受到了伤害。所以在性能要求严格的场景使用具体技术的一些特性无可厚非但要保持警惕认清这是把双刃剑。不可仗着自己功力深厚而肆意妄为。 3.没经历过c/s的时代。但从数据模型驱动设计的相关书籍中,可以看到存储过程在当初是如何的大行其道。可是放在现在当存储过程等一系列手段成过去式后数据模型驱动设计就开始变得很贫血。基本只剩实体关系模型和数据项这点单薄的信息承载能力,已经不适合再驱动复杂的业务软件的设计。 4.放上自己对数据模型驱动的实现以做交流: https://github.com/Jxin-Cai/mdd/tree/master/data-model/mini-faas
VoltDB的这个分片复制和rocketMq的nameserver有异曲同工之妙。通过并行对所有副本执行操作规避副本间达成共识的复杂性。
OceanBase支持Oracle的存储过程迫不得已因为这决定着它是否能 “侵入” Oracle的传统客户阵营-大企业和金融领域是纯商业行为。Oracle 的ERP产品大量采用存储过程来实现业务逻辑最复杂的业务逻辑的源码打印出来几十页这么复杂的存储过程相信OceanBase的工具无法完美处理(移植到OB)但为竞标之类的商业行为你如果不支持Oracle的很多特性你就根本没有参与的机会。
VoltDB用K-safety机制解决数据复制的问题其实就是N1的副本机制VoltDB在写数据操作的时候会在每个副本中执行该语句这样就可以保证数据被正确插入每个副本。这N1的副本都可以同时提供访问同时允许最多N个副本丢失(分区故障), 当N1个副本都不可用的时候VoltDB就会停止服务进行修复。
“《阿里巴巴 Java 开发手册》“禁止使用存储过程存储过程难以调试和扩展更没有移植性。” 有误导嫌疑这里存储过程针对MySQL确实难以调试难以复制。在同等时代的产品产品中以oracle的PL/SQL,SQL server 的T-SQL编写的存储过程还是很有优势DB2和Oracle都支持PL/SQL的这里PL/SQL是具有移植性的并且这个存储过程在SQL标准中叫做SQL/PSM (SQL/Persistent Stored Modules) https://en.wikipedia.org/wiki/SQL/PSM。
阿里开发手册的这条建议不是特指MySQL放在MySQL这一章可能因为MySQL在阿里使用比较多是有代表性的数据库。难道他们一边宣传禁用MySQL存储过程一边暗地里快乐的用着Oracle的存储过程似乎不大可能。
纵贯SQL标准的发展以及oracle的发展存储过程的支持也是有发展历程的存储过程在性能和开发效率上还是蛮高的。在大数据时代人们讲存储分离存储归存储计算归计算在硬件和成本平衡的基础上通过水平扩展来增加算力把存储过程功能暂时不开发或者说难以开发但是Apache hive是支持的存储过程的叫做hpsql。
另外SQL标准对所有数据库都只是参照不同的数据库数据类型、全局变量、函数、甚至存储过程名的长度都有差异。没有完全相同的数据库除非是专门适配。这也是为什说系统切换数据库是个大事。
在分布式数据库中的典型的代表 TiDB和CockroachDB 二者在语法兼容以及对存储过程的支持上有些不同CockroachDB是支持pg语法的存储过程的pg类似于PL/SQL
了解这些差异后有的同学可能依然觉得这不是事so easy。对个体来说难还是易是个很主观的判断关键在于你的团队是否能长期、低成本的使用这项技术如果可以那也未尝不可。
既然存储过程都支持用JAVA了那数据复制应该就可借鉴TCC直接在代码层也就相当于是“服务层”实现而且又基于内存重试成本较低直接用代码往节点里写得了
都是基于内存但与Redis不同应该不会要求那么高的性能直接用线程池同时往数据节点里写数据。
存储过程是单机数据库时代的不可替代的产物当年我当程序员的时候存储过程是最好的解决前后端代码分离的利器。一个10万条订单批量审核的操作调用存储过程几分钟搞定前端vb代码执行一个小时都出不了结果
是的存储过程对于数据密集型计算绝对是一大利器。
clickhouse的物化视图其实是个触发器这种应该从什么角度分析
ClickHouse 中的物化视图(MaterializedView)从机制上来看,确实可以看作是一种触发器。
功能角度
物化视图的作用是对某张基础表进行预计算,实时维护SELECT查询的结果,功能上相当于创建了一个实时更新的缓存视图。这与触发器在数据变更时自动执行预设操作的功能类似。
实现机制角度
ClickHouse通过引擎创建物化视图,当基础表有数据变更时,会自动触发物化视图的更新。这利用了引擎的触发器机制来实现物化视图的实时性。
使用场景角度
物化视图可用于数据分析、Dashboard等需要快速访问聚合结果的场景,取代重复查询,这与触发器的用途有相通之处。
性能角度
物化视图通过缓存提高读性能,但会增加写负载。需要权衡读写比例来决定是否使用。这也体现了触发器的性能权衡特点。
限制角度
物化视图对查询有各种限制条件,这些限制也是触发器通常需要考虑的因素。
综上,从多角度来看,ClickHouse的物化视图确实可看作一种特殊的触发器,对理解和使用物化视图都有帮助。这给了我一个新的角度来分析数据库中的各种自动化机制。