Положить ли бизнес-логику в хранимую процедуру или нет?


21

Всегда есть спор по теме - «Поместить ли бизнес-логику в хранимую процедуру или нет?». Если мы решим не использовать инструмент ORM и не помещать бизнес-логику в хранимую процедуру, тогда куда мы поместим бизнес-логику?

В моих предыдущих приложениях я всегда предпочитал помещать всю бизнес-логику только в хранимые процедуры. Затем из кода .NET я вызываю эти хранимые процедуры, используя блоки доступа к данным. SQLHelper и т. Д. Но это не может быть сценарий все время. Так что я немного погуглил, но в итоге растерялся .......

Любые предложения ...?


Я предвзятый -> Хранил Procs всегда. Но тогда я пристрастен. Забудьте о гибком программировании, печальная реальность заключается в том, что в деловом мире изменения происходят постоянно, и их нужно делать «немедленно». Хранимые процедуры позволяют это. Это спасатель. Попытка внести такие изменения с помощью кодовой базы была бы невозможна.
Темная ночь

4
@Darknight, сильно зависит от вашей платформы и архитектуры, чтобы сделать подобное заявление. Я не понимаю, почему развертывание хранимой процедуры в базе данных занимает гораздо меньше времени, чем, скажем, выполнение сценария сборки и развертывания для создания нового файла WAR, его развертывания и перезапуска сервера приложений.
maple_shaft

7
Хранимые процедуры - септик информатики.
Mongus Pong

1
Хранимые процедуры - просто еще один инструмент, как и любой другой.
Сам Йи

Ответы:


15

Я бы принял прагматический подход - исторически главное «преимущество» хранения бизнес-логики в хранимых процессах заключается в соображениях производительности (архитектура 2,5 уровня), в то время как разделение бизнес-логики на уровень BLL (уровень 3 / N) обычно чище от перспективы технического обслуживания, и легче тестировать (макет / заглушка доступа к данным).

Однако, учитывая, что .NET ORMS с поддержкой LINQ, такие как LINQ2SQL, EF и NHibernate, теперь создают параметризованные SQL-запросы, где планы запросов могут кэшироваться, экранироваться для SQL-инъекций и т. Д., Я думаю, что переход к 3 / N-уровневой архитектуре более привлекательным, чем когда-либо, и большинства SPROC (особенно ориентированных на запросы) можно вообще избежать. Шаблоны репозитория в .NET обычно предоставляют параметры дерева выражений IQueryable / accept, что обеспечивает безопасный тип, но в то же время гибкий доступ к вашим таблицам. (Лично в архитектурах типа SOA я бы не стал раскрывать IQueryable за пределами BLL, т. Е. Ваши уровни Service и Presentation должны работать с четко определенным набором методов. Причина в том, что в противном случае вы никогда не сможете полностью протестировать свою систему, и вы выиграли ».

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


1
+1 для облегчения написания модульных тестов на уровне приложений, однако рамки автоматизированного модульного тестирования БД прошли долгий путь.
maple_shaft

14

Будучи Java-разработчиком, я предпочел поместить бизнес-логику в BLL (удобный и простой источник контроля, знакомство и т. Д. И т. Д.).

Однако после работы на большом предприятии с множеством распределенных приложений, использующих различные технологии (C #, Java, Pick (не спрашивайте)), стало очевидным одно существенное преимущество использования хранимых процедур:

Хранимые процедуры могут быть общими для разных приложений .


Очень хороший момент
NoChance

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

2
Если вы разделите свое управление данными на библиотеки, эти библиотеки также могут быть теоретически разделены между различными приложениями ...
glenatron 10.10.11

2
Я согласен частично. Все эти технологии имеют прямой доступ к базе данных; таким образом, вы используете хранимые процедуры для совместного использования общего кода между ними. С тем же успехом можно решить ту же проблему, имея средний уровень и иметь гетерогенные решения, обращающиеся к вашему среднему уровню вместо вашей базы данных, и этот средний уровень совместно использует такой код.
Ekevoo

1
К вашему сведению, этот ответ - вздор, спустя 6 лет - в базу данных поступают только данные. Вы вводите логику, у вас много проблем в будущем. Просто создайте микросервис на выбранном вами языке, который обращается к БД.
НимЧимпский

6

У нашей команды есть мягкое правило. Иногда лучше решить бизнес-логику в T-SQL, иногда проще сделать это в c # (бизнес-уровень).

Таким образом, у нас есть прагматичное решение: поместите туда, где оно подходит лучше. Я знаю, что теория иногда очень строга к этому ... но это теория :-)


2
Конечно, это худшее решение из всех? Как ведущий разработчик узнает, где хранится логика? Я полагаю, что иногда он выползает на уровень приложений или, что еще хуже, в пользовательский интерфейс?
Пол Т Дэвис

2
Нет. Это всегда в бизнес-уровень или T-SQL. Выяснение, где хранится логика, является, вероятно, самой маленькой проблемой, когда дело доходит до обслуживания.
gsharp

Что происходит, когда кто-то присоединяется к команде, и вы говорите им это правило? Как они должны знать, где что-то "подходит лучше"? Это почти кажется мне не правилом. Очень субъективно на основе личности.
RationalGeek

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

4
Я действительно не вижу смысла неправильно использовать c # для вещей, которые SQLServer может сделать намного лучше, и наоборот.
gsharp

3

Есть преимущества и недостатки у обоих (на мой взгляд):

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

С другой стороны, хранимые процедуры позволяют быстрее исправлять ошибки в определенных ситуациях. Если в хранимой процедуре есть ошибка, вы просто исправляете ее, и все готово. Исправление ошибки в ORM требует перестройки. В зависимости от вашего процесса сборки это может быть длительным / раздражающим.


+1 за необходимость контроля исходного кода с сохраненными процессами, если вы собираетесь использовать их интенсивно. Многие администраторы баз данных, с которыми я работал, очень устойчивы к этой идее.
RationalGeek

2

Мы всегда размещаем нашу бизнес-логику на уровне бизнес-логики. Если вы поместите его в хранимую процедуру, он будет потерян, как только вы поменяете свою СУБД.


16
Последнее, что меняется, это СУБД ;-)
gsharp 10.10.11

