木匠的微型博客 Charlie Twitter

    follow me on Twitter

    Tuesday, November 20, 2012

    将数据处理逻辑SQL放在数据库后端的存储过程到底好不好? data logic SQL in Database vs in Web Application server


    将数据处理逻辑放在数据库后端的存储过程到底好不好? @诸超_小石头爸爸 是反对的, @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年冬天

    3 comments:

    20 Percent Useful Tech Tips said...

    there is no absolute good or bad solutions in IT world. talent and experienced people intend to make good move in either side.

    ORM is good concept if the developers are not lazy and use just what being provide by default. good solutions provide cache feature so that network roundtrips becomes not a problem.

    when web was introuduced, the entire IT world was talking about advantages about thin client,middleware then became popular and turns database just a storage. ASP and nerwork pc were old and unsuccessful comcepts until they were renamed to cloud computing. the difference now is even with cloud computing, web client is absolutely fat and rich with ajax...

    so things do evolve, and trend is to merge with each other....

    Unknown said...

    @Andrew Ma,

    观点是对的. 来点具体案例吧. 太虚,摸不着.

    -木匠

    lewvip said...

    刚刚拜读,双方都有道理(我最讨厌这么没观点的说话了),这个还真得看具体案例了。不过老板最喜欢的观点是系统容易维护,而不是技术瓶颈。