Размещение логики базы данных в приложении вместо триггера, хранимых процедур, ограничений и т. Д. - PullRequest
6 голосов
/ 31 июля 2010

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

Интересно, стоит ли вместо этого помещать логику базы данных в само приложение?

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

Это правильный путь?

Спасибо

Ответы [ 8 ]

14 голосов
/ 31 июля 2010

(Примечание: это пост-центрированный пост. У меня есть многолетний опыт работы с MySQL, а также с несколькими Postgres и Oracle. Я предпочитаю Postgres по миле страны, но это не главное в этом посте.)

Это действительно вопрос о двух направлениях: должна ли база данных быть просто хранилищем данных или содержать логику приложения? Есть случаи для обоих.

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

Дейв Маркл в другом ответе хорошо говорит о триггерах, которые, как правило, являются «волшебными» для разработчика. Изменение ввода по пути может быть очень запутанным. Если я говорю UPDATE foo set X=3;, но затем проверяю foo и x действительно 4, потому что какой-то триггер его перехватил, это может сбить с толку. Как и Дэйв, я склонен продвигать триггеры для функций аудита и тому подобного. Другая проблема, связанная с триггерами, - это производительность, они могут просто высосать жизнь из хорошей пакетной операции.

Хранимые процедуры - я придерживаюсь гораздо более высокого мнения. Разработчик явно вызывает их, и они названы, поэтому он не должен видеть их как черный ящик. Хорошая хранимая процедура может значительно увеличить скорость за счет уменьшения количества строк, которые необходимо «отправить по проводам». Для БД, такой как Postgres с сильным набором PL-языков, действительно нет ничего, что не может быть в SP (это не означает, что это ДОЛЖНО быть сделано, но может быть). Взгляните на SimplyCity , чтобы узнать, как хранимые процедуры могут быть вашими друзьями. Кроме того, вы можете разделить классы логики приложения между кодом приложения и PL / python, PL / Perl или PL / Php, PL / Ruby или PL / Java. Я считаю, что Oracle может сделать нечто подобное с Java - просто это не то, с чем работает компания, в которой я сейчас работаю с Oracle.

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

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

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

6 голосов
/ 31 июля 2010

Я дам ответ, вероятно, противоположный тому, что скажут все остальные.

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

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

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

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

5 голосов
/ 31 июля 2010

Если вы уже используете Ruby on Rails, значит, вы решили использовать самоуверенное программное обеспечение. Так или иначе, по мнению Rails, логика заключается в том, что логика лежит в приложении Rails. Для этого даже требуется обеспечить принудительное использование ссылочной целостности через ActiveRecord и его ассоциации, хотя вы, конечно, можете применить это в базе данных, если захотите, добавив ограничения к вашим таблицам. Многие разработчики Rails не беспокоятся ни по незнанию, ни по выбору.

  • Повышение производительности, которое обеспечивает Rails, имеет тенденцию уменьшаться, когда вы начинаете отклоняться от его мнений и соглашений
  • Если вы пишете приложение такого типа, которое манипулирует большими объемами данных и получит выгоду от использования определенных функций СУБД, то это в любом случае плохо подходит для Rails, поскольку оно оптимизировано для создания новых веб-приложений CRUD
4 голосов
/ 31 июля 2010

Я сам в лагере "логики приложений".

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

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

4 голосов
/ 31 июля 2010

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

Логика зависит от базы данных - например, MySQL не имеет ни рекурсивной поддержки запросов, ни аналитических функций. PostgreSQL только недавно получил аналитику - SQL Server имел оба с v2005; Oracle с 9i.

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

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

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

Заключение

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

1 голос
/ 31 июля 2010

Есть логика данных и логика приложения.База данных должна знать все о логике данных, приложении о логике приложения.Логика данных может храниться в базе данных в виде хранимых процедур, представлений, правил и т. Д. Oracle, PostgreSQL, SQL Server и т. Д. Имеют очень мощные инструменты для поддержки этого.

Многие приложения могут использовать одну и ту же базу данныхте же данные, и вы должны быть уверены, что данные верны.Каждое приложение (на любом языке) может делать разные вещи с этими данными, это зависит от приложения.Построение логики базы данных внутри вашего приложения - это все равно что заново изобретать колесо и создавать проблемы.СУБД имеют 40-летнюю историю разработки, и вы не получите лучшего результата через пару недель или месяцев.

Для PostgreSQL взгляните на разные PL: PL / pgSQL хорош,PL / perl и PL / ruby ​​могут быть более интересными для разработчиков perl и ruby.

1 голос
/ 31 июля 2010

По моему мнению, СУБД должны быть тупыми и гибкими, использоваться исключительно для постоянства, а разрозненные корпоративные приложения должны взаимодействовать с помощью методов SOA.

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

Я думаю об этом таким образом.Если я хочу получить доступ к данным электронной почты моей компании, я не получаю к ним доступ напрямую, где они находятся на диске.Это было бы больно, так как мне пришлось бы разбираться в структурах данных, прежде чем я смог что-либо сделать.Вместо этого я общаюсь с приложением своего почтового сервера (в моем случае Exchange Server) с помощью методов SOA (WebDAV, CDO, LDAP и т. Д.).Это приложение предоставляет уровень абстракции для запроса электронной почты, календаря или данных контактов, отправки электронных писем, создания контактов или встреч, управления календарями и т. Д.

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

1 голос
/ 31 июля 2010

Обычно да, в основном по причинам, которые вы только что упомянули.

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...