Что лучше, фильтрация результатов в БД или в приложении?

Простой вопрос. Бывают случаи, когда я извлекаю данные, а затем обрабатываю их в своем BLL. Но я понял, что такая же обработка/фильтрация может быть выполнена в моей хранимой процедуре, и отфильтрованные результаты возвращаются в BLL.

Что лучше, обработка в БД или обработка в BLL? И почему?

рассмотрите сценарий, я хочу проверить, существует ли продукт в моей базе данных, и если он существует, добавьте его в заказ (пример взят из ответа Нура Сабони ниже) теперь я могу сделать эту проверку в своем BLL или я делаю это в также хранимая процедура. Если я объединяю вещи в одну процедуру, я сокращаю всю операцию до одного вызова БД. Это лучше?


person shashi    schedule 20.09.2010    source источник
comment
Это достаточно субъективный вопрос. Ответ во многом зависит от ваших потребностей.   -  person Matt Ball    schedule 20.09.2010


Ответы (9)


ну, самый точный ответ - в базе данных, но вы можете рассмотреть что-то вроде Linq2Sql, я имею в виду написать выражение на уровне представления, и оно будет проанализировано как оператор Sql на уровне доступа к данным.

конечно, есть некоторые ситуации, когда 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.
}
person Nour    schedule 20.09.2010
comment
взяв пример, который вы упомянули, я могу проверить, доступен ли продукт в той же хранимой процедуре, что и заказ на размещение. Здесь вы выполняете два вызова базы данных, но если я объединим эту бизнес-логику в своей хранимой процедуре, я смогу добиться функциональности с помощью одного вызова базы данных. Так какой подход лучше в этом случае? Я думаю, что мои сомнения теперь немного яснее! - person shashi; 22.09.2010
comment
я знаю, что можно переместить логику в базу данных, но с точки зрения архитектуры приложения вы ничего не должны знать о базе данных или (службе сохранения), что, если вы захотите изменить поставщика базы данных? - person Nour; 22.09.2010
comment
принцип многоуровневости подразумевает, что вы ничего не должны знать о поставщике хранилища, кроме процедур запроса и хранения. (извините за мой слабый язык) вы можете подумать, что это делает накладные расходы на производительность, я согласен с вами в этом. - person Nour; 22.09.2010
comment
хорошо.. так что я не прошу ничего знать о провайдере.. я..? Скажем, я проверяю это конкретное условие в процедуре p_chk на сервере Sql. В настоящее время это вызывается из DAL. Теперь я переключаюсь на MySQl. Поскольку я использую шаблон репозитория, такой как реализация, мне абсолютно не нужно менять свою реализацию BLL. Есть очень незначительное изменение, которое я делаю в своем DAL, чтобы также включить поставщика MySql. Но метод DAL, вызывающий эту хранимую процедуру, не меняется. Итак, теперь реальная проблема заключается в том, можно ли реализовать sproc для получения идентичных результатов в MySQL. - person shashi; 22.09.2010
comment
И если я могу реализовать процедуру для получения идентичных результатов, то изменение постоянства больше не остается проблемой, не так ли? В любом случае, если я решу изменить постоянство, скажем, с MySql на SqlServer, все таблицы, sprocs и т. д. должны быть перенесены в новую базу данных. Итак, если производительность моего приложения улучшается за счет переноса обработки определенной логики в базу данных, не следует ли мне следовать этому? Наверное, глупый вопрос, который я задаю, но, как кто-то однажды сказал, самые глупые вопросы — это те, которые никогда не задают. - person shashi; 22.09.2010
comment
ну, во-первых, это вовсе не глупый вопрос (я думаю, что глупый означает глупый, не так ли?). теперь вся идея заключается в том, что BLL — это уровень бизнес-логики, и он должен заботиться о любой логике, необходимой для обработки данных, и я думаю, что решение о том, сколько продуктов должно быть доступно для продолжения процесса продажи, связано в BLL, а не в процедуры DAL, не так ли? И что я имею в виду под сменой провайдера, так это то, что когда вы разрешаете кому-то создавать базу данных, он не должен знать о логике, необходимой для обработки данных, и все о чем ему нужно заботиться, так это о том, как сохранить данные. - person Nour; 22.09.2010

На уровне базы данных.

Базы данных должны быть оптимизированы для запросов, так зачем прикладывать все усилия, чтобы вернуть большой набор данных, а затем выполнять фильтрацию в своем приложении?

