【问题标题】:Using ORM with stored procedures, a contradiction?将ORM与存储过程一起使用,矛盾吗?
【发布时间】:2010-12-11 18:29:48
【问题描述】:

我继承了一个严格使用存储过程来完成其工作的 Web 应用程序。我喜欢让前端开发人员无法破坏数据库的方法,但我已经厌倦了用简单的 SQL 编写对 SP 的调用,并希望有一些更理智的东西。虽然我一直在寻找一个体面的 ORM(在这种情况下是针对 Perl,但这与问题无关)并支持存储过程,但我意识到 ORM 可能与 SP 直接矛盾。

我的想法是,正如名字已经告诉我们的那样,SP 是过程,即过程式 Pascal 风格编程的代表,事实上,一个 Web 应用程序看起来与 SQL-Server 端的 Pascal 完全一样——许多功能,没有真正的命名空间。与此相反,我们正在尝试进行大部分 OOP 风格的编程(或功能性,这是另一个主题),因此实际上过程 SP 并不适合干净的对象层次结构。同时,关系逻辑可以干净地转换为对象(通过 ORM),但不是过程,这可能是大多数 ORM 不能很好地支持 SP 的原因(但我不是该领域的专家)。从某种意义上说,SP ORM。

所以这两个问题是:

  1. 假设我们在运行 ORM 时最好使用普通表,我是否正确?
  2. 市场上是否有任何“面向对象的存储过程”,从关系模型构建?显然,有面向对象的数据库,但我对“服务器端的 ORM”感兴趣。

【问题讨论】:

    标签: sql oop stored-procedures orm


    【解决方案1】:

    “假设我们在运行 ORM 时使用普通表更好,我是对的吗?”

    是的。

    RDBMS 应该专注于持久存储,仅此而已。

    如果您这样做,您会发现您可以 - 轻松地 - 用您的 OO 语言构建访问层。所有的“前端”开发者都必须使用访问层,不能破坏数据库。

    “面向对象的存储过程?”

    Oracle 具有一些类似于 OO 的 PL/SQL 特性。

    不要在这上面浪费任何时间。关注持久性(在 RDBMS 中)和应用程序处理(不在 RDBMS 中)之间的清晰分离。

    很多很多人会向您发送讨厌的邮件,说“供应商将所有这些功能都放在那里,这意味着您应该使用它们”和“存储过程有什么问题?”以及“一个好的 DBA 胜过一屋子的前端开发人员”等等。

    我不知道为什么人们声称存储过程“更好”,但许多系统最终都遇到了存储过程和触发器变得如此繁重以至于不得不重写的问题。

    我从未见过有人抱怨他们在数据库之外拥有太多应用软件。

    在这里继续按照你的想法——使用 ORM——避免存储过程。

    【讨论】:

    • 同意。使用存储过程构建 ORM 是疯狂的。
    • 触发器是对的;这是一种使复杂性失控的简单方法。但是存储过程可以很好地作为一个层来保持数据库的一致性,并强制执行日志记录和安全性。
    • @Andomar:访问层将保持数据库的一致性,并强制执行日志记录和安全性。存储过程并不容易或特别擅长这些事情。它们对 DBA 来说似乎很方便。然而,从长远来看,它们很脆弱且难以维护。我已经向客户收取了很多钱,让他们在他们失败(反复)简单地找到关键存储过程的来源时闲逛。
    • 我认为重要的是要注意,当您拥有在多个 RDBMS 后端下发布的产品时,SP 和 ORM 可以很好地协同工作。语法可能会有所不同(尤其是在尝试提高性能时),并且这些特定实例的 SP 可以通过将代码留给服务器本身来保持代码的可维护性。在这种极端情况之外,我同意作者的观点。
    • -1 因为这绝不是一个封闭的问题,存在重大分歧和缺乏共识。双方各有利弊,因此最好尽可能多地阅读并形成自己的观点。
    【解决方案2】:

    这个问题没有一个黑白分明的答案。双方都有许多相互矛盾的论点,我,(恕我直言),还没有看到一个明确的共识出现。对于反对的观点,理性的论点赞成反对,请参阅 ORM - Vietnam of CS,或 another ORM link

    【讨论】:

      【解决方案3】:

      大多数 ORM 工具(我使用过。我在 .NET 世界中)提供了一种使用存储过程的机制。因为 ORM 工具(同样是我使用过的工具)喜欢默认选择 all 列,因此它们都加载到对象图中,因此您通常必须编写 SPROC 来选择所有列对象图的一部分。这是我在使用 ORM 包时遇到的唯一主要怪事。

      通常有一些方法可以优化 ORM 工具中的 SPROC 调用,因此它们不需要选择所有列,但这通常更高级。

      我会说这样做是安全的,但通常只有当您需要优化通过普通 ORM 方法会很慢的东西时,您才会想要/需要这样做。

      【讨论】:

        【解决方案4】:

        在 .NET 中,LINQ 数据类将为过程生成强类型类。您将过程称为:

        foreach (var customer in db.GetCustomers())
            Console.WriteLine(customer.firstName);
        

        GetCustomers() 是数据库中的存储过程。但是您不能更新返回的客户并将更改提交到数据库。 ORM 只能对普通表执行此操作。

        我的经验与 S.Lot 的相反,存储过程层使我的数据库保持一致、干净和快速。我想这取决于应用程序的大小和复杂性,以及您对 SQL 的了解程度。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-04-23
          • 1970-01-01
          相关资源
          最近更新 更多