【问题标题】:Which is better, filtering results at db or application?哪个更好,在数据库或应用程序中过滤结果?
【发布时间】:2011-04-14 19:31:27
【问题描述】:

一个简单的问题。在某些情况下,我获取数据然后在我的 BLL 中处理它。但我意识到可以在我的存储过程中进行相同的处理/过滤,并将过滤后的结果返回给 BLL。

哪个更好,在 DB 中处理还是在 BLL 中处理?为什么?

考虑这种情况,我想检查我的数据库中是否存在产品,如果存在,将其添加到订单中(示例取自下面 Nour Sabony 的回答)现在我可以在我的 BLL 或我做这个检查这在存储过程中也是如此。如果我将事情组合到一个过程中,我会将整个操作减少到一个数据库调用。这样更好吗?

【问题讨论】:

  • 这是一个相当主观的问题。很多答案取决于您的需求。

标签: data-access-layer


【解决方案1】:

在数据库级别。

数据库应该针对查询进行优化,那么为什么要努力返回一个大型数据集,然后在您的应用程序中进行过滤呢?

【讨论】:

  • 复杂性是一个正当的理由。具有多个条件的不同类型的过滤器在应用层而不是在数据库中实现总是“更容易”。
【解决方案2】:

作为一般规则:任何合理地属于数据库职责并且可以在您的数据库中完成的事情,在您的数据库中完成

【讨论】:

  • -1 这是一个糟糕的建议,因为任何事情都可以在 DB 中完成。然而,数据库中的一切正常吗?
  • 可能选词不当。现已编辑。我以为我们都是懂事的人,至少有一些常识:)
  • 修改后改为+1。我认为我们中的太多人已经看到了 2000 行长的 PL-SQL 存储过程,以至于当有人说在数据库中做所有事情时看不到这一点。
  • @Chris Marisic:谢谢。我认为这与透视有关。我经常看到不称职的开发人员的脚本将所有内容卸载到 php,而如果在 db 级别完成,效率会提高 100%。
  • ok.. 考虑这种情况,我想检查我的数据库中是否存在产品,如果存在,请将其添加到订单中(示例取自下面 Nour Sabony 的回答)现在我可以做到这一点检查我的 BLL 或我也在存储过程中执行此操作。如果我将事情合并到一个过程中,我会将整个操作减少到一个数据库调用。这样更好吗?
【解决方案3】:

好吧,最好的答案是在数据库中, 但你可以考虑像 Linq2Sql 这样的东西, 我的意思是在表现层写一个表达式,在数据访问层会被解析为Sql Statement。

当然有一些情况BLL应该从DAL获取一些数据,处理它,然后返回给DAL。 举个例子: PutOrder(Order value) 过程,它应该检查所订购产品的可用性。

public void PutOrder(Order _order)
{
foreach (OrderDetail _orderDetail in _order.Details)
   {
    int count = dalOrder.GetProductCount(_orderDetail.Product.ProductID);
    if (count == 0)
    throw new Exception (string.Format("Product {0} is not available",_orderDetail.Product.Name));
    }
    dalOrder.PutOrder(_order);
}

但如果您正在制作浏览视图,则从 Dal 中获取所有数据然后选择要在浏览视图中显示的内容不是一个好主意(从性能角度来看)。

以下可能会有所帮助:

public List<Product> SearchProduts(Criteria _criteria)
{
string sql = Parser.Parse(_criteria);
///code to pass the sql statement to Database procedure and get the corresponding data.
}

【讨论】:

  • 以您提到的示例为例,我可以检查产品是否在与放置订单相同的存储过程中可用。在这里,您对 db 进行了两次调用,但是如果我在存储过程中结合该业务逻辑,我可以通过单个 db 调用来实现该功能。那么在这种情况下哪种方法更好呢?我想我的疑问现在更清楚了!
  • 我知道将逻辑移动到数据库是可能的,但是从应用程序架构的角度来看,您不应该对数据库或(持久性服务)有任何了解,如果您想更改数据库怎么办提供者?
  • n 层原则意味着您不应该知道存储提供者的任何事情,除了查询和存储过程。 (请原谅我的语言不好)你可能认为这会影响性能,我同意你的看法。
  • 好的..所以我不想知道有关提供者的任何信息..我是..吗?假设我在 Sql server 的过程 p_chk 中检查该特定条件。这当前是从 DAL 调用的。现在我切换到 MySQl。由于我使用的是类似实现的存储库模式,因此我绝对没有办法更改我的 BLL 实现。我在 DAL 中进行了一个非常小的更改,以合并 MySql 提供程序。但是调用这个存储过程的 DAL 方法并没有改变。所以现在真正的问题是是否可以实现存储过程以在 MySQL 上产生相同的结果。
  • 如果我可以实施该过程以产生相同的结果,那么持久性的改变不再是一个问题,不是吗?无论如何,如果我决定改变持久性,比如从 MySql 到 SqlServer,所有的表、sprocs 等都必须移植到新的数据库中。因此,如果通过将某些逻辑的处理移至数据库,我的应用程序的性能会更好,我不应该这样做吗?我在问什么可能是一个愚蠢的问题,但正如有人曾经说过“最愚蠢的问题是那些从未被问过的问题”..
【解决方案4】:

在数据库中。

【讨论】:

    【解决方案5】:

    要提出不同的观点,它还取决于您的数据抽象模型,如果您有一个位于数据库顶部的大型二级缓存并且您将过滤的大部分(或全部)数据是在缓存中,然后是留在应用程序中并使用缓存的数据。

    【讨论】:

      【解决方案6】:

      当您考虑包含永远不会超过几十行的表时,差异并不是很重要。

      当您考虑将增长到数千、数十万或数百万行的表时,在数据库中进行过滤成为显而易见的选择。传输这么多数据以过滤记录子集是零意义的。

      【讨论】:

        【解决方案7】:

        我一直被教导应该尽可能在数据层中处理数据。过滤数据是数据库专门要做的事情,并且经过优化。因此,这就是它应该发生的地方。

        这也可以防止重复工作。如果数据过滤发生在数据层中,那么其他代码/系统可以从相同的存储过程中受益,而不是重复 BLL 中的工作。

        我发现人们喜欢将主要逻辑放在他们最擅长工作的部分。无论开发人员的优势如何,数据处理都应该尽可能放在数据层中。

        【讨论】:

          【解决方案8】:

          我在今年早些时候的 SSRS 课程中问了一个类似的问题,当时我想了解让存储过程检索查询数据而不是在报表数据集中执行 TSQL 的“最佳实践”。我收到的回应是:让数据库引擎做“繁重的工作”。即在存储过程中做所有的选择、分组、排序,让SSRS专注于交付结果。

          您的场景也是如此。无论如何,我的投票是在您的存储过程中进行所有过滤。从您的应用程序中调用存储过程并让数据库完成工作。

          【讨论】:

            【解决方案9】:

            如果您在数据库中进行过滤,那么只有应用程序需要的数据实际上是在数据库和应用程序服务器之间的线路上发送的。为此,我建议最好在数据库中进行过滤。

            【讨论】:

              猜你喜欢
              • 2011-03-20
              • 2019-03-11
              • 2011-05-04
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2010-12-10
              • 1970-01-01
              相关资源
              最近更新 更多