Каковы преимущества / недостатки хранения SQL в исходном коде C # или в хранимых процессах? Я обсуждал это с другом в проекте с открытым исходным кодом, над которым мы работаем (C # ASP.NET Forum). В настоящее время большая часть доступа к базе данных осуществляется путем встроенного SQL в C # и обращения к БД SQL Server. Поэтому я пытаюсь определить, какой для этого конкретного проекта будет наилучшим.
Пока что у меня есть:
Преимущества для в коде:
- Проще поддерживать - не нужно запускать SQL-скрипт для обновления запросов
- Проще портировать на другую БД - без процов на порт
Преимущества для хранимых процедур:
- Производительность
- Безопасность
c#
sql
sql-server
stored-procedures
парень
источник
источник
Ответы:
Я не фанат хранимых процедур
В конечном итоге вы перекомпилируете его, когда типы данных изменятся, или вы захотите вернуть дополнительный столбец, или что-то еще. Количество раз, когда вы можете «прозрачно» изменить SQL из своего приложения, в целом довольно мало
Языки программирования, включая C #, имеют эту удивительную вещь, называемую функцией. Это означает, что вы можете вызывать один и тот же блок кода из нескольких мест! Удивительный! Затем вы можете поместить повторно используемый код SQL в один из них, или, если вы хотите получить действительно высокотехнологичный, вы можете использовать библиотеку, которая сделает это за вас. Я считаю, что они называются объектно-реляционными картографами, и в наши дни они довольно распространены.
Согласен, поэтому хранимые процессы - это плохо. Гораздо проще реорганизовать и разложить (разбить на более мелкие части) код на функции, чем SQL на ... блоки SQL?
Почему ваши приложения Windows подключаются напрямую к центральной базе данных? Это похоже на ОГРОМНУЮ дыру в безопасности и узкое место, поскольку исключает кеширование на стороне сервера. Разве они не должны подключаться через веб-сервис или аналогично вашим веб-серверам?
Итак, нажмите 1 новый sproc или 4 новых веб-сервера?
В этом случае это проще нажать одну новую sproc, но по моему опыту, 95% от «подтолкнули изменений» влияют на код , а не базы данных. Если вы отправляете 20 вещей на веб-серверы в этом месяце, а 1 - на базу данных, вы вряд ли сильно потеряете, если вместо этого отправите 21 вещь на веб-серверы и ноль на базу данных.
Можете ли вы объяснить, как? Я не понимаю этого. Особенно учитывая, что спроки, вероятно, не находятся в управлении исходным кодом, и поэтому не могут быть доступны через веб-браузеры SCM и так далее.
Больше минусов:
Storedprocs живут в базе данных, которая выглядит для внешнего мира как черный ящик. Простые вещи, такие как желание поместить их в систему контроля версий, становятся кошмаром.
Есть также проблема явных усилий. Возможно, имеет смысл разбить все на миллион ярусов, если вы пытаетесь объяснить своему генеральному директору, почему им просто нужно 7 миллионов долларов на создание некоторых форумов, но в противном случае создание хранимого процесса для каждой мелочи - просто лишняя работа для пустяка. выгода.
источник
Это обсуждается в нескольких других темах здесь в настоящее время. Я последовательный сторонник хранимых процедур, хотя приводятся некоторые хорошие аргументы для Linq to Sql.
Встраивание запросов в ваш код тесно связывает вас с вашей моделью данных. Хранимые процедуры являются хорошей формой контрактного программирования. Это означает, что администратор базы данных имеет свободу изменять модель данных и код в процедуре, если поддерживается контракт, представленный входами и выходами хранимой процедуры.
Настройка производственных баз данных может быть чрезвычайно сложной, когда запросы скрыты в коде, а не в одном центральном, простом в управлении месте.
[Редактировать] Вот еще одно текущее обсуждение
источник
По моему мнению, вы не можете голосовать за или нет по этому вопросу. Это полностью зависит от дизайна вашего приложения.
Я полностью голосую против использования SP в 3-х уровневой среде, где перед вами стоит сервер приложений. В такой среде ваш сервер приложений предназначен для запуска вашей бизнес-логики. Если вы дополнительно используете SP, вы начнете распространять свою реализацию бизнес-логики по всей вашей системе, и станет очень неясно, кто за что отвечает. В конце концов вы получите сервер приложений, который в основном не будет делать ничего, кроме следующего:
В итоге ваш средний уровень работает на этом очень крутом кластере из 4 серверов, каждый из которых оснащен 16 процессорами, и он на самом деле ничего не будет делать! Какая трата!
Если у вас есть толстый графический клиент, который напрямую подключается к вашей БД, или, может быть, даже больше приложений, это другая история. В этой ситуации SP могут служить своего рода псевдо-средним уровнем, который отделяет ваше приложение от модели данных и предлагает контролируемый доступ.
источник
На самом деле, я думаю, что у вас есть это задом наперед. ИМХО, SQL в коде - боль в поддержке, потому что:
Хранимые Procs воспринимаются как методы, которые вы вызываете из объекта базы данных - их гораздо проще использовать повторно, есть только одно место для редактирования, и в случае, если вы меняете поставщиков БД, изменения происходят в ваших Stored Procs, а не в вашем коде ,
Тем не менее, прирост производительности хранимых процедур минимален, как сказал до меня Стю, и вы не можете поставить точку останова в хранимой процедуре (пока).
источник
ПРОТИВ
Я считаю, что выполнение большого количества обработки внутри хранимых процедур сделало бы ваш сервер БД единственной точкой негибкости, когда дело доходит до масштабирования вашего действия.
Однако выполнение всего этого перебора в вашей программе, в отличие от sql-сервера, может позволить вам масштабировать больше, если у вас есть несколько серверов, на которых работает ваш код. Конечно, это не относится к хранимым процессам, которые выполняют только обычную выборку или обновление, но к тем, которые выполняют больше операций, таких как циклический просмотр наборов данных.
ПРОФИ
источник
Преимущество производительности для хранимых процедур часто пренебрежимо мало.
Больше преимуществ для хранимых процедур:
источник
Я падаю на стороне кода . Мы создаем слой доступа к данным, который используется всеми приложениями (как веб-, так и клиентскими), поэтому он СУХОЙ с этой точки зрения. Это упрощает развертывание базы данных, потому что мы просто должны убедиться в правильности схемы таблицы. Это упрощает обслуживание кода, потому что нам не нужно смотреть на исходный код и базу данных.
У меня нет особых проблем с тесной связью с моделью данных, потому что я не вижу, где можно действительно сломать эту связь. Приложение и его данные неразрывно связаны.
источник
Хранимые процедуры.
Если ошибка проскальзывает или логика немного меняется, вам не нужно перекомпилировать проект. Кроме того, он позволяет получать доступ из разных источников, а не только из одного места, где вы закодировали запрос в своем проекте.
Я не думаю, что поддерживать хранимые процедуры сложнее, вы не должны кодировать их непосредственно в базе данных, но сначала в отдельных файлах, затем вы можете просто запускать их в любой БД, которую вам нужно настроить.
источник
Преимущества для хранимых процедур :
Проще пересмотреть код.
Менее спаренный, поэтому легче тестируется.
Более легко настраивается.
Производительность, как правило, лучше, с точки зрения сетевого трафика - если у вас есть курсор или что-то подобное, то нет многократных поездок в базу данных.
Вы можете легче защитить доступ к данным, удалить прямой доступ к таблицам, обеспечить безопасность с помощью процедур - это также позволяет относительно быстро найти любой код, который обновляет таблицу.
Если задействованы другие службы (например, службы отчетов), вам может оказаться проще хранить всю логику в хранимой процедуре, а не в коде, и вам придется дублировать ее.
Недостатки:
Сложнее управлять разработчикам: контроль версий скриптов: есть ли у каждого своя база данных, интегрирована ли система контроля версий с базой данных и IDE?
источник
В некоторых случаях динамически создаваемый sql-код может иметь более высокую производительность, чем хранимый процесс. Если вы создали хранимый процесс (скажем, sp_customersearch), который становится чрезвычайно сложным с десятками параметров, потому что он должен быть очень гибким, вы, вероятно, можете сгенерировать гораздо более простой оператор SQL в коде во время выполнения.
Можно утверждать, что это просто переносит некоторую обработку с SQL на веб-сервер, но в целом это было бы хорошо.
Еще одна замечательная особенность этого метода заключается в том, что если вы смотрите в профилировщике SQL, вы можете увидеть сгенерированный вами запрос и отладить его гораздо проще, чем увидеть сохраненный вызов proc с 20 параметрами.
источник
Мне нравятся хранимые процедуры, я не знаю, сколько раз мне удавалось вносить изменения в приложение с помощью хранимой процедуры, которая не приводила к простоям приложения.
Большой поклонник Transact SQL, настройка больших запросов оказалась для меня очень полезной. За 6 лет не написал ни одного встроенного SQL!
источник
Вы перечисляете 2 pro-точки для sprocs:
Производительность - не совсем. В Sql 2000 или выше оптимизация плана запросов довольно хороша и кэшируется. Я уверен, что Oracle и т. Д. Делают подобные вещи. Я не думаю, что есть повод для sprocs для производительности больше.
Безопасность? Почему спроки могут быть более безопасными? Если у вас в любом случае нет достаточно незащищенной базы данных, весь доступ будет из ваших администраторов баз данных или из вашего приложения. Всегда параметризуйте все запросы - никогда не вставляйте что-либо из пользовательского ввода, и все будет в порядке.
Это лучшая практика для производительности в любом случае.
Linq - это, безусловно, путь, которым я бы сейчас занялся новым проектом. Смотрите этот похожий пост .
источник
@Keith
Как предлагает Komradekatz, вы можете запретить доступ к таблицам (для комбинации имени пользователя и пароля, которая подключается к БД) и разрешить только доступ к SP. Таким образом, если кто-то получает имя пользователя и пароль в вашу базу данных, он может выполнять SP, но не может получить доступ к таблицам или любой другой части БД.
(Конечно, выполнение sprocs может дать им все необходимые данные, но это будет зависеть от доступных sprocs. Предоставление им доступа к таблицам дает им доступ ко всему.)
источник
Подумай об этом так
У вас есть 4 веб-сервера и несколько приложений для Windows, которые используют один и тот же код SQL. Теперь вы поняли, что с кодом SQl есть небольшая проблема, поэтому вы предпочитаете ...... изменить процедуру в 1 месте или отправить код всем веб-серверы, переустановите все настольные приложения (может помочь clickonce) на всех окнах
Я предпочитаю хранимые процы
Кроме того, проще выполнить тестирование производительности с помощью процесса, поместив его в анализатор запросов, установите статистику io / time, включите showplan_text и вуаля.
нет необходимости запускать профилировщик, чтобы увидеть, что именно называется
только мои 2 цента
источник
Я предпочитаю хранить их в коде (используя ORM, а не inline или ad-hoc), поэтому они защищены системой контроля версий без необходимости сохранять файлы .sql.
Кроме того, хранимые процедуры не являются более безопасными. Вы можете написать неверный запрос с помощью sproc так же легко, как и встроенный. Параметризованные встроенные запросы могут быть такими же безопасными, как sproc.
источник
Используйте код своего приложения, как лучше всего: обрабатывайте логику.
Пользователь вашей базы данных для того, что он делает лучше всего: хранить данные.
Вы можете отлаживать хранимые процедуры, но вам будет легче отлаживать и поддерживать логику в коде. Обычно вы заканчиваете перекомпиляцию кода каждый раз, когда меняете модель базы данных.
Кроме того, хранимые процедуры с необязательными параметрами поиска очень неэффективны, поскольку вам необходимо заранее указать все возможные параметры, а сложные поиски иногда невозможны, поскольку вы не можете предсказать, сколько раз параметр будет повторяться в поиске.
источник
Когда дело доходит до безопасности, хранимые процедуры намного более безопасны. Некоторые утверждают, что все доступ будет через приложение в любом случае. Многие люди забывают, что большинство нарушений безопасности происходят изнутри компании. Подумайте, сколько разработчиков знают «скрытое» имя пользователя и пароль для вашего приложения?
Кроме того, как отметил MatthieuF, производительность может быть значительно улучшена за счет меньшего количества циклов между приложением (будь то на настольном компьютере или веб-сервере) и сервером базы данных.
По моему опыту, абстракция модели данных с помощью хранимых процедур также значительно повышает удобство сопровождения. Как человек, которому в прошлом приходилось обслуживать много баз данных, это такое облегчение, когда он сталкивается с необходимостью изменения модели, чтобы иметь возможность просто изменить хранимую процедуру или две и сделать это изменение полностью прозрачным для ВСЕХ внешних приложений. Много раз ваше приложение не единственное, которое указывает на базу данных - есть другие приложения, решения для составления отчетов и т. Д., Поэтому отслеживание всех этих уязвимых точек может быть проблемой с открытым доступом к таблицам.
Я также поставлю отметки в столбце «плюс», чтобы передать программирование на SQL тем, кто специализируется на нем, и SP, которые значительно облегчат изоляцию и тестирование / оптимизацию кода.
Единственным недостатком, который я вижу, является то, что многие языки не допускают передачу параметров таблицы, поэтому передача значений данных с неизвестным числом может раздражать, и некоторые языки по-прежнему не могут обрабатывать получение нескольких наборов результатов из одной хранимой процедуры (хотя последний не делает SP в этом отношении хуже встроенного SQL).
источник
Одно из предложений от сеансов Microsoft TechEd по безопасности, которые я посетил, чтобы сделать все вызовы через хранимые процедуры и запретить доступ непосредственно к таблицам. Этот подход был объявлен как обеспечение дополнительной безопасности. Я не уверен, стоит ли это только ради безопасности, но если вы уже используете хранимые процедуры, это не повредит.
источник
Определенно легче поддерживать, если вы поместите его в хранимую процедуру. Если существует сложная логика, которая потенциально может измениться в будущем, то, безусловно, было бы неплохо поместить ее в базу данных, когда подключено несколько клиентов. Например, я сейчас работаю над приложением, которое имеет веб-интерфейс для конечного пользователя и приложение для рабочего стола администратора, оба из которых совместно используют базу данных (очевидно), и я пытаюсь сохранить как можно больше логики в базе данных. Это прекрасный пример принципа СУХОЙ .
источник
Я твердо на стороне хранимых процедур, предполагая, что вы не обманываете и не используете динамический SQL в хранимых процессах. Во-первых, использование хранимых процедур позволяет dba устанавливать разрешения на уровне хранимых процедур, а не на уровне таблицы. Это важно не только для борьбы с атаками SQL-инъекций, но и для предотвращения прямого доступа инсайдеров к базе данных и изменения вещей. Это способ предотвратить мошенничество. Никакая база данных, которая содержит личную информацию (номера SSN, номера кредитных карт и т. Д.) Или которая в любом случае создает финансовые транзакции, никогда не должна быть доступна, кроме как через строгие процедуры. Если вы используете любой другой метод, вы оставляете свою базу данных широко открытой для частных лиц в компании, чтобы создавать поддельные финансовые транзакции или красть данные, которые могут быть использованы для кражи личных данных.
Хранимые процедуры также намного проще в обслуживании и настройке производительности, чем SQL, отправленный из приложения. Они также позволяют dba увидеть, какое влияние окажут структурные изменения базы данных на доступ к данным. Я никогда не встречал хорошего DBA, который позволил бы динамический доступ к базе данных.
источник
Мы используем хранимые процедуры с базами данных Oracle, где я сейчас работаю. Мы также используем Subversion. Все хранимые процедуры создаются в виде файлов .pkb и .pks и сохраняются в Subversion. Я сделал встроенный SQL раньше, и это боль! Я предпочитаю, как мы делаем это здесь. Создавать и тестировать новые хранимые процедуры намного проще, чем делать это в своем коде.
Есть
источник
Меньшие журналы
Еще один мелкий профессионал для хранимых процедур, который не был упомянут: когда речь идет о трафике SQL, доступ к данным на основе sp генерирует намного меньше трафика. Это становится важным, когда вы отслеживаете трафик для анализа и профилирования - журналы будут намного меньше и удобочитаемее.
источник
Я не большой поклонник хранимых процедур, но я использую их в одном условии:
Когда запрос довольно большой, лучше хранить его в базе данных как хранимую процедуру, а не отправлять его из кода. Таким образом, вместо отправки огромного количества строковых символов с сервера приложений в базу данных
"EXEC SPNAME"
будет отправлена только команда.Это излишне, когда сервер базы данных и веб-сервер не находятся в одной сети (например, интернет-связь). И даже если это не так, слишком много стресса означает много потраченной впустую полосы.
Но человек, им так ужасно управлять. Я избегаю их столько, сколько могу.
источник
Процесс, хранимый в SQL, не увеличивает производительность запроса
источник
Очевидно, что использование хранимых процедур имеет несколько преимуществ по сравнению с построением SQL в коде.
источник
Хранимые процедуры более удобны в обслуживании, потому что:
Повторение кода - худшее, что вы можете сделать, когда пытаетесь создать поддерживаемое приложение!
Что происходит, когда вы обнаружите логическую ошибку, которую необходимо исправить в нескольких местах? Вы более склонны забыть изменить последнее место, куда вы копировали и вставляли свой код.
На мой взгляд, повышение производительности и безопасности является дополнительным плюсом. Вы по-прежнему можете писать небезопасные / неэффективные хранимые процедуры SQL.
Нетрудно написать все хранимые процедуры для создания в другой БД. На самом деле - это проще, чем экспортировать таблицы, потому что нет первичных / внешних ключей, о которых нужно беспокоиться.
источник
@Terrapin - спроки столь же уязвимы для атак инъекций. Как я сказал:
Это касается sprocs и динамического Sql.
Я не уверен, что перекомпиляция вашего приложения является преимуществом. Я имею в виду, что вы выполнили свои модульные тесты для этого кода (как приложения, так и БД), прежде чем все равно снова начать работу.
@ Да, да, вы правы, sprocs позволяет вам контролировать пользователей приложений, чтобы они могли выполнять только sproc, а не основное действие.
Мой вопрос был бы: если весь доступ к нему через ваше приложение, используя соединения и пользователей с ограниченными правами на обновление / вставку и т. Д., Добавляет ли этот дополнительный уровень безопасность или дополнительное администрирование?
Мое мнение очень последнее. Если они скомпрометировали ваше приложение до такой степени, что они могут переписать его, у них есть множество других атак, которые они могут использовать.
Sql-инъекции могут все еще выполняться против этих sprocs, если они динамически встроенный код, так что золотое правило все еще применяется, весь пользовательский ввод всегда должен быть параметризован.
источник
То, что я не видел, упоминалось до сих пор: люди, которые лучше всего знают базу данных, не всегда люди, которые пишут код приложения. Хранимые процедуры дают возможность пользователям баз данных взаимодействовать с программистами, которые на самом деле не хотят много изучать SQL. Большие - и особенно унаследованные - базы данных - не самая простая вещь для полного понимания, поэтому программисты могут предпочесть простой интерфейс, который дает им то, что им нужно: позвольте администраторам баз данных выяснить, как объединить 17 таблиц, чтобы это произошло.
Тем не менее, языки, используемые для написания хранимых процедур (PL / SQL является пресловутым примером), довольно жестоки. Как правило, они не предлагают никаких изысков, которые вы бы увидели в популярных на сегодняшний день императивных, ООП или функциональных языках. Подумай, Кобол.
Поэтому придерживайтесь хранимых процедур, которые просто абстрагируют реляционные детали, а не те, которые содержат бизнес-логику.
источник
Я вообще пишу ОО код. Я подозреваю, что большинство из вас, вероятно, тоже. В этом контексте мне кажется очевидным, что вся бизнес-логика, включая запросы SQL, относится к определениям классов. Разделение логики таким образом, что ее часть находится в объектной модели, а часть в базе данных, не лучше, чем внедрение бизнес-логики в пользовательский интерфейс.
Многое было сказано в предыдущих ответах о преимуществах безопасности хранимых процедур. Они делятся на две большие категории:
1) Ограничение прямого доступа к данным. Это, безусловно, важно в некоторых случаях, и, когда вы сталкиваетесь с ним, сохраняемые процы являются практически единственным вариантом. Однако, по моему опыту, такие случаи являются скорее исключением, чем правилом.
2) SQL-инъекция / параметризованные запросы. Это возражение - красная сельдь. Встроенный SQL - даже динамически генерируемый встроенный SQL - может быть столь же полностью параметризован, как и любой хранимый процесс, и это можно сделать так же легко на любом современном языке, который стоит того. Здесь нет никакого преимущества. («Ленивые разработчики могут не беспокоиться об использовании параметров» не является обоснованным возражением. Если в вашей команде есть разработчики, которые предпочитают просто объединять пользовательские данные в их SQL вместо использования параметров, сначала вы пытаетесь обучить их, а затем запустить их если это не сработает, так же, как вы это делаете с разработчиками, у которых есть другие вредные, явно вредные привычки.)
источник
Я большой сторонник кода над SPROC. Причиной номер один является сохранение тесно связанного кода, а вторая - легкость управления исходным кодом без большого количества пользовательских утилит, которые его поддерживают.
В нашем DAL, если у нас очень сложные операторы SQL, мы обычно включаем их в качестве файлов ресурсов и обновляем их по мере необходимости (это может быть также отдельная сборка с заменой на дБ и т. Д.).
Это сохраняет наш код и наши вызовы sql в одном и том же контроле версий, не забывая запускать некоторые внешние приложения для обновления.
источник