存储过程已经在一些组织中失宠了好几年了。现在这些企业访问其数据库的首选方法是使用对象关系映射(Object Relational Mapper,简称 ORM),例如 NHibernate 或 Entity Framework。在接下来的几篇文章中,我们将探讨他们这样做的原因,以及这种模式转变是否表示存储过程的最终会被淘汰。
存储过程基础
如了解关系数据库的存储过程和函数中所述:
存储过程(stored procedure,简称 proc)是一组带有指定名称的结构化查询语言(Structured Query Language,SQL)语句,作为一个组存储在关系数据库管理系统中,因此可以被多个程序重用和共享。存储过程可以访问或修改数据库中的数据,但它不依赖于特定的数据库或对象。这种不紧密耦合的情况是有利的,因为为不同但相似的目的重用过程是很容易。
到目前为止,听起来存储过程像是一个有用的工具,但是,正如我们将在下一节中看到的那样,并不是每个人都相信。
存储过程的缺点
尽管存储过程具有长期优势,但存储过程的反对者指出了其许多缺点,例如:
- 容易出现错误:由于存储过程封装了应用程序逻辑,因此应将其移至应用程序代码中,以便更好地对其进行管理和测试。由于测试存储过程本身就是个挑战,它们可能是导致一些非常严重错误的原因。
- 实现差异:存储过程实现因供应商而异。虽然许多数据库开发人员认为 Oracle 的存储过程质量最高,而其他产品的过程(例如 MySQL 的存储过程)不太完善。
- 不断变化的需求:存储过程的原本用途之一是减少网络流量。然而,在现今超快的网络速度下,这已不是问题了。 因此,将应用程序逻辑放入存储过程可能是过早优化。
- 难以维护:存储过程往往需要比应用程序代码更多的工作来开发和维护。对于初学者,你需要有不同的存储过程来为每个表执行创建、检索、更新和删除操作,还需要为你希望进行的每个不同查询创建一个单独的存储过程。然后,你需要在代码中实现类和/或方法来调用每个存储过程。 与之相比,O/R 映射只需要类定义、数据库表和映射文件。事实上,现代 ORM 使用基于约定的方法,无需单独的映射定义。
- 代码重复:存储过程要求你违反 DRY(Don't repeat yourself,不要重复你自己)原则,因为你必须引用数据库表列六次或以上。此外,将对象作为参数传递给大多数存储过程是不可能的,只有简单的类型,如字符串、整数、日期/时间等,几乎不可能避免长长的参数列表(十几个或以上是常见的!)。
即使是存储过程最坚定的反对者,在某些情况下仍然使用它们。例如,存储过程非常适合数据库内务管理或报告。否则,开发人员应该有充分的理由将它们集成到他们的应用程序中。
预告
听过一些避免存储过程而支持应用程序代码和对象关系映射(ORM)(例如 NHibernate 或 Entity Framework)的原因后,你可能会确信这是正确的。好吧,暂时不要做出决定。在下一部分中,我们将考虑更多放弃和保留存储过程的动机因素。然后,如果你仍然想改变,至少你将对所涉及的所有问题有更全面的了解。