存储过程和ORM

Gui*_*Gui 23 stored-procedures

与使用ORM(nHibernate,EF等)处理某些CRUD操作相比,存储过程的目的是什么?要调用存储过程,我们只是传递一些参数,并使用ORM发送整个SQL查询,但这只是性能和安全性的问题还是有更多优势?

我问这个是因为我从未使用过存储过程(我只是用ORM编写所有SQL语句并执行它们),并且客户告诉我在下一个项目中我将不得不使用存储过程,我我试图找出何时使用它们.

Mar*_*ote 32

存储过程通常用SQL(SQL Server的T-SQL,PL-SQL Oracle等)的方言编写.那是因为他们为SQL添加了额外的功能,使其更强大.另一方面,你有一个ORM,比方说NH生成SQL.

ORM生成的SQL语句与编写T-SQL存储过程的速度或功能不同.这里是两难进入:我需要超高速应用绑定到SQL数据库供应商,难以维持或做我需要灵活,因为我需要针对多个数据库,我更喜欢写HQL查询比SQL缩短开发时间那些?

存储过程比SQL语句更快,因为它们是在数据库引擎中预编译的,并且执行计划已缓存.你不能在NH中这样做,但你有其他选择,比如使用Cache Level 1或2.

此外,尝试使用NH进行批量操作.存储过程在这些情况下非常有效.您需要考虑SP在更深层次上与数据库进行通信.

选择可能不那么明显,因为所有这些都取决于您正在处理的场景.

  • 在大多数情况下,由一个体面的ORM生成的SQL是完美的,只是当事情变得复杂时它们就会崩溃. (8认同)
  • ORM生成的SQL的速度和功能与直接T-SQL相同.(它们也得到预编译并在SQL Server中重用).写入也更容易,更快,风险更低,维护更方便. (2认同)
  • Paul和Ernst - 如果两者都以最好的方式编写,那么直接的SQL和存储过程有可能比ORM生成的SQL更快地获得大量订单.这是事实.当然,这是可维护性与性能之间的巨大折衷.但请永远不要声称速度/功率是相同的:) (2认同)

Chr*_*ier 13

您应该使用存储过程的主要(我想说“唯一”)原因是您是否确实需要性能。

在数据库中创建快速执行复杂操作的“函数”似乎很诱人。但它很快就会失控。

我所使用的应用程序在 SQL 中封装了如此多的业务逻辑,以至于几乎不可能重构任何内容。从字面上看,数百个存储过程对于使用 ORM 的开发人员来说是黑匣子。

此类应用程序变得脆弱、难以调试且难以理解。通过允许业务逻辑存在于存储过程中,您将允许 SQL 开发人员在比 ORM 更难使用、记录和调试的工具中做出他们不应该做出的设计选择。我见过处理付款处理的存储过程。真正的核心内容。那些对应用程序如此重要以至于没有人敢碰它的东西,都是因为一些具有良好 SQL 技能的人花了 5 年时间编写了一个脚本来快速修复某些问题,它从未迁移到 ORM,并最终成长为一个难以管理的怪物,充满了逻辑混乱无人能理解。开发人员最终不得不盲目地相信它所做的一切。更糟糕的是,它几乎总是在测试覆盖范围之外,因此部署时您可能会破坏所有内容,即使您的测试通过了模拟数据,但某些古老的存储过程突然开始出现问题。

滥用存储过程是您可能积累的最严重的技术债务形式之一。数据库是持久层,不应该用于业务逻辑。您应该尽可能严格地保持这种区别。

当然,在某些情况下,ORM 的性能会很糟糕,或者根本不支持您需要的 SQL 功能。如果使用原始 SQL 进行操作确实不可避免,那么只有这样您才应该考虑存储过程。

我见过存储过程地狱。你不想要这样。


And*_*rew 6

在某些情况下,存储过程具有显着的性能优势。通常由 Linq 和其他 ORM 生成的查询可能效率低下,但仍然足以满足您的目的。某些 RBDMS(例如 SQL Server)会缓存存储过程的执行计划,从而节省查询时间。对于您经常使用的更复杂的查询,这种性能节省可能至关重要。

但是,对于大多数普通的 CRUD,我发现如果 ORM 可用并且其操作满足您的需求,那么仅使用 ORM 通常会更好地维护可维护性。大多数情况下,实体框架在 .NET 世界中对我来说效果很好(与 Linq 结合使用),而且我非常喜欢 PHP 的 Propel。


小智 6

我偶然发现了这个相当古老的问题,但令我震惊的是,存储过程最重要的好处甚至没有被提及。

安全与资源保护

使用 SP,您可以将该 SP 的执行权授予用户。用户可以执行该SP并且只能执行该SP。您甚至不必授予用户对所使用的表的读或写访问权限。用户甚至不必知道所使用的表。

使用 ORM,您必须授予对所使用的表和用户的读或/和写访问权限。用户可以从您授予权限的所有表中读取所有数据,甚至可以将它们组合到查询中(无论您是否愿意),并且还可以运行在数据库服务器上产生沉重负载的查询。

当应用程序开发和数据库开发由不同的团队完成并且数据库由多个应用程序使用时,这一点尤其有用。