Бизнес-логика:Уровень базы данных или приложения

StackOverflow https://stackoverflow.com/questions/119540

  •  02-07-2019
  •  | 
  •  

Вопрос

Вечный вопрос.Где следует разместить свою бизнес-логику: в базе данных в виде хранимых процедур (или пакетов) или в приложении/среднем уровне?И что еще более важно, почему?

Предположим, независимость базы данных не является целью.

Это было полезно?

Решение

Поместите в базу данных достаточное количество бизнес-логики, чтобы гарантировать согласованность и правильность данных.

Но не бойтесь дублировать часть этой логики на другом уровне, чтобы улучшить взаимодействие с пользователем.

Другие советы

Ремонтопригодность вашего кода всегда является серьезной проблемой при определении того, куда должна идти бизнес-логика.

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

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

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

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

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

Будет сложно заставить несколько приложений работать с одной и той же базой данных.Изменения в одном приложении приведут к поломке других.Это может быстро превратиться в кошмар при обслуживании.Так что это действительно не масштабируется.

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

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

Это действительно зависит от вас, пока вы последовательны.

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

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

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

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

Некоторые из систем, которые я поддерживаю, за последние 10–15 лет претерпели следующие изменения пользовательского интерфейса:Oracle Forms/Visual Basic/Perl CGI/ASP/Java-сервлет.Единственное, что не изменилось — реляционная база данных и хранимые процедуры.

Хотя единственного правильного ответа не существует — это зависит от рассматриваемого проекта, я бы рекомендовал подход, предложенный в «Дизайн, управляемый доменомn» Эрика Эванса.В этом подходе бизнес-логика изолирована на своем собственном уровне — уровне домена, который находится поверх уровня(ов) инфраструктуры, который может включать в себя код вашей базы данных, и ниже уровня приложения, который отправляет запросы на уровень домена. для выполнения и слушает подтверждение их завершения, эффективно управляя приложением.

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

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

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

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

Использовать или нет SP также сильно зависит от базы данных, которую вы собираетесь использовать.Если вы не примете во внимание независимость базы данных, у вас будет совсем другой опыт использования T-SQL и PL/SQL.

Если вы используете Oracle для разработки приложения, то PL/SQL — очевидный выбор в качестве языка.Он очень тесно связан с данными, постоянно совершенствуется в каждой версии, и любой достойный инструмент разработки будет интегрировать разработку PL/SQL с CVS, Subversion или чем-то подобным.

Веб-среда разработки Oracle Application Express полностью построена на PL/SQL.

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

Это не значит, что не стоит включать его в пользовательский интерфейс (зачем отправлять информацию, которую база данных не примет), но игнорировать эти вещи в базе данных — значит навлечь на себя катастрофу.

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

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

Конечно, существует большая разница между умением составить оператор SQL и наличием «сильных навыков работы с базами данных» — если ваша команда ближе к первому, чем ко второму, тогда поместите логику в приложение, используя один из Hibernates этого мира. (или смените команду!).

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

Надеюсь, это поможет.

В настоящее время можно отправить на Subversion ваш сохраненный код процедуры и отладить этот код с помощью хорошей инструментальной поддержки.

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

Как только мы начали работать на C#, мы приняли решение не использовать хранимые процедуры, но теперь мы перемещаем все больше и больше кода в хранимые процедуры.Особенно пакетная обработка.

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

Размещение кода на уровне приложения приведет к созданию независимого от БД приложения.

Иногда лучше использовать хранимые процедуры из соображений производительности.

Это (как обычно) зависит от требований приложения.

Единственное, что хранится в базе данных, — это данные.

Хранимые процедуры — это кошмар для обслуживания.Это не данные и им не место в базе данных.Бесконечная координация между разработчиками и администраторами баз данных — это не более чем организационные трения.

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

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

Однако кодом внутри базы данных управлять гораздо сложнее.Нет подходящей среды — нет «PATH», ссылок на каталоги или других переменных среды — чтобы обеспечить какой-либо полезный контроль над тем, какое программное обеспечение используется;у вас есть постоянный, глобально связанный набор прикладного программного обеспечения, закрепленный в базе данных и связанный с данными.

Триггеры еще хуже.Это кошмар одновременно и для обслуживания, и для отладки.Я не понимаю, какую проблему они решают;они кажутся способом обойти плохо спроектированные приложения, в которых кто-то не удосужился правильно использовать доступные классы (или библиотеки функций).

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

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

Бизнес-логику следует размещать на уровне приложений/среднего уровня в качестве первого варианта.Таким образом, его можно выразить в виде модели предметной области, поместить в систему контроля версий, разделить или объединить со связанным кодом (рефакторинг) и т. д.Это также дает вам некоторую независимость от поставщика базы данных.

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

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

По моему опыту, ответ лежит где-то в спектре ценностей, обычно определяемых навыками вашей организации.

СУБД — очень мощный зверь, а значит правильное или неправильное обращение принесет большую пользу или большую опасность.К сожалению, во многих организациях основное внимание уделяется программистскому персоналу;Навыки работы с базами данных, особенно навыки разработки запросов (в отличие от административных), игнорируются.Что усугубляется тем, что возможность оценить навыки работы с DBMS также, вероятно, отсутствует.

И лишь немногие программисты в достаточной степени понимают то, чего они не понимают в базах данных.

Отсюда и популярность неоптимальных концепций, таких как Active Records и LINQ (чтобы добавить некоторую очевидную предвзятость).Но они, вероятно, являются лучшим ответом для таких организаций.

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

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

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

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

