2009-07-23 4 views
30

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

Есть ли какие-либо эмпирические правила, о которых вы можете думать в связи с этим?

+0

Предложить удалить php-тег, поскольку php может быть легко любым другим языком программирования. – Iain

ответ

29

Вау ... Я собираюсь плавать прямо против текущего здесь и сказать «почти всегда». Есть список причин из соображений, некоторые из которых я уверен, что другие будут спорить. Но я разработал приложения как с использованием, так и без использования хранимых procs в качестве уровня доступа к данным, и мой опыт заключался в том, что хорошо написанные хранимые процедуры упрощают запись вашего приложения. Тогда есть хорошо документированные характеристики производительности и безопасности.

+6

* хорошо * документально подтвержденная производительность и преимущества безопасности. Просто хотел повторить это. Мы не ставим TSQL в приложениях, КОГДА-ЛИБО. SQL идет в хранимой процедуре, процедура вызывается из кода. Никакой код никогда не затрагивает даже столько, сколько выбор. Запуск SP или нет - это разница между предварительно скомпилированным и интерпретированным кодом, который вы предпочитаете? Ответ на ваш вопрос «ВСЕГДА». – Jeremy

+4

«Хорошо документированный» элемент производительности на самом деле не является проблемой в зависимости от используемого вами механизма базы данных. Тем не менее, вы должны ВСЕГДА использовать хранимые процедуры просто из-за проблем с безопасностью. При использовании procs вы можете запретить прямой доступ к таблице и тем самым полностью защитить себя от большинства форм деструктивной SQL-инъекции. В противном случае вы зависите от кода, чтобы остановить его; которые не все программисты созданы равными. – NotMe

+2

@Chris Lively: параметризованные запросы наиболее безопасны для инъекций sql. См. Http://palisade.plynt.com/issues/2006Jun/injection-stored-procedures/ –

4

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

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

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

Рассмотрим Who Needs Stored Procedures, Anyways?:

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

и Why I do not use Stored Procedures:

Абсолютное худшее, что вы можете сделать, и это ужасающе распространено в мире разработки Microsoft, является split related functionality between sproc's and middle tier code. Grrrrrrrrr. Вы просто делаете код хрупким, и вы увеличиваете интеллектуальные накладные расходы . система.

+3

Плохие примеры не устраняют преимущества при правильном использовании метода. – txwikinger

+0

«Плохие примеры» одного человека - «хорошие примеры того, почему что-то плохо». – cletus

+1

@cletus, который не имеет смысла. Пример всегда ограничен и никогда не доказывает обобщения. – txwikinger

4

В основном, когда вам необходимо выполнить операции с данными, которые не нужны для выхода из базы данных. Например, вы хотите обновить одну таблицу данными от другого, нет смысла извлекать данные и обратно, если вы можете сделать все это одним выстрелом в db.

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

4

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

Очень простой пример:

registerUser(username, password) 

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

Конечно, разные люди будут иметь разные перспективы (DBA против программиста).

+0

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

2

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

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

2

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

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

4

Я использовал хранится проки в 1 из 3 сценариев:

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

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

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

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

Безопасность была одной из причин. Однако, с LINQ и другими ORM там, операции DAL уровня кода намного более безопасны, чем они были в прошлом. Сохраненные procs являются безопасными, но ORM как LINQ.

0

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

Это включает в себя:

  • Наполнение несколько таблиц из одной RowSource
  • Проверка нескольких таблиц против различных бизнес-правил
  • Выполнение операций, которые не могут быть эффективно выполняются с помощью на основе набора подход

и т.д.

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

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

У меня есть статья об этом в своем блоге:

15

Это полностью зависит от вашей среды. Ответ на вопрос на самом деле не является проблемой кодирования или даже проблемой анализа, а бизнес-решением.

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

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

  1. С корпоративной базой данных актив ценен, а недопустимые данные или действия могут иметь угрожающие бизнесу последствия. Ваша главная задача - защитить бизнес, а не то, насколько удобный доступ для ваших кодеров.
  2. Такие базы данных по определению доступны более чем одним приложением. Вам нужно использовать абстракцию, которую предлагают хранимые процедуры, чтобы база данных могла быть изменена, когда приложение A обновлено, и у вас нет ресурса для обновления приложения B.
  3. Аналогично инкапсуляция бизнес-логики в SP, а не в код приложения позволяет изменениям такой логики быть реализованы в бизнесе более легко и надежно, чем если бы такая логика была встроена в код приложения. Например, если изменение налога изменяется, оно меньше работает и более надежное, если расчет должен быть изменен в одном SP, чем несколько приложений.Эмпирическое правило здесь заключается в том, что бизнес-правило должно быть реализовано в ближайшей точке к данным, где оно уникально - поэтому, если у вас есть специализированное приложение, тогда логика для этого приложения может быть реализована в этом приложении, но логика более широко применима бизнес должен быть реализован в СП.

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

