首页 文章

存储过程与从数据库中获取数据的其他形式相比的好处[重复]

提问于
浏览
-5

可能重复:将SQL保存在存储过程与代码中的优缺点是什么

只是好奇使用存储过程与从数据库中获取数据的其他形式的优缺点 . 确保速度,准确性和安全性的首选方法是什么(我们不希望sql注入!) .

(我应该将此问题发布到另一个堆栈交换站点吗?)

3 回答

  • 0

    根据所有数据库问题的答案'它取决于' . 但是,由于计划缓存,存储过程在速度方面肯定有帮助(尽管正确参数化的SQL也将从中受益) . 准确性没有区别 - 不正确的查询是否不正确,无论它是否在存储过程中 . 在安全性方面,它们可以提供限制用户访问的有用方法 - 因为您不需要让他们直接访问基础表 - 您可以只允许他们执行您想要的存储过程 . 但是,关于这个主题有很多问题,我建议你稍微搜索一下,然后再找一些 .

  • 0

    这在程序员SE上可能会更好,但我会在这里回答 .

    CRUD存储过程曾经是,有时仍然是SQL DBMS上数据持久性和检索的最佳实践 . 每个这样的DBMS都有存储过程,因此无论编码语言和DBMS如何,您几乎都可以保证能够使用此解决方案,并且使用该解决方案的代码可以指向具有适当存储过程的任何DB,并且它将会使用最少的代码更改(在不同的DBMS中调用SP时需要进行一些语法更改;通常将这些更改集成到语言的库支持中以访问特定DBMS上的SP) . 也许最大的优点是集中访问表数据;您可以像Fort Knox一样锁定表格,并根据需要为更多有限的用户帐户分配SP的访问权限 .

    但是,它们有一些缺点 . 首先,SP难以进行TDD,因为这些工具并不存在于数据库IDE中;您必须在运行SP的其他代码中创建测试(因此测试必须使用预期的测试数据设置DB) . 从技术角度来看,这样的测试不是也不可能是一个小的,狭窄的功能区域的狭窄测试,它没有副作用(例如读/写文件系统) . 此外,SP是在进行必要的功能更改时必须更改的一个层 . 向查询结果添加新字段需要更改表,检索源代码和SP . 添加新方法来搜索特定类型的记录需要创建和测试语句,然后将其封装在SP中,并在DAO上创建相应的方法 .

    可用的新最佳实践IMO是一个称为对象关系映射器或ORM的库 . ORM抽象实际数据层,因此您要求的内容将成为代码对象本身,并根据这些对象的属性查询它们,而不是基于表数据 . 这些查询几乎总是代码可配置的,并且基于您在对象模型和数据模型之间定义的一个或多个“映射”被转换为DBMS的SQL风格(类型A的对象被保存为表B中的记录,将此属性C写入字段D) .

    优点是代码中的更多灵活性实际上以这些代码对象的形式查找数据 . 查询的标准通常可以在代码中自定义;如果需要具有不同WHERE子句的新查询,则只需编写查询,然后ORM将其转换为新的SQL语句 . 因为ORM是唯一实际使用SQL的地方(并且大多数ORM使用系统存储的proc来执行可用的参数化查询字符串)注入攻击几乎是不可能的 . 最后,根据语言和ORM,可以对查询进行编译器检查;在.NET中,一个名为Linq的库可用于提供SQL-ish关键字语法,然后将其转换为方法调用,这些方法调用将提供给“查询提供程序”,后者可以将这些方法调用转换为数据存储的本机查询语言 . 这也允许在代码中测试查询;您可以验证所使用的查询是否会产生所需的结果给定内存中的实际DBMS对象集合 .

    ORM的缺点是ORM库通常是特定于语言的; Hibernate在Java中可用,NHibernate(和L2E和L2SQL)在.NET中,以及一些类似的库,如PHP中的Pork,但如果您使用较旧或更深奥的语言进行编码,那么就没有任何可用的类型 . 另一个是安全性变得有点棘手;大多数ORM需要直接访问表以便查询和更新它们 . 一些人会容忍被指向用于检索的视图和用于更新的SP(允许视图/ SP和表安全性的隔离以及限制可检索字段的能力),但是现在你正在混合两个世界中最糟糕的;您仍然需要定义映射,但现在您还在数据层中有代码 . 克服这个问题的最简单方法是在其他地方实施您的安全性;强制应用程序使用Web服务获取数据,该服务使用ORM提供数据并具有特定的,有限的“前门” . 此外,许多ORM在某些方面使用时会出现一些性能问题;大多数数据都是针对“延迟加载”数据而设计的,数据是在实际需要时而不是之前检索的,这样可以在您不需要所需的每条记录时提高前期性能 . 但是,当您需要所需的每条记录时,这会产生额外的往返行程 . 您必须以特定方式构造查询以绕过此预期的用例行为 .

    哪个更好?你必须决定 . 我现在可以告诉你,使用ORM比SP更容易设置和正常工作,而且它是一个巨大的优点 . 在大多数情况下,您认为安全性是一个问题,实际上并非如此,当安全性确实存在问题时,将解决方案放在数据库层通常是错误的地方,因为DBMS是防止入侵的最后一道防线;如果必须依靠DBMS来阻止不必要的事情发生,那么你就无法在其上面的许多软件和固件层中这样做(甚至鼓励它发生) .

  • 0

    关于此问题,Stackoverflow上有几个问题 . 我真的不认为你会在这里得到一个“正确”的答案,两者都能很好地解决,而且两者都可以工作得非常糟糕 . 我想如果你使用的是Java,那么一般模式是使用像Hibernate / JPA这样的ORM框架 . 只要您正确使用框架,这可以完全免受SQL注入攻击 . 我对.Net开发人员的经验是,他们更有可能使用存储过程支持的持久性,但这似乎比以前更开放 . NHibernate和其他MS技术似乎都越来越受欢迎 .

    我个人认为,一般来说,ORM会为您节省大量冗长编码的时间,因为它可以自动生成您在典型CRUD类型系统中使用的大部分SQL . 要获得这一点,您可能会放弃一点性能和一些灵活性 . 如果你的系统是低到中等音量(10 's of thousands of requests per day) then an ORM will be just fine for you. If you start getting in to the millions of requests per day then you may need something a little more bare metal like straight SQL or stored procedures. Note than an ORM doesn' t阻止你更直接地到数据库,它通常不是你会使用的 .

    最后需要注意的是,我认为ORM持久性使应用程序更易于测试 . 如果你在大部分持久性中使用存储过程,那么你几乎必然会开始在这些中获得一堆业务逻辑 . 要测试它们,您必须实际持久保存数据并与数据库交互,这使得测试变得缓慢而脆弱 . 使用ORM框架,您可以避免大多数此类测试,或者在您真正想要测试持久性时使用内存数据库 .

    看到:

相关问题