«Уровни» бизнес-приложений:

1.Пользовательский интерфейс

Это реализует взгляд бизнес-пользователя на работу h(is/er).Он использует термины, с которыми пользователь знаком.

2.Обработка

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

3.База данных

Это должно быть:нормализованная последовательная база данных (стандартные СУБД на базе SQL);объектно-ориентированная база данных, хранящая объекты, обертывающие бизнес-данные;и т. д.

Что происходит Куда

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

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

ИМХО.При принятии решения о том, где находится бизнес-логика в приложении, управляемом реляционной базой данных, возникают две противоречивые проблемы:

  • ремонтопригодность
  • надежность

Ре.ремонтопригодность:Чтобы обеспечить эффективную будущую разработку, бизнес-логика должна быть частью вашего приложения, которую легче всего отлаживать и контролировать версии.

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

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

В нашем приложении большая часть бизнес-логики содержится на уровне модели приложения, например.счет-фактура знает, как инициализироваться из данного заказа на продажу.Когда несколько разных вещей изменяются последовательно для такого сложного набора изменений, как этот, мы объединяем их в транзакцию, чтобы обеспечить согласованность, вместо того, чтобы выбирать хранимую процедуру.Подсчет итогов и т.д.все выполняются с помощью методов на уровне модели.Но когда нам нужно что-то денормализовать для повышения производительности или вставить данные в таблицу «изменений», используемую всеми клиентами, чтобы выяснить, срок действия каких объектов им должен истечь в их кэше сеанса, мы используем триггеры/функции на уровне базы данных для вставки новой строки. и отправьте уведомление (Postgres прослушивает/уведомляет) из этого триггера.

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

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


Конечно, все меняется, когда вы выходите за пределы СУБД и переходите к системам хранения кортежей, таким как Amazon SimpleDB и Google BigTable.Но это другая история :)

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

И мы знаем, где оно находится, без необходимости искать среди гектаров решений и кодовой базы!

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

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

Я думаю, что приведенный пример был отображением счета-фактуры на экране.Решение пометить просрочку красным цветом – это деловое решение...

Это континуум.ИМХО, главный фактор - скорость.Как вы можете запустить эту присоску как можно быстрее, сохраняя при этом хорошие требования к программированию, такие как ремонтопригодность, производительность, масштабируемость, безопасность, надежность и т. д.Часто SQL является наиболее кратким способом выражения чего-либо, а также во многих случаях оказывается наиболее производительным, за исключением строковых операций и т. д., но именно здесь могут помочь ваши процедуры CLR.Я считаю, что нужно щедро использовать бизнес-логику там, где вы считаете, что это лучше всего подходит для текущего дела.Если у вас есть группа разработчиков приложений, которые обосрались, глядя на SQL, позвольте им использовать логику своего приложения.Если вы действительно хотите создать высокопроизводительное приложение с большими наборами данных, поместите в БД как можно больше логики.Увольте своих администраторов баз данных и дайте разработчикам полную свободу в работе с их базами данных разработчиков.Не существует единого ответа или лучшего инструмента для работы.У вас есть несколько инструментов, поэтому станьте экспертом на всех уровнях приложения, и вскоре вы обнаружите, что тратите гораздо больше времени на написание красивого, краткого и выразительного SQL, где это оправдано, и использование уровня приложения в других случаях.На мой взгляд, в конечном итоге сокращение количества строк кода приводит к простоте.Мы только что преобразовали приложение с поддержкой sql, состоящее всего из 2500 строк кода приложения и 1000 строк SQL, в модель предметной области, которая теперь имеет 15 500 строк кода приложения и 2500 строк SQL, чтобы добиться того, что делало предыдущее приложение с поддержкой sql.Если вы можете оправдать 6-кратное увеличение кода как «упрощенное», тогда продолжайте.

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

По сути, мне сказали, что если у вас есть миллионы строк данных в таблицах вашей базы данных, тогда подумайте о том, чтобы поместить бизнес-логику в хранимые процедуры и триггеры.Именно этим мы и занимаемся прямо сейчас: преобразуем Java-приложение в хранимые процедуры для удобства сопровождения, поскольку Java-код стал запутанным.

Я нашел эту статью: Войны бизнес-логики Автор также добавил миллион строк в аргумент таблицы, что мне показалось интересным.Он также добавил бизнес-логику в JavaScript, который находится на стороне клиента и находится за пределами уровня бизнес-логики.Я не думал об этом раньше, хотя уже много лет использую JavaScript для проверки, а также проверку на стороне сервера.

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

И последнее: есть еще одна группа, над которой я сейчас работаю, которая выполняет огромную работу с базами данных для исследований, и объем данных, с которыми они имеют дело, огромен.Тем не менее, для них они не имеют никакой бизнес-логики в самой базе данных, а хранят ее на уровне приложения/среднего уровня.Для их дизайна подходящим местом было приложение/средний уровень, поэтому я бы не стал использовать размер таблиц как единственное соображение при проектировании.

Бизнес-логика обычно воплощается в объектах и ​​различных языковых конструкциях инкапсуляции, наследования и полиморфизма.Например, если банковское приложение передает деньги, может существовать тип «Деньги», который определяет бизнес-элементы того, что такое «деньги».Это в отличие от использования примитивной десятичной дроби для обозначения денег.По этой причине хорошо спроектированное ООП — это место, где живет «бизнес-логика», а не строго на каком-либо уровне.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top