За и против помещения логики в SQL? [закрытый]

7
задан Nathan Long 22 July 2010 в 14:04
поделиться

10 ответов

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

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

7
ответ дан 6 December 2019 в 07:24
поделиться

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

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

7
ответ дан 6 December 2019 в 07:24
поделиться

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

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

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

2
ответ дан 6 December 2019 в 07:24
поделиться

У этого аргумента не так много абсолютных плюсов и минусов, поэтому ответ - «это зависит от обстоятельств». Некоторые сценарии с различными условиями, которые влияют на это решение, могут быть следующими:

Клиент-серверное приложение

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

Этот тип архитектуры несколько немодный в наши дни, но в какой-то момент считался лучшим способом сделать это. Многие VB, Oracle Forms, Informix 4GL и другие клиент-серверные приложения того времени были созданы таким образом, и на самом деле это работает довольно хорошо.

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

Актуален ли он сегодня? Довольно часто богатый клиент является подходящей платформой для приложения, и определенно ведется много новых разработок с Winforms и Swing. Сегодня у нас действительно есть хорошие ORM с открытым исходным кодом, где в приложении Oracle Forms 1995 года выпуска, возможно, не было возможности использовать этот тип технологии.Однако решение об использовании ORM определенно не одно и то же - в книге Фаулера Patterns of Enterprise Application Architecture довольно хорошо проработан ряд стратегий доступа к данным и обсуждены их относительные достоинства.

Трехуровневое приложение с богатой объектной моделью

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

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

Дополнительные пакетные процессы

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

В этом случае SQL вполне может быть подходящим способом сделать это, хотя традиционные 3GL (особенно COBOL) были разработаны специально для этого типа обработки.В действительно больших средах (особенно мэйнфреймах) выполнение этого типа обработки с плоскими файлами или файлами VSAM вне базы данных может быть самым быстрым способом сделать это. Кроме того, некоторые задания могут быть изначально ориентированы на записи и процедурные, или могут быть гораздо более прозрачными и обслуживаемыми, если реализованы таким образом.

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

Отчетность

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

Другие области

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

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

3
ответ дан 6 December 2019 в 07:24
поделиться

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

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

1
ответ дан 6 December 2019 в 07:24
поделиться

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

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

0
ответ дан 6 December 2019 в 07:24
поделиться

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

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

1
ответ дан 6 December 2019 в 07:24
поделиться

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

SELECT P.LastName, 'Michael' AS FirstName
    FROM University.PhilosophyProfessors P
    WHERE P.LastName = 'Baldwin'
UNION ALL SELECT P.LastName, 'Bruce' AS FirstName
    FROM University.PhilosophyProfessors P
    WHERE P.LastName <> 'Baldwin'

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

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

1
ответ дан 6 December 2019 в 07:24
поделиться

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

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

0
ответ дан 6 December 2019 в 07:24
поделиться

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

Например, рассмотрим таблицу со столбцами FirstName и LastName и приложение, которое часто использует поле FullName. У вас есть три варианта:

  1. Запросить имя и фамилию и вычислить полное имя в коде приложения.

  2. Выполняйте запросы первым, последним и (первым || последним) в SQL вашего приложения всякий раз, когда вы запрашиваете таблицу.

  3. Определите представление CustomerExt, которое включает первый и последний столбцы, а также столбец с вычисленным полным именем, а затем запросите это представление, а не таблицу клиентов.

Я считаю, что вариант 3 явно верен. Рассмотрим добавление поля MiddleInitial в таблицу и вычисление полного имени.Используя вариант 3, вам просто нужно заменить представление, и каждое приложение в вашей компании мгновенно будет использовать новый формат для FullName. Представление по-прежнему делает базовые столбцы доступными для тех экземпляров, в которых вам нужно выполнить какое-то специальное форматирование, но для стандартного экземпляра все работает «автоматически».

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

2
ответ дан 6 December 2019 в 07:24
поделиться
Другие вопросы по тегам:

Похожие вопросы: