• 用存储过程还是用嵌入式SQL语句


        最近与同事在存储过程的问题上发生严重的分歧了.
    他认为程序中几乎不应该出现sql 语句, 所有的访问数据库的动作, 都应封装成存储过程. 而我不喜欢存储过程, 不到万不得已, 我不会使用存储过程.

    我的想法:
    <1>效率.
    <1.1>先考虑简单sql 语句, 所谓简单, 比如只有一个select/update/insert/delete 语句, 对简单sql 语句来说, 与存储过程的差异在哪里呢, 存储过程只是预先编译过了, 也就是说, sql语句的执行时间=编译时间+ 执行时间, 而存储过程只有执行时间, 没有编译时间. 而两者的执行时间应该是一样的, 对于简单sql 语句来说, 编译时间非常小, 可以忽略不计, 虽然没有确切的数据, 不过我认为我的这个推断应该没有什么问题. 也就是说, 从效率上讲, 简单sql 语句与存储过程没有什么区别.  我用过各种各样的简单sql语句测试, 这其中也包括链接十几张表的复杂查询, 执行时间跟存储过程没什么差异.
    <1.2>复杂sql语句段. 要声明一下, 我认为很长, 譬如几十句, 甚至上百句的sql 段根本不应该存在. 因为比较长的sql语句段一定会包含许多"逻辑" 处理, 而不是"数据" 处理, 举个简单的例子, 像left 这样的字串操作函数, 我觉得根本不应该出现在sql 语句中. --------在服务器中, 数据库服务器是压力最大的服务器, 也是最关键的服务器, web 服务器相对来说压力就小得多, 同等的工作, 应该优先考虑由web服务器来负责, 而不应该转嫁给数据库服务器. 另外, sql 语句虽然经过编译, 但是在类似left 这样的函数处理能力上, 比由C# 这样的高级语言的处理能力还是差得多(这一点不需要证明吧...) , 所以, 我认为所有的逻辑判断, 业务处理, 都应该由高级语言处理, 而sql 语句只处理数据, 这样也可以保证将数据库服务器的压力降到最小.  这一观念的推论, 就可以得出, 长长的sql 段是要不得的, 虽然存储过程擅长sql段, 但是我的程序会保证总是提交给服务器简单sql 语句.

    <2>安全性.
    提到存储过程, 就会常常提到它对用户的分隔能力, 可是在我参与过的三四个大型项目来看, 这种能力几乎毫无用处, 至少在我所参与的ERP 项目中, 它是毫无用处. 因为最终用户根本不会, 也无需, 也不可能去了解数据库层的东西, 他们只是要求打开一个页面, 可以展示一个报表, 或操作数据, 或完成某个流程等, 实际上, 即使使用存储过程, 在程序中也总是以某一个高权限用户去访问所有的存储过程.

    <3>可扩展性.
    从这个角度来说, 存储过程就处于完全没有竞争力的地步了. 一个页面很可能会发展变化, 但是每次升级都改动存储过程显然是一件危险的事, 事实上, 一个存储过程一旦写完投入使用, 就很少有人敢去改它. 而sql 语句则可以任意的升级,变化.

    <4>可管理性.
    由于任何一个项目在其漫长的生命期中都很难预测它到底会膨胀到多大, 所以存储过程的数目也会急剧地增加, 几百个存储过程是很稀松平常的事, 大型项目的存储过程达到几千个一点也不夸张, 如许多的存储过程, 要管理并记清楚每一个存储过程所完成的工作, 实在不是一件容易的事. 尤其是, 写这个存储过程的人离职后, 新来的人多半会被大量的存储过程难倒.

    <5>我个人认为使用存储过程很麻烦, 远不如sql语句来得方便.

    <6>借助于将表映射成类, 可以很好的支持表结构改变, 这主要是针对从零开始开发, 因为在第一次设计中, 不可能将数据库的结构设计得一次到位, 如果到了后期修改表结构, 所有的旧引用都是运行时错误, 而类型化的sql 语句则会变成编译时错误, 只要全项目替换一下就可以了.

    因此, 我的结论是,
    <原则1> 只有在很复杂, 需要大量的sql语句时, 才应使用存储过程.
    <原则2> 应把所有逻辑处理转移到web服务器, 除极少数特殊情况外, 不应使用sql段.
    根据这两个原则, 就很少会有使用存储过程的机会了.

    但是, 由于对存储过程缺乏更深入的理解, 所以我对上想法也并没有太大的把握 , 在网上查了不少东西, 也罕有有用的文章, 多半是隔靴搔痒, 或是给新人看的, 或是语焉不详, 一笔带过, 所以就先贴在这儿, 大家在扔砖头之余 , 希望能详细地谈谈这个问题, 也好有个确定的答案.



    看了大家的评论, 既有收益, 还是有点无奈, 与我现在面对的状况基本一样, 大家的观点也分成两派, 而且看起来人数也相当, 不过好几位一面倒认为应该使用存储过程的兄弟, 都是"唯心" 式地认为存储过程就是好, 效率就是高, 或者不加说明的下结论, 呵呵, 我觉得这种观点对别人的帮助就很小了, 可能是懒得打字吧.
    针对大家的回复, 我再谈几点我的看法.
    首先声明, 我是做ERP 的, 系统运行在内网, 公司的网络设施也很好, 所以网络传输部分的代价几乎可以忽略,
    另外, 项目的源代码有80多MB(不含图片), 有四五家分公司, 数万人使用, 数据量之大不用说了,当然, 维护也是我们. 有专门的DBA, 但是他很少会管存储过程, 存储过程主要是由我们的项目经理写的.  
    我觉得这种环境应该是比较典型的, 写公网上的系统的人应该不会很多吧?

    to:@Happiness is enough(21楼)
    你说的比较详细也比较中肯, 不过, 你说"没有任何理由可以说明一个project中的成百上千个类和方法不会带来灾难."  这句话我无法认同.  不要说成百上千个, 在.net framework中, 类和方法不止上万吧, 可是也没有带来灾难. 因为类可以按它的用途等等进行层层归类, 而方法封装进类中, 如果这种结构设计得好的话, 即使数量很多,也很容易管理. 另外, 借助于IDE 的智能感知, 以及XML 注释的威力, 我们也无需背下来这些类和方法的名字, 用的时候看一下就可以了. 而存储过程就没办法进行这样的管理.
    @koenemy(37楼)
    说"你在告诉你同事,,不是几乎,应该是根本,访问数据库的方式要一致。"
    这句话的后半句我很赞同, 而且事实上几乎必须这样操作, 虽然说, 有的情况比较适合用存储过程, 有的情况比较适合用嵌入式语句, 但是, 在项目的管理上来说, 除非极少数的特殊情况要求, 否则应该用一致的方式来操作, 这也是我觉得为什么一定要在这两者之间挑一个出来作为"主力" 的原因. 因为在项目中还有很多"模棱两可" 的情况, 必须有一个优先的选择.
    -----------------------------------------------------------
    ︶ㄣ九蜘蛛也来说两句:
    在服务器中, 数据库服务器是压力最大的服务器, 也是最关键的服务器, web 服务器相对来说压力就小得多, 同等的工作, 应该优先考虑由web服务器来负责, 而不应该转嫁给数据库服务器.

    Transact-SQL 写在存储过程里、写在CODE里,最终还是由数据库执行的。
    写在CODE里并没有减小数据库服务器的压力。不过在实际操作中,大多数还是写在CODE里的
    我们的追求良好的用户体验程序安全健壮、程序的高效系统配置方便灵活、结构清晰……




  • 相关阅读:
    Oracle去除重复(某一列的值重复),取最新(日期字段最新)的一条数据
    eclipse中的项目无法添加到tomcat中
    Myeclipse查看当前项目工作空间
    oracle查看表中否存在某字段,数据库是否存在某张表
    Java中Double原样输出,取消科学计数法
    DateTimeField *** received a naive datetime (***) while time zone support is active
    JS 将UTC时间转为本地时间
    Python与Django的时区问题
    在Django / DRF中正确处理日期时间/时区
    django时间的时区问题
  • 原文地址:https://www.cnblogs.com/netwom/p/950823.html
Copyright © 2020-2023  润新知