将数据处理逻辑放在数据库后端的存储过程到底好不好? @诸超_小石头爸爸 是反对的, @OracleAskTom 是坚决推广的.这一点,我和Tom站在一边. 希望有一天和ChaoPing兄弟来个辩论会,互相学习到有益的经验. 两个人辩论肯定比一个人讲更有意思,更能吸引到听众的注意力.
把问题具体细化一下. (data logic)SQL放在哪里?
追加一个细化条件: 99% 纯SQL, 基本没有CPU运算 的 数据处理逻辑.
关于如何区分 UI, business logic 和 data logic :
http://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_ID:5662105500346364576
先谈谈我的亲身体会.
案例 1,
当今社会,网络成为瓶颈的机会很大. 我们有个登录事务,4个简单SQL,查序列号,删除旧曲奇,插入新Cookie,COMMIT.一共四次网络传输,如果改成存储过程,只需要一次网络传输,网络立刻畅通. @yong321 @诸超_小石头爸爸 你们怎么看?
案例 2,
十年前, Java developer写了一个客户订单查询系统, 没有做分页处理, 随着时间的推移,用户数据量越来越大,查询响应时间越来越长,极大的浪费了数据库资源. 可是开发人员不对数据库负责,总是提不上他们的议事日程.
这是一个简单而至关紧要的关于控制权和责任的问题, Control and Responsibility.
Facebook说了, Control and Responsibility是他们成功的最重要因素.
参考文章: Scaling Facebook to 500 Million Users and Beyond
http://www.facebook.com/note.php?note_id=409881258919
案例 3,
在我们的好多关键业务模块,同一条一模一样的SQL被执行了好多次,连绑定变量值都是一样的.
Java developer非常依赖ORM, 而且懒得写SQL,或者草草了事,不在乎或者不知道SQL的执行效率.
同上一个案例一样,除非该模块导致数据库停机,他们懒得修改,也不负责任.
相对来说, Java developer写出的SQL要比数据库专业开发人员写出的SQL效率低二到十倍.
(因为鄙人经常能够经过重新设计一些功能模块,提高数据库处理效率五到数十倍)
所以,很多情况下,你根本就不需要水平拆分split, 一个新的优化的设计,就帮助你解决扩展性问题.
还节省了购买新软硬件的成本,降低了因为拆分导致的系统复杂性.
补充一点, 就算是拆分了以后, 你依然可以调用后台存储过程, 中间件应用服务器只需要做一个分发调度器就可以了. 某书店的工作流软件就是这么实施的,大概拆分出十多个数据库.
案例 4,
接着 案例1 的上下文, 其实前3个SQL可以简化成一个SQL INSERT,就解决问题了,
取序列号可以省掉,替代主键索引可以省掉, DELETE可以省掉, 查询配合B+树索引 +INDEX_DESC hint, SELECT 取最新的一条记录就行了, 逻辑读恒定,不会随着数据的增长而增加. INSERT比UPDATE/DELETE引发更少的阻塞锁.
Java developer一般不在乎或者不知道高效SQL,也不是非常了解数据库是如何工作的.
而且他们控制了代码,又不对数据库的问题负责任, 这个, 很难...很难! 这个就是普遍的现实,我们不能活在虚幻当中.
所以要着手解决现实问题. 由数据库专业人员来控制数据库存取的SQL代码.
备注:
@yong321 要求拿出Profiling数据,证明网络是瓶颈.
这一点很好, Critical Thinking: Be critical to what you hear and read. "Critically Analyze What You Read and Hear" 要的就是积极主动的分析思考, 批判性学习. 而不是被动的接受信息.
我们有完整的 Profiling 数据, 剔除敏感信息以后, 性能剖析分析矩阵会被补充进来.
@诸超_小石头爸爸 建议用匿名PL/SQL块(Anonymous PL/SQL block), 也能减少网络传输, eBay就是这么做的.
反方意见:
@诸超_小石头爸爸: 关于业务逻辑作为存储过程数据库里面:如果database不需要licemse我不反对,如果database和app一样容易scale我不反对,如果我是oracle vendor我不反对。如果是传统企业或者很小业务我不反对,如果注定做不大或者就是尝试快速试错我不反对。如果没有7+24的可用性要求我不反对。如果 (11月4日 22:40)@推车老王: 把业务逻辑放在数据库中?不谈别的,从可扩展性来说是增加APP服务器方便,还是split数据库方便?根本就没有可比性啊!从系统运维角度来看,系统规模越大,业务层与数据层分离就越重要。
@刘德伟goodxp:赚钱不等于正确。没听过技术债吗?欠了多少没人知道,我面试时就遇见过编个理由离开原公司的,因为已经搞不起了,老总还当功臣留他。存储过程效率高,但很难维护,如果逻辑复杂还是应该放在Daemon里,数量多的话可以考虑做一个业务规则引擎。
@yong321:I agree with 推车老王 and 刘德伟. If logic is or will be complicated, it's better stored at app layer; easier to scale up and make it OO (if needed). Otherwise, put it whichever has free CPU capacity.
各位老大说了: It depends.
一定要根据自身条件,设计出能够解决自身问题的合适方案.
这些反方意见对我们目前的情况来说,都不是问题. 我们目前最大的问题就是命名规范. 如何简洁明了的把相关功能特性组织在一个模块里面,使重用最大化.
欢迎各位看官猛烈评论, 给出积极的建设性意见.
-木匠, 2012年冬天