zoukankan      html  css  js  c++  java
  • SQL,SP与ORM

    SQL译为按每一次情况的办理,SP意为存储过程,ORM就是对象-关系映射,比如Hibernate
    一,演变
      刚开始的时候,只有sql语句,即可以用交互模式一句一句执行, 也可以用批模式执行,多行sql语句一次提交执行。
      很快人们发现用批模式执行的一堆sql语言可以用过程的形式,事先存放到数据库里面,这就变成了存储过程。
      随着面向对象技术的成熟,从程序中可以自动生成sql语句,这就是ORM  

    二,性能
      如果我们把一堆sql,以批的方式一次送入到服务器,那么服务器,会对这一堆sql进行缓存,当下一次再度执行的时候,就好像调用一个”匿名“的存储过程一样。在这种情况下,性能差不多。
      但是,如果我们不注意,很有可能,把可以一次提交的sql,变成了多次提交,甚至是每个循环做了一次提交,那么性能就很差了,也就是说如果使用sql,只要写法得当,性能和sp区别不大。
      同样的道理,ORM的性能取决于ORM的Sql生成算法, 和用户使用的时候,对生成算法的控制,比如利用好Lazy laoding等,在某些情况下,甚至可以不通过sql,毕竟没有sql比最优化的sql还要快。

    三,可维护性

      可维护性是选择sql,sp,orm最主要的因素。
      刚开始的时候,sql的维护性看起来是最差,因为它往往散布在程序的每个角落。而存储过陈都放在数据库中,有清晰接口。
      但是如果我们做一次重构,情况居然会颠倒过来。
      首先,存储过程完全可以照搬到C#中,sp的名字直接变成method的名字,sp的参数表直接变成method的参数表,(其实就是Command模式)。
      其次,把这些methdod放到一个文件或者文件夹中。(所谓的DAL层,如果喜欢层的话)
      通过这个重构,我们获得了以下的好处,

      1,首先是过程的调用和过程的定义放到了一起,修改起来比较方便。IDE都有定义跳转功能。
      2,过程的调用和定义同时进行版本控制,不会出现不匹配的情况。减少了sp的参数表和调用的不匹配,包括拼写,类型,参数次序
      3,单元测试非常方便

      当然sp也有存在的价值,比如所谓的安全性,后面会提到。比如友好的调试环境,对于中小型项目,和初级程序员来说,也是很好的选择。  
      ORM则将可维护性提升身到了一个新的高度,它试图将sql屏蔽起来,在操作对象的同时,自动就把数据库的事情给办了。
      ORM有两种模式,一种是ActiveRecord, 一种是Datamapper,前者从数据库中读取定义,后者在程序中定义。不过由于前者往往用migration来生成数据库,其实也是定义在程序里面的。好的ORM都有"leaking"的设计,也就是留了个”后门“,让你有机会用sql来控制。  
      微软的linq从某个角度类说,也是一种ORM, 它的设计思想可能是因为它觉得写sql语句比写c#代码效率高,所以提供直接在C#中写sql语句的机制,再自动生成真正的sql。不过,ORM真正价值在于它可以在恰当的时候,完全抛弃sql,比如比如读用cache,写用queue。而微软的linq,完全是“无厘头”的风格,在O中用R的写法,难道是RRM, 唯一的好处只是锁定程序和程序员在微软的平台上。

     三,安全性

      对企业来说,安全性有的时候比性能更重要,由于存储过程在数据库上多加了一道屏障,所以很多企业会把存储过程作为首选。
      ORM可以说是安全性最差的, 因为只有到程序运行起来,你才能知道,会产生什么样的sql。
      但是保证安全有许多方法和方面,比如部署前的测试, 数据库的备份,对表的权限的设置。等。用sp来保证安全,只是多个选项中的一个。
      在startup型企业中,高级程序员往往起到主导作用, 所以他们会不犹豫的选择ORM。
      在传统企业中,如果DBA或者技术主管比较强势,往往会采用sp。

    综上所述:

      ORM SQL
    开发速度
    运行性能
    方便修改    
    可维护性

    ORM,最大的问题是复杂查询,可以考虑SQL和ORM两者同时使用,简单地方用ORM,复杂地方用SQL;利用Cache等技术可以很好地提高查询速度,在Phalcon中,就是采用两者合用的方式:

    1.Model中返回的是当前的Model集
    2.PHQL中返回的是查询集
    前者支持魔术方法get/count加关联Model名,用可选参数来进行二次筛选;后者采用类似SQL的方法来关联表,这样查询集
    里面就利用驼峰规则就可以访问所有的字段:
    $phql = "SELECT Cars.*, Brands.* FROM Cars, Brands WHERE Brands.id = Cars.brands_id"
    $rows = $manager->executeQuery($phql);
    foreach ($rows as $row) {
        echo "Car: ", $row->cars->name, " ";
        echo "Brand: ", $row->brands->name, " ";
    }
    还可以访问指定字段:
    $phql = "SELECT Cars.name AS car_name, Brands.name AS brand_name WHERE Brands.id = Cars.brands_id";
    $rows = $manager->executeQuery($phql);
    foreach ($rows as $row) {
        echo $row->car_name, " ";
        echo $row->brand_name, " ";
    }
    当然可以加别名访问:
    $phql = "SELECT c.*, b.* FROM Cars c, Brands b WHERE b.id = c.brands_id";
    $rows = $manager->executeQuery($phql);
    foreach ($rows as $row) {
        echo "Car: ", $row->c->name, " ";
        echo "Brand: ", $row->b->name, " ";
    }
  • 相关阅读:
    开源框架.netCore DncZeus学习(五)下拉树的实现
    开源框架.netCore DncZeus学习(四)项目升级
    github下载更新代码到本地
    AndroidStudio替换空行
    Ext.net获取选中行数据
    OZCode
    禁止密码显示框
    Android layout_weight理解
    微信页面关于点击按钮关注公众号放到链接里无关注按钮
    进入页面就触发了popstate事件。
  • 原文地址:https://www.cnblogs.com/fuland/p/4280733.html
Copyright © 2011-2022 走看看