Бизнес-логика: база данных или прикладной уровень
Вековой вопрос. Где вы должны разместить свою бизнес-логику, в базе данных в виде хранимых процедур (или пакетов) или на уровне приложений / промежуточного уровня? И что более важно, почему?
Предположим, независимость от базы данных не является целью.
24 ответа
Поместите достаточное количество бизнес-логики в базу данных, чтобы обеспечить согласованность и правильность данных.
Но не бойтесь дублировать эту логику на другом уровне, чтобы улучшить взаимодействие с пользователем.
Поддержание вашего кода всегда является большой проблемой при определении того, куда должна идти бизнес-логика.
Интегрированные средства отладки и более мощные интегрированные среды разработки обычно упрощают поддержку кода среднего уровня, чем тот же код в хранимой процедуре. Если нет реальной причины иначе, вы должны начать с бизнес-логики в вашем среднем уровне / приложении, а не в хранимых процедурах.
Однако, когда вы приходите к отчетам и интеллектуальному анализу / поиску данных, хранимые процедуры часто могут быть лучшим выбором. Это благодаря мощным возможностям агрегации / фильтрации баз данных и тому факту, что вы продолжаете обрабатывать очень близко к источнику данных. Но в любом случае это не то, что большинство считает классической бизнес-логикой.
Для очень простых случаев вы можете поместить свою бизнес-логику в хранимые процедуры. Обычно даже простые случаи имеют тенденцию усложняться со временем. Вот причины, по которым я не помещаю бизнес-логику в базу данных:
Размещение бизнес-логики в базе данных тесно связано с технической реализацией базы данных. Изменение таблицы приведет к повторному изменению большого количества хранимых процедур, что вызовет множество дополнительных ошибок и дополнительного тестирования.
Обычно пользовательский интерфейс зависит от бизнес-логики для таких вещей, как проверка. Помещение этих вещей в базу данных вызовет тесную связь между базой данных и пользовательским интерфейсом или в разных случаях дублирует логику проверки между этими двумя.
Будет сложно работать с несколькими приложениями в одной базе данных. Изменения для одного приложения приведут к поломке других. Это может быстро превратиться в кошмар обслуживания. Так что это на самом деле не масштабируется.
Практически SQL не является хорошим языком для реализации бизнес-логики понятным способом. SQL отлично подходит для операций на основе множеств, но в нем отсутствуют конструкции для "программирования в целом", трудно поддерживать большое количество хранимых процедур. Современные ОО языки лучше подходят и более гибки для этого.
Это не значит, что вы не можете использовать сохраненные процедуры и представления. Я думаю, что иногда хорошей идеей является размещение дополнительного уровня хранимых процедур и представлений между таблицами и приложениями для их разделения. Таким образом, вы можете изменить структуру базы данных без изменения внешнего интерфейса, что позволит вам выполнить рефакторинг базы данных независимо.
Это действительно зависит от вас, если вы последовательны.
Одна веская причина поместить его на уровень базы данных: если вы уверены, что ваши клиенты никогда не изменят свою базу данных.
Одна веская причина поместить его на уровень приложения: если вы нацеливаетесь на несколько технологий персистентности для своего приложения.
Вы также должны принять во внимание основные компетенции. Ваши разработчики в основном разработчики прикладного уровня или они в основном DBA-типы?
Хотя наличие бизнес-логики на прикладном уровне, безусловно, имеет свои преимущества, я хотел бы отметить, что языки / платформы меняются чаще, чем базы данных.
За последние 10-15 лет некоторые системы, которые я поддерживаю, прошли через следующие пользовательские интерфейсы: Oracle Forms/Visual Basic/Perl CGI/ ASP/Java Servlet. Единственное, что не изменилось - реляционная база данных и хранимые процедуры.
Хотя единого правильного ответа нет - это зависит от рассматриваемого проекта, но я бы порекомендовал подход, предложенный Эриком Эвансом в " Области, управляемой доменом" Эрика Эванса. При таком подходе бизнес-логика изолируется на своем собственном уровне - уровне домена - который расположен поверх уровня (ов) инфраструктуры - который может включать код вашей базы данных, и ниже уровня приложения, который отправляет запросы на уровень домена для выполнения и слушает подтверждение их завершения, эффективно управляя заявкой.
Таким образом, бизнес-логика фиксируется в модели, которую можно обсуждать с теми, кто понимает бизнес, помимо технических проблем, и это должно упростить изоляцию изменений в самих бизнес-правилах, проблем технической реализации и потока приложение, которое взаимодействует с бизнес-моделью (доменом).
Я рекомендую прочитать вышеприведенную книгу, если вы получите шанс, поскольку он довольно хорошо объясняет, как этот чистый идеал может быть приближен к реальному миру реального кода и проектов.
Все, что влияет на целостность данных, должно быть размещено на уровне базы данных. Помимо пользовательского интерфейса, другие вещи часто помещают данные, обновляют или удаляют данные из базы данных, включая импорт, массовые обновления для изменения схемы ценообразования, оперативные исправления и т. Д. Если необходимо обеспечить постоянное соблюдение правил, установите логику по умолчанию и триггеры.
Это не означает, что не стоит также иметь его в пользовательском интерфейсе (зачем отправлять информацию, которую база данных не примет), но игнорировать эти вещи в базе данных - значит спровоцировать катастрофу.
Единственное, что входит в базу данных - это данные.
Хранимые процедуры - это кошмар обслуживания. Они не являются данными и не принадлежат базе данных. Бесконечная координация между разработчиками и администраторами баз данных - это нечто большее, чем организационные трения.
Трудно поддерживать хороший контроль версий хранимых процедур. Код вне базы данных действительно прост в установке - когда вы думаете, что у вас неправильная версия, вы просто делаете SVN UP (возможно, установку) и ваше приложение возвращается в известное состояние. У вас есть переменные окружения, ссылки на каталоги и большой контроль среды над приложением.
Вы можете, с простым PATH
манипуляции, иметь вариант программного обеспечения, доступного для различных ситуаций (обучение, тестирование, контроль качества, производство, специфичные для клиента усовершенствования и т. д. и т. д.)
Код внутри базы данных, однако, гораздо сложнее в управлении. Нет подходящей среды - нет "PATH", ссылок на каталоги или других переменных среды - чтобы обеспечить какой-либо полезный контроль над тем, какое программное обеспечение используется; у вас есть постоянный глобальный набор прикладного программного обеспечения, прикрепленный к базе данных и связанный с данными.
Триггеры еще хуже. Они оба - обслуживание и кошмар отладки. Я не вижу, какую проблему они решают; Похоже, они являются способом работы с плохо спроектированными приложениями, в которых кто-то не может правильно использовать доступные классы (или библиотеки функций).
В то время как некоторые люди находят аргумент производительности убедительным, я все еще не видел достаточного количества эталонных данных, чтобы убедить меня в том, что хранимые процедуры настолько быстры. У каждого есть анекдот, но ни у кого нет параллельного кода, где алгоритмы более или менее одинаковы.
[В примерах, которые я видел, старое приложение было плохо спроектировано; когда хранимые процедуры были написаны, приложение было перепроектировано. Я думаю, что изменение дизайна оказало большее влияние, чем изменение платформы.]
Независимость от базы данных, которая в данном случае исключает спрашивающего, является самым сильным аргументом для удаления логики из базы данных. Самый сильный аргумент в пользу независимости базы данных - это возможность продавать программное обеспечение компаниям, которые предпочитают серверную часть базы данных.
Поэтому я бы посчитал, что основной аргумент для удаления хранимых процедур из базы данных - только коммерческий, а не технический. Там могут быть технические причины, но есть и технические причины для его сохранения - производительность, целостность и возможность, например, позволить нескольким приложениям использовать один и тот же API.
На то, использовать ли SP или нет, также сильно влияет база данных, которую вы собираетесь использовать. Если вы не учитываете независимость от базы данных, то у вас будет совсем другой опыт использования T-SQL или PL/SQL.
Если вы используете Oracle для разработки приложения, PL / SQL является очевидным выбором в качестве языка. Он очень тесно связан с данными, постоянно совершенствуется во всех отношениях, и любой достойный инструмент разработки собирается интегрировать разработку PL / SQL с CVS или Subversion или что-то подобное.
Веб-среда разработки приложений Oracle Express даже на 100% построена на PL/SQL.
Если вам нужна независимость от базы данных, вы, вероятно, захотите поместить всю свою бизнес-логику на уровень приложений, поскольку стандарты, доступные на уровне приложений, гораздо более распространены, чем стандарты, доступные на уровне баз данных.
Однако, если независимость от базы данных не является фактором № 1, а набор навыков вашей команды включает в себя сильные навыки работы с базами данных, то размещение бизнес-логики в базе данных может оказаться лучшим решением. Вы можете сделать так, чтобы ваши прикладные сотрудники выполняли специфичные для приложения вещи, а ваши сотрудники базы данных следили за выполнением всех запросов.
Конечно, существует большая разница между способностью объединять оператор SQL и обладать "сильными навыками работы с базами данных" - если ваша команда ближе к первому, чем ко второму, то примените логику в приложении, используя один из спящих в этом мире (или смени свою команду!).
По моему опыту, в корпоративной среде вы будете иметь единую целевую базу данных и навыки в этой области - в этом случае поместите все, что можете, в базу данных. Если вы занимаетесь продажей программного обеспечения, стоимость лицензии на базу данных сделает независимость базы данных самым важным фактором, и вы будете реализовывать все, что сможете, на уровне приложений.
Надеюсь, это поможет.
В настоящее время можно представить в subversion ваш сохраненный код proc и отладить этот код с хорошей поддержкой инструментов.
Если вы используете хранимые процедуры, которые сочетают в себе SQL-операторы, вы можете уменьшить объем трафика данных между приложением и базой данных, уменьшить количество обращений к базе данных и получить значительный прирост производительности.
Как только мы начали сборку в C#, мы приняли решение не использовать хранимые процессы, но теперь мы перемещаем все больше и больше кода в хранимые процедуры. Особенно пакетная обработка.
Однако не используйте триггеры, используйте хранимые процедуры или лучшие пакеты. Триггеры уменьшают ремонтопригодность.
Размещение кода на уровне приложения приведет к созданию приложения, независимого от БД.
Иногда лучше использовать хранимые процедуры из соображений производительности.
Это (как обычно) зависит от требований приложения.
Бизнес-логика должна быть помещена в приложение / средний уровень в качестве первого выбора. Таким образом, его можно выразить в форме модели предметной области, поместить в систему контроля версий, разделить или объединить со связанным кодом (с рефакторингом) и т. Д. Это также дает вам некоторую независимость от поставщика базы данных.
Объектно-ориентированные языки также гораздо более выразительны, чем хранимые процедуры, что позволяет вам лучше и проще описывать в коде, что должно происходить.
Единственные веские причины для размещения кода в хранимых процедурах: если это приводит к значительному и необходимому выигрышу в производительности или если один и тот же бизнес-код должен выполняться несколькими платформами (Java, C#, PHP). Даже при использовании нескольких платформ существуют альтернативы, такие как веб-сервисы, которые могут лучше подходить для совместного использования функций.
Ответ в моем опыте лежит где-то на спектре ценностей, обычно определяемых тем, где лежат навыки вашей организации.
СУБД является очень мощным зверем, что означает, что правильное или неправильное обращение принесет большую пользу или большую опасность. К сожалению, во многих организациях основное внимание уделяется программированию; Навыки dbms, особенно навыки разработки запросов (в отличие от административных), игнорируются. Что усугубляется тем фактом, что способность оценивать навыки дбмс также, вероятно, отсутствует.
И есть немного программистов, которые достаточно понимают, что они не понимают о базах данных.
Отсюда популярность неоптимальных понятий, таких как Active Records и LINQ (чтобы добавить некоторые очевидные предвзятости). Но они, вероятно, лучший ответ для таких организаций.
Тем не менее, обратите внимание, что очень масштабные организации, как правило, уделяют гораздо больше внимания эффективному использованию хранилища данных.
Бизнес-логика должна быть размещена на уровне приложения, а не в базе данных. Причина в том, что хранимая процедура базы данных всегда зависит от используемого вами продукта базы данных. Это нарушает одно из преимуществ трехуровневой модели. Вы не можете легко перейти на другую базу данных, если не предоставите дополнительную хранимую процедуру для этого продукта базы данных. с другой стороны, иногда имеет смысл поместить логику в хранимую процедуру для оптимизации производительности.
Я хочу сказать, что бизнес-логику нужно поместить в уровень приложений, но есть исключения (в основном из-за соображений производительности).
По моему мнению. Есть две противоречивые проблемы с решением, куда идет бизнес-логика в приложении на основе реляционной базы данных:
- ремонтопригодность
- надежность
Число рейнольдса Сопровождаемость: чтобы обеспечить эффективное будущее развитие, бизнес-логика принадлежит к той части вашего приложения, которую проще всего отлаживать и контролировать версии.
Число рейнольдса надежность: когда существует значительный риск несоответствия, бизнес-логика относится к уровню базы данных. Реляционные базы данных могут быть спроектированы для проверки ограничений на данные, например, не допускать значения NULL в определенных столбцах и т. Д. Когда в проекте приложения возникает сценарий, когда некоторые данные должны находиться в определенном состоянии, которое слишком сложно выразить с помощью этих простых ограничения, может иметь смысл использовать триггер или что-то подобное на уровне базы данных.
Триггеры - это боль, чтобы быть в курсе, особенно когда ваше приложение должно работать на клиентских системах, к которым у вас даже нет доступа. Но это не значит, что их невозможно отследить или обновить. Аргументы С. Лотта в его ответе о том, что это боль и неприятности, полностью действительны, я повторю это и тоже был там. Но если вы будете помнить об этих ограничениях при первом проектировании слоя данных и воздерживаться от использования триггеров и функций ни для чего, кроме абсолютных потребностей, это будет управляемым.
В нашем приложении большая часть бизнес-логики содержится на уровне модели приложения, например, счет-фактура знает, как инициализировать себя из данного заказа на продажу. Когда куча разных вещей изменяется последовательно для такого сложного набора изменений, как этот, мы сворачиваем их в транзакцию для обеспечения согласованности, вместо того чтобы выбирать хранимую процедуру. Подсчет итогов и т. Д. Выполняется методами на уровне модели. Но когда нам нужно что-то денормализовать для повышения производительности или вставить данные в таблицу "изменений", используемую всеми клиентами, чтобы выяснить, какие объекты им нужно истечь в их кеше сеанса, мы используем триггеры / функции на уровне базы данных, чтобы вставить новую строку и отправьте уведомление (Postgres прослушать / уведомить материал) от этого триггера.
После того, как наше приложение работало в течение года и использовалось сотнями клиентов каждый день, единственное, что я хотел бы изменить, если бы мы начинали с нуля, - это разработать нашу систему для создания функций базы данных (или хранимых процедур, однако вы хочу позвонить им) с учетом версий и обновлений для них с самого начала.
К счастью, у нас есть какая-то система для отслеживания версий схемы, поэтому мы создали что-то еще, чтобы позаботиться о замене функций базы данных. Это бы сэкономило нам некоторое время, если бы мы с самого начала рассмотрели необходимость их замены.
Конечно, все меняется, когда вы выходите за пределы сферы СУРБД в системы хранения кортежей, такие как Amazon SimpleDB и Google BigTable. Но это другая история:)
"Слои" бизнес-приложений:
1. Пользовательский интерфейс
Это реализует представление бизнес-пользователя о работе h(is/er). Он использует термины, с которыми пользователь знаком.
2. Обработка
Здесь происходят вычисления и манипулирование данными. Любая бизнес-логика, которая предполагает изменение данных, реализована здесь.
3. База данных
Это могут быть: нормализованная последовательная база данных (стандартные СУБД на основе SQL); OO-база данных, хранящая объекты, обертывающие бизнес-данные; и т.п.
Что идет куда
При переходе на вышеперечисленные слои вам необходимо провести необходимый анализ и проектирование. Это будет указывать, где лучше всего реализовать бизнес-логику: правила целостности данных и проблемы параллелизма / реального времени, касающиеся обновлений данных, обычно реализуются как можно ближе к данным, как и вычисляемые поля, и это хороший указатель к хранимым процедурам / триггерам, где целостность данных и контроль транзакций абсолютно необходимы.
Бизнес-правила, включающие значение и использование данных, по большей части будут реализованы на уровне обработки, но также появятся в пользовательском интерфейсе как рабочий процесс пользователя - связывая различные процессы в некоторой последовательности, которая отражает работа пользователя.
На этот вопрос не существует отдельного правильного ответа. Это зависит от требований вашего приложения, предпочтений и навыков ваших разработчиков, а также от фазы луны.
Масштабируемость также является очень важным фактором для использования бизнес-логики на среднем уровне или уровне приложения, а не на уровне базы данных. Следует понимать, что DatabaseLayer предназначен только для взаимодействия с базой данных, а не с манипуляциями, которые возвращаются в базу данных или из нее.
Я помню, как где-то читал статью, в которой говорилось, что на каком-то уровне все может быть частью бизнес-логики, и поэтому этот вопрос не имеет смысла.
Я думаю, что приведенный пример был отображением счета на экране. Решение пометить просроченный красным цветом является деловым решением...
Это континуум. ИМХО самый большой фактор это скорость. Как сделать так, чтобы этот лохотрон работал и работал как можно быстрее, при этом придерживаясь таких хороших клиентов в программировании, как удобство обслуживания, производительность, масштабируемость, безопасность, надежность и т. Д. Зачастую SQL является наиболее кратким способом выражения чего-либо, а также бывает самый производительный во многих случаях, за исключением строковых операций и т. д., но здесь могут помочь ваши CLR Procs. Я верю в то, чтобы свободно распространять бизнес-логику везде, где вы чувствуете, что это лучше всего подходит для данного дела. Если у вас есть куча разработчиков приложений, которые обосрались, глядя на SQL, то пусть они используют логику своего приложения. Если вы действительно хотите создать высокопроизводительное приложение с большими наборами данных, поместите в БД как можно больше логики. Увольняйте своих администраторов баз данных и дайте разработчикам максимальную свободу над своими базами данных Dev. Нет единого ответа или лучшего инструмента для работы. У вас есть несколько инструментов, поэтому вы станете экспертом на всех уровнях приложения, и вскоре вы обнаружите, что тратите гораздо больше времени на написание красивого и выразительного SQL-кода, где это оправдано, и в других случаях на прикладном уровне. Для меня, в конечном счете, сокращение числа строк кода - это то, что приводит к простоте. Мы только что преобразовали SQL-приложение, содержащее всего 2500 строк кода приложения и 1000 строк SQL-кода, в модель предметной области, которая теперь имеет 15500 строк кода приложения и 2500 строк SQL-кода, чтобы достичь того, что делало прежнее приложение SQL-rich. Если вы можете оправдать 6-кратное увеличение кода как "упрощенное", тогда продолжайте.
Это большой вопрос! Я нашел это после того, как уже задал симлиарный вопрос, но это более конкретно. Это появилось в результате решения об изменении дизайна, которое я не принимал участие в принятии.
По сути, мне сказали, что если у вас есть миллионы строк данных в таблицах базы данных, обратите внимание на размещение бизнес-логики в хранимых процедурах и триггерах. Это то, что мы делаем прямо сейчас, превращая Java-приложение в хранимые процедуры для удобства сопровождения, поскольку код Java стал более сложным.
Я нашел эту статью на тему: Войны бизнес-логики. Автор также сделал миллион строк в аргументе таблицы, что мне показалось интересным. Он также добавил бизнес-логику в javascript, который находится на стороне клиента и за пределами уровня бизнес-логики. Я не думал об этом раньше, хотя я использовал JavaScript для проверки в течение многих лет, наряду с проверкой на стороне сервера.
Мое мнение таково, что вам нужна бизнес-логика на уровне приложения / среднего уровня, как правило, но не стоит сбрасывать со счетов случаи, когда имеет смысл поместить ее в базу данных.
И последнее: есть еще одна группа, в которой я сейчас работаю, которая выполняет огромную работу с базами данных для исследований, и объем данных, с которыми они имеют дело, огромен. Тем не менее, для них у них нет бизнес-логики в самой базе данных, но они хранятся на уровне приложений / промежуточного уровня. Для их дизайна, приложение / средний уровень было правильным местом для него, поэтому я не стал бы использовать размер таблиц в качестве единственного подхода к проектированию.
Мы храним много бизнес-логики в хранимых процедурах - она не идеальна, но часто это хороший баланс между производительностью и надежностью.
И мы знаем, где это, без необходимости искать через акры решений и кодовой базы!
Бизнес-логика обычно состоит из объектов и различных языковых конструкций инкапсуляции, наследования и полиморфизма. Например, если банковское приложение раздает деньги, может существовать тип Money, который определяет бизнес-элементы того, что такое "деньги". Это в отличие от использования примитивного десятичного числа для представления денег. По этой причине хорошо продуманная ООП - это то место, где живет "бизнес-логика", а не строго на каком-либо уровне.