Значит ли это, что вы ограничиваете хранимую процедуру извлечением, обновлением и вставкой данных ....?
Правин Патил

1
Каждая большая система, которую я видел, реальность такова, что база данных - это система. Языки программирования почти не имеют значения на данном этапе, так как это просто «передний конец» ..
Darknight

2
@gsharp, это не всегда так. Вы можете либо добавить другую СУБД, например Oracle, либо полностью заменить существующую. Или, в некоторых случаях, вы хотите заменить реальные данные фиктивными данными.
Шлякер

2
@ Шлякер, конечно, это не всегда так. Но более вероятно, что программа изменится (редизайн программного обеспечения, новые языки программирования и т. Д.), А не БД.
gsharp

2

«Бизнес-логика» - это немного туманный термин. Я имею в виду, что у него нет единого определения. Практическое правило заключается в том, чтобы свести к минимуму связь между уровнями, когда это возможно. Таким образом, вам не нужно отправлять пустое имя клиента на сервер, чтобы проверить его перед вставкой строки.

Бывают случаи, когда правило основано на чтении базы данных. Скажем, вы хотите перевести деньги со Счета 1 на Счёт 2. Вы должны прочитать оба аккаунта, убедиться, что они находятся в хорошем состоянии и что сумма на Счете 1 достаточна. В этом случае сервер является лучшим кандидатом для этого правила, потому что клиенту (который здесь является BL) не нужно выполнять 3 вызова уровня базы данных для этого процесса.

Конечно, если вам нужно, чтобы ваше решение было независимым от базы данных, создавайте хранимые процедуры только для CRUD (если они вообще используются).


1

Логика должна быть в BLL всегда, потому что:

  • Это можно проверить правильно
  • Когда SQL 20XX устарел и вам нужно перейти на последнюю версию, вам не нужно переписывать свой код.
  • Люди не склонны делать изменения на лету (что, кажется, выдвигается в качестве аргумента для SP)
  • По моему опыту, SP являются самой большой ошибкой разработчика, особенно после нескольких поколений обслуживания / изменений.

Я считаю, что должен быть закон, который гласит, что после того, как SP больше X строк, он не будет работать так, как задумано.


Что не так с изменениями на лету? Если в хранимой процедуре есть ошибка, которую легко исправить, исправьте ее. Это положительно, потому что это означает, что вам не нужно делать переиздание для чего-то тривиального. Пока люди не начинают маскировать ошибки в коде, изменяя хранимые процедуры, я не вижу проблем.
AndrewC

Под изменениями на лету я подразумеваю вещи, которые не тестировались и не следуют формальной процедуре выпуска. И да, sp изменения для маскировки ошибок кода - это то, что я видел довольно много.
Пол Т Дэвис

0

Мы создаем сервисный слой, который содержит всю нашу бизнес-логику, реализованную на выбранном языке, и используем базу данных только для запросов. Этот подход является своего рода обязательным для нас, потому что наша цель заключается в создании COTS-решений для доставки приложений с различными реализациями баз данных. Hibernate оказался спасателем для нас в этих обстоятельствах.

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

Кроме того, несмотря на некоторые ответы на форуме, у меня есть друг, работающий в страховой компании «Фортуна 100», который сделал 2 преобразования базы данных за три года, потому что база данных, выбранная для компании, изменилась.


0

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.