工作中,看到很多文章都是告诫开发者,逻辑控制最好都放到应用层,而且很少看到触发器,函数,存储过程的实际应用,一般都是直接 insert update delete select
这 3 条理由应该都很常见
1.应用了存储过程,函数,等执行效率会下级很多。导致很多人不敢轻易使用上述功能
2.增加开发难度,不但需要维护应用程序代码,还得维护 mysql 的相关代码
3.数据库的计算资源非常宝贵,能在应用层完成 就放在应用层。
然而既然数据库有相关的功能,为什么不利用起来呢?
1.解放双手,少写很多代码。
2.都是代码,理解了代码的功能,一样一样的维护。
3.貌似无法反驳,在极端的情况,少一个资源竞争,多一份稳定。但是应用端的资源也是资源,利用的好应用端资源也给节省了
触发器,函数,存储过程 我们都应用到了
触发器的例子 1:
https://wuhao.pw/archives/268/
1.效率。编辑一条数据,这个效率上损失,无伤大雅
2.写好了,几乎不要动了
3.
1
adoal 2021-11-30 12:47:12 +08:00
因为他们以为他们做的实际并发不超过 10 个的信息系统要面对的应用场景都是阿里爸爸的双 11 秒杀……
|
2
adoal 2021-11-30 12:49:03 +08:00
以及,他们唯一知道的免费数据库是 MySQL ,这玩意长期以来在数据库高级功能上的实现确实比较烂,靠这些半身不遂的实现还真不如写到应用层。
|
3
MoYi123 2021-11-30 13:21:38 +08:00
mysql 里各种老版本的问题遗留下来的规矩多的要死.
我在试用期就跑路的一家做电商的公司. 库存总是会产生负数,虽然我也不知道这个东西为什么这么难, 我就建议弄不好就写个存储过程吧, 至少一定不会出问题吧. 得到回应是: 有 bug 事小, 写存储过程坏了规矩事大. |
4
6IbA2bj5ip3tK49j 2021-11-30 13:50:39 +08:00
我来解释下:
1 和 2 是因为大多数开发并不会写,公司也不情愿招一堆 DBA 来写这玩意儿。 3 ,倒不是资源珍贵,而是服务层面的水平扩容和数据库扩容难度不是一个级别的。 简单说, 1 ,公司想省钱,不想买商业软件,也不想额外花钱请 DBA 。 2 ,公司觉得自己以后会很牛逼,不想被绑到某个数据库上。 历史发展的必然。 |
5
hand515 2021-11-30 13:53:37 +08:00
实际经历过后,我也不推荐用存储过程写业务逻辑
那种痛苦真的是不经历过就体验不到 |
6
thevita 2021-11-30 13:58:11 +08:00
我觉着可维护性应该不怎么好
|
7
onhao OP |
8
zjsxwc 2021-11-30 14:43:00 +08:00
我只是单纯觉得,如果以后要在存储过程中加业务,比如需要对存储过程业务业务中访问 redis 获取别的数据时,mysql 存储过程里好像很难实现。
|
9
onhao OP @zjsxwc 还是看需求了, 如果需求常常变,只要 mysql 还能胜任,那就无妨。当然像需要 redis 来协作的显然用 存储过程就不适用了。
|
10
wangxin13g 2021-11-30 16:47:28 +08:00
然后你后期数据要换 pg 换 mariadb 换其他支持 Mysql 协议的数据库,之前的所有用了数据库自带功能的怎么办?
|
11
adoal 2021-11-30 17:04:04 +08:00
@onhao 因为阿里爸爸之类互联网大厂为社会输送的架构师们薪水高,话语权大,抱团刷价值观,所以在各行各业做传统信息系统的被他们的技术路线绑架了,很少会去考虑这些大厂推崇的技术路线是否适用于自己的场景。
|
12
shuimugan 2021-11-30 17:10:45 +08:00
用存储过程的话,负载均衡,灰度发布,版本控制,扩容、限流、这些咋搞?
特别是扩展,在 serverless 架构上,你想弹多少个实例都可以,费用也不高,应对高峰期很方便。但是到了数据库升级配置,你可以选一个最高档的看看价格… |
13
adoal 2021-11-30 17:13:32 +08:00
建议楼主说说自己工作中所开发出来的系统的实际业务场景,是互联网还是传统信息化。
|
14
cweijan 2021-11-30 17:34:59 +08:00
存储过程和触发器虽然理论上性能会好点, 但代码相对面向对象语言而言难读, 从而难维护; 现在的系统只希望数据库用于存储数据, 不做应用层的逻辑, 否则相当于需要维护两个应用.
|
15
supuwoerc 2021-11-30 17:56:51 +08:00
之前 V2 讨论过一次,我看了看,大家一直觉得程序好维护,迭代,排查问题,数据库层面很多开发并不是专门的 DBA ,而很多中小公司是没有专门的 DBA 的,并且貌似还有数据迁移,版本迁移的各种适配问题,数据库版权,服务器扩容成本等等问题,所以开发不愿意用存储过程之类的玩意,后来我问了问在大厂的师兄,他说他工作的两个大厂,6 年时间团队都不让用存储过程。
|
16
aguesuka 2021-11-30 18:13:18 +08:00
可以实现一个乞丐版的日志, 勉强能在编译前给出编译错误和警告, 虽然没有模块和私有函数不过可以用名称代替, 勉强可以把 create 语句放在 GIT 或 SVN 上, 可以打断点调试, 还能手动执行.
马马虎虎凑合吧, 能有这个想法的人说明没维护过老代码, 体验一下也不失为宝贵经验. |
17
sujin190 2021-11-30 18:25:20 +08:00
这和性能不性能的无关吧,和维护及开发效率有关吧
现实来说,太多情况需求三天两头变,很少有按固定产品需求开发测试然后交互就结束的,直接用数据库且不说面对需求频繁改变确实有些吃力,而且吧正因为改变太快太多,所以恰恰需要一个稳定的存储逻辑,业务逻辑做在数据库里你就不怕三天两头改的时候直接把数据库干废了么 再者吧数据库毕竟是查询组织管理数据的,对业务逻辑的表达能力本来也不强,何不把数据和业务流程组织过程放在一起,这样且不说更直观,而且对人员的要求也降低了,毕竟如果后台用 php 的话,招人来做看 php 就行,数据库你会增删改查也就行了,要求可是降低很多的吧 |
18
jtwor 2021-11-30 19:10:51 +08:00
旧工地就是用存储过程、触发器写业务,代码无法管理控制。存储过程调试依赖工具,生产无日志排除难度高。批量更新触发器就会低效。这还是单表的情况,分表分库运维成本很高。如果换数据库,语法不同又要写一套。还有一个最大的问题,大部分的程序员 sql 水平就删增查改,很多 ORM 用惯了,sql 都不会写的。
|
19
ychost 2021-11-30 19:29:51 +08:00
一般情况 SQL 都懒得写,ORM 一把梭,只有离线数据分析的时候会用到 SQL ,像阿里的 MaxCompute 都有 Udx 这种插件再 SQL 里面跑 Java Function 也挺舒服的
|
21
wdlth 2021-11-30 23:19:16 +08:00
现在大都是微服务的设计了,进一步的有 CQRS ,很多数据源是根据领域进行设计的,单个数据库的存储过程难以完成,更别说有分库分表逻辑的大中型系统了。
|
22
onhao OP |
24
hallDrawnel 2021-12-01 01:23:50 +08:00
无法实现灰度发布之类的吧。我记得存储过程要改就是一把梭改完。如果出问题了回滚也是一把梭回滚(当然数据层面的改动能不能回滚另说)。这样很可怕啊。以及存储过程无法打日志,出问题了只能靠输入输出人脑 debug ?
|
25
2i2Re2PLMaDnghL 2021-12-01 10:10:07 +08:00
@hallDrawnel 建一张新表叫做 log 把日志打到里面去(
|
26
Fule 2021-12-01 13:55:32 +08:00
合适的场景用合适的工具,有些场景用存储过程、函数无论是开发难易度、执行效率、部署便利性都是极高的,毕竟数据库就是专业处理集合数据的,对集合数据的处理同等硬件条件下应用层写出花来效率也不会比数据库自己操作高,把数据库擅长的处理放在应用层,更多是牺牲效率换取可伸缩性。要说难以版本管理,确实,不过可以做一些自定义规则和工具缓解。开发不就是一个权衡么,针对特定场景,针对可维护性、执行效率、伸缩性等等一系列因素的侧重点不同,利大于弊就用,弊大于利就不用。触发器的最大的问题在于隐蔽性,属于“偷偷摸摸”就把事儿办了那种,所以这个确实慎用。
|
28
adoal 2021-12-01 15:12:27 +08:00
@Fule 还有就是,我听到过一些案例,一开始去关系数据库,后来逐渐在应用层根据业务需求用 Java 代码来实现各种约束和抽象,相当于自己实现了关系数据库的部分功能。那问题来了,我是相信基础设施大厂和知名开源团队里专职做 RDBMS 的研发实力做出的实现呢,还是相信互联网大厂做秒杀出来流到行业信息化里的应用系统架构师们带着一堆北大青鸟、达内的 CRUD boys 在应用层做出的实现呢?
|
29
huiyanpohundh123 2021-12-01 15:43:13 +08:00
存储过程抽象层级不够,写的代码贼恶心
|
30
adoal 2021-12-01 15:49:51 +08:00
看下来,对 RDBMS 持反面意见的有三种。
一种是出于架构的角度,尤其是 scalability ,针对互联网大厂的应用场景,高弹性,高并发,数据量巨大,实时一致性要求低,确实知道自己为什么要去 RDBMS 。 一种是出于软工的角度,虽然也可能认同 RDBMS 的高级特性是好东西,但出于版本管理、RDBMS 迁移、CI/CD 的角度,还是选择把数据库当简单的存储表来用,这算是一种 tradeoff ,有舍有得。 还有一种是,没有专职 DBA ,广大“程序员”不懂 RDBMS ,所以把数据库当简单的存储表来用……在这里,程序员三个字可能被简化为这样一种气质(根据我在行业信息化工作中遇到的不少所谓程序员来看),大概自学或者在培训班学习了某门主流编程语言的基本语法,然后就在师傅的带领下进入业务系统的开发,有心于技术的可能会在实践中学习设计模式和软件架构,不是很有心的,可能会去钻研业务场景或者管理知识,慢慢脱离技术岗位。然而即使往高级技术路线走的这些 crud boys 其实技术体系是不扎实也不完整的,他们缺的不只是数据库知识,对操作系统(哪怕不涉及原理和内核,只是生产环境的 Linux 规范化使用和写脚本、业务系统所依赖的基础服务器软件比如 web server 的常用配置)、网络、编程语言(是说编译等,不是指会简单的语法)、信息安全也没有系统化的学习,甚至连培训班这样浮躁的系统化学习都没有。他们认为的开发、编程,在技术层面上就是指会用某种编程语言本身。悲催的是,大多数地方性的、行业性的小信息化公司里这样的程序员还要兼在客户的生产环境上做实施。我遇到过很多这样的乙方程序员甚至技术经理,真的很无奈。 |
31
wdlth 2021-12-02 22:20:39 +08:00
@onhao 存储过程应该是最常见的,特别是 BI 类的系统,会用存储过程做查询、计算和聚合等。
UDF 函数的也可能使用,不过触发器比较少,性能开销太大了。 |
32
onhao OP 触发器是特殊的存储过程,性能开销大,并不妨碍使用他,在低频操作下,用他就很合时宜。甚至高频操作 带来的性能损失只要在一定的可接受范围内都可以用,如果实在有碍于系统运行了,适当的性能调优即可。
@wdlth |
33
uselessVisitor 2021-12-06 20:34:45 +08:00
存储过程可读性可太差了,你知道老项目,存储过程里面套了好几个视图,中间表多难看懂吗?
触发器?不懂业务的生产出现问题最多的就是触发器,debug 都不知道数据为啥变了,最后发现是触发器。 函数还行,我们也在用。 |
34
onhao OP @beichenhpy ^_^ 兄台,触发器不是你自己写的吧,上一位兄弟说的非常形象"偷偷摸摸”就把事儿办了那种。你这属于项目交接问题。
|
35
ouyc 2021-12-08 15:03:28 +08:00
个人看法:并发少的,数据库服务器和应用服务器资源有多余的,写那都可以。并发多的,应用服务器好扩展,数据库怎么扩展?而且本来编程就挺难的,还要整高级 SQL ,还要不要下班了
|