person LittleBobbyTables - Au Revoir    schedule 20.09.2010
comment
Сложность будет уважительной причиной. Различные типы фильтров с несколькими критериями всегда проще реализовать на уровне приложения, чем в БД. - person Jahir; 30.04.2021

Общее правило: все, что разумно относится к обязанностям базы данных и может выполняться в вашей базе данных, делайте это в своей базе данных.

person Dennis Haarbrink    schedule 20.09.2010
comment
-1 это плохой совет, потому что в БД можно сделать все что угодно. И еще, в БД все нормально делается? - person Kugel; 20.09.2010
comment
Возможно неудачный выбор слов. Отредактировано сейчас. Я думал, что все мы разумные люди, у которых есть хотя бы какой-то здравый смысл :) - person Dennis Haarbrink; 20.09.2010
comment
Изменено на +1 после редактирования. Я думаю, что слишком многие из нас видели хранимые процедуры PL-SQL длиной 2000 строк, чтобы не видеть этого, когда кто-то говорит делать все в БД. - person Chris Marisic; 20.09.2010
comment
@Chris Marisic: Спасибо. Думаю, это связано с перспективой. Я слишком часто вижу скрипты некомпетентных разработчиков, выгружающих все на php, хотя было бы на 100% эффективнее, если бы это было сделано на уровне db. - person Dennis Haarbrink; 21.09.2010
comment
хорошо .. рассмотрим сценарий, я хочу проверить, существует ли продукт в моей базе данных, и если он существует, добавьте его в заказ (пример взят из ответа Нура Сабони ниже) теперь я могу сделать эту проверку в моем BLL или я делаю это и в хранимой процедуре. Если я объединяю вещи в одну процедуру, я сокращаю всю операцию до одного вызова БД. Это лучше? - person shashi; 22.09.2010
comment
@sassyboy: Разве это не должно быть обеспечено ограничением внешнего ключа? - person Dennis Haarbrink; 26.09.2010

в базе данных.

person Arthur Rizzo    schedule 20.09.2010

Чтобы выделить другую точку зрения, это также действительно зависит от вашей модели абстракции данных, если у вас есть большой кеш 2-го уровня, который находится поверх вашей базы данных, и большая часть (или все) ваши данные, которые вы будете фильтровать, находятся в cache тогда да, оставайтесь внутри приложения и используйте кешированные данные.

person Chris Marisic    schedule 20.09.2010

Разница не очень важна, если рассматривать таблицы, которые никогда не будут содержать более нескольких десятков строк.

Фильтрация в БД становится очевидным выбором, когда вы рассматриваете таблицы, которые вырастут до тысяч, сотен тысяч или миллионов строк. Нет никакого смысла передавать такой объем данных для фильтрации подмножества записей.

person Paul Sasik    schedule 20.09.2010

Меня постоянно учили, что данные должны обрабатываться на уровне данных, когда это возможно. Фильтрация данных — это то, для чего специально предназначена БД и для чего она оптимизирована. Поэтому именно там это должно произойти.

Это также предотвращает дублирование усилий. Если фильтрация данных происходит на уровне данных, то другой код/системы могут извлечь выгоду из одной и той же хранимой процедуры вместо дублирования работы в вашем BLL.

Я обнаружил, что людям нравится помещать основную логику в раздел, в котором им наиболее удобно работать. Независимо от сильных сторон разработчика обработка данных должна по возможности выполняться на уровне данных.

person dredful    schedule 20.09.2010

Я задал аналогичный вопрос в классе SSRS ранее в этом году, когда хотел узнать «лучшую практику» для того, чтобы хранимая процедура извлекала запрошенные данные вместо выполнения TSQL в наборе данных отчета. Ответ, который я получил, был следующим: «Позвольте ядру базы данных делать «тяжелую работу». То есть выполнять весь выбор, группировку и сортировку в хранимой процедуре и позволить SSRS сконцентрироваться на доставке результатов.

То же самое относится и к вашему сценарию. Во что бы то ни стало, я бы проголосовал за всю фильтрацию в вашей хранимой процедуре. Вызовите sproc из своего приложения и позвольте базе данных сделать всю работу.

person SidC    schedule 20.09.2010

Если вы фильтруете в базе данных, то только те данные, которые требуются приложению, фактически отправляются по проводу между базой данных и сервером приложений. По этой причине я предлагаю фильтровать по базе данных.

person DwB    schedule 20.09.2010