0

У меня был очень плохой опыт с этим.

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

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

Во-вторых, написать заявление не так просто, только в хранимых процедурах, хотя я столкнулся с тем, что делало сверхчеловеческие усилия. Таким образом, вы получаете что-то дорогое в обслуживании: оно реализовано на двух разных языках программирования, а исходный код часто не все в одном месте, поскольку хранимые процедуры окончательно хранятся в СУБД, а не в исходном архиве. Предполагая, что кто-то когда-либо управлял/беспокоился, вытаскивать их из сервера базы данных и архивировать их на всех.

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

С другой стороны, хранимые процедуры являются чрезвычайно полезными, ЕСЛИ:

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

  2. Вам требуется производительность, которая может быть достигнута только за счет запуска логики на сервере базы данных, а не в качестве клиента. Но, как я уже сказал, когда вы это делаете, вы едите в общие системные ресурсы сервера СУБД. Поэтому вам следует убедиться, что если есть значимые биты операции о нарушении, которые могут быть выгружены на клиентов, вы можете их разделить и оставить наиболее важные вещи для сервера СУБД.

+1

Если у вас есть «50 веб-серверов», я надеюсь, что у вас есть хотя бы один администратор базы данных. Кто знает TSQL. Это то, что написано в хранимых процедурах. В этом нет ничего грязного - что грязно, не использует процедуры хранилища. – Jeremy

+1

Сохраненные procs не имеют никакого отношения к тому, сколько серверов баз данных вам понадобится. Простая причина заключается в том, что неважно, является ли это proc или встроенным SQL, серверу БД все еще нужно запустить код. – NotMe

+2

", поскольку хранимые процедуры окончательно хранятся в СУБД, а не в исходном архиве" Плохие разработчики. Мы всегда, всегда храним хранимые процедуры в исходном архиве. И их не нужно вытаскивать из базы данных и помещать в исходный архив, поскольку они поступают из исходного архива во все базы данных. (за исключением случаев, когда они разрабатываются в dev.) –

2

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

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

9

Я сказал это в комментарии, но я собираюсь сказать это снова здесь.

Безопасность, охрана, безопасность.

Когда код sql встроен в ваше приложение, вы должны открыть базовые таблицы для прямого доступа. Это может звук в порядке. До тех пор, пока вы не столкнетесь с какой-нибудь SQL-инъекцией, которая скремблирует все поля varchar в вашей базе данных.

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

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

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

Наконец, что касается идеи не использовать s'procs, потому что вам, возможно, придется переносить на другой rdbms: во-первых, большинство приложений не меняют серверы баз данных. Во-вторых, в случае, если это реальная возможность, вам все равно нужно использовать код ANSI sql; которые вы можете сделать в своих процессах. В-третьих, вам придется переоценить весь ваш код sql, несмотря ни на что, и это намного проще, если этот код находится в одном месте. В-четвертых, все современные базы данных теперь поддерживают s'procs. В-пятых, при использовании s'proc вы можете настраивать свой sql для базы данных, в которой он работает, чтобы использовать расширения sql этой конкретной базы данных.

+1

Еще одно преимущество: проще изменить код sql в s'procs в уже выпущенном приложении, чем перенаправить целое приложение из-за незначительного изменения запроса. – NotMe

0

Определенный сценарий, который вы, вероятно, выиграете, включает ситуацию вокруг проблемы масштабируемости (n + 1). Любой вид многомерной/иерархической ситуации, вероятно, будет включать этот сценарий.

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

1

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

0

Если вы говорите бизнес-логику, а не просто «Должен ли я использовать sprocs вообще», я бы сказал, что вы должны поместить бизнес-логику в sprocs, когда выполняете большие операции на основе набора или в любое другое время, выполняющее логику, потребует большое количество вызовов в db из приложения.

0

Это также зависит от вашей аудитории. Является ли удобство установки и переносимости между СУБД важными для вас?

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

+0

Да, да, люди всегда ссылаются на это как на причину, по которой вам следует избегать нестандартного SQL, но на практике вряд ли когда-либо возникает причина для замены поставщика базы данных (я не думаю, что когда-либо видел это за 30 лет в ИТ за исключением самых тривиальных проектов) – Cruachan

2

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

0

Я согласен, что они должны использоваться часто и хорошо.

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

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

Смежные вопросы