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

时间:2012-07-09 18:57:04

标签: sql sql-server stored-procedures

  

可能重复:
  What are the pros and cons to keeping SQL in Stored Procs versus Code

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

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

3 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分:0)

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

我个人认为,一般来说,ORM会为您节省大量冗长编码的时间,因为它可以自动生成您在典型CRUD类型系统中使用的大部分SQL。要获得这一点,您可能会放弃一点性能和一些灵活性。如果您的系统是中低容量(每天数万个请求的数量),那么ORM对您来说就没问题了。如果你开始接受每天数以百万计的请求,那么你可能需要一些像直接SQL或存储过程那样的裸机。请注意,ORM不会阻止您更直接地访问数据库,这通常不是您要使用的。

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

请参阅:

答案 2 :(得分:0)

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

CRUD存储过程曾经是,有时仍然是SQL DBMS上数据持久性和检索的最佳实践。每个这样的DBMS都有存储过程,因此无论编码语言和DBMS如何,您几乎都能保证能够使用此解决方案,并且使用该解决方案的代码可以指向具有适当存储过程的任何DB及其& #39; ll使用最少的代码更改(在不同的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本身来阻止不必要的事情发生,那么你就无法在其上面的许多软件和固件层中这样做(甚至鼓励它发生)。