Хранимые процедуры MySQL или код php?

Общий вопрос, без конкретного случая в памяти - это обычно предпочитается для использования хранимых процедур MySQL по записи Сценария PHP, который выполняет те же вычисления и запросы?

Каковы преимущества каждого метода?

7
задан Omri 5 August 2010 в 22:09
поделиться

10 ответов

Я думаю, что Джефф Этвуд в 2004 году попал в самую точку в отношении хранимых процедур:

В любом случае, кому нужны хранимые процедуры?

Я широко использовал как хранимые процедуры, так и динамический SQL, я определенно предпочитаю последний: проще управлять , лучшая инкапсуляция, отсутствие BL на уровне доступа к данным, большая гибкость и многое другое. Практически каждый крупный проект PHP с открытым исходным кодом использует динамический SQL поверх хранимых процедур (см .: Drupal, Wordpress, Magento и многие другие).

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

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

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

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

Хранимая процедура 99 раз из 100. Если бы я выбрал 1 причину, то это было бы так, что если ваше веб-приложение php выполняет весь доступ к базе данных через хранимые процедуры, а ваш пользователь базы данных имеет только разрешение на выполнение указанных хранимых процедур, тогда вам 100 % защищен от атак SQL-инъекций.

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

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

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

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

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

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

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

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

Точка / Встреча с Джеффом Этвудсом «Кому вообще нужны хранимые процедуры?» из 2004 :

1) Хранимые процедуры написаны на больших железных «языках» баз данных, таких как PL / SQL (Oracle) или T-SQL (Microsoft). Эти так называемые языки архаичны и полны сумасшедших, бессвязных дизайнерских решений, которые всегда являются результатом мучительной эволюции десяти лет обратной совместимости. Вы действительно не хотите писать много кода в этом материале. Для контекста, JavaScript - это гигантский шаг вперед по сравнению с PL / SQL или T-SQL.

Ответ : «S» в «SQL» означает «структурированный», а не «стандартизованный» - PLSQL и TSQL являются пользовательскими расширениями SQL, которые также используют ANSI SQL, потому что очень мало SQL, независимого от базы данных. Как правило, если вам нужен хорошо работающий запрос, вы не можете полагаться на ANSI SQL.

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

Я никогда не пойму, почему веб-разработка, объединение бесчисленных технологий (HTML, Javascript / AJAX, Flash ...) всегда выделяет SQL как паршивую овцу. семьи. Как и всем остальным, вы должны научиться этому, чтобы получить что-то от этого. Должно быть мгновенное удовлетворение, которое вы получаете при использовании других технологий ...

2) Хранимые процедуры обычно не могут быть отлажены в той же среде IDE, в которой вы пишете свой пользовательский интерфейс. Каждый раз, когда я изолирую исключение в процессах, мне приходится останавливать то, что я делаю, выгружать свою копию Toad и загружать пакеты базы данных, чтобы увидеть, что идет не так. Часто переход между двумя совершенно разными IDE с совершенно разными интерфейсами и языками не совсем продуктивен.

Ответ : Был ли изначально отладчик Javascript в Eclipse или Visual Studio? Нет, они позволяют использовать плагины, чтобы выпустить продукт и оживить ранее несуществующий рынок. У большинства нет проблем с использованием Firebug вне Visual Studio / Eclipse, почему отладка SQL должна быть другой?

3) Хранимые процедуры не обеспечивают особой обратной связи, когда что-то идет не так. Если процесс не закодирован внутренне со странной обработкой исключений T-SQL или PL / SQL, мы получим загадочные «ошибки», возвращаемые на основе конкретной строки внутри процесса, в котором произошел сбой, например, в таблице нет строк.

Ответ : Ваше незнание не делает плохой язык. Как будто вам никогда не приходилось искать в гугле странную ошибку на выбранном вами языке ... По крайней мере, Oracle и MySQL предоставляют ссылочные номера ошибок.

4) Хранимые процедуры не могут передавать объекты. Итак, если вы не будете осторожны, вы можете получить миллион параметров. Если вам нужно заполнить строку таблицы 20+ полями с помощью процедуры, поздоровайтесь с 20+ параметрами. Хуже всего, если я передаю неверный параметр - слишком много, недостаточно или неверные типы данных - я получаю общую ошибку «плохой вызов».Oracle не может сказать мне, какие параметры ошибочны! Поэтому мне нужно вручную изучить более 20 параметров, чтобы выяснить, какой из них является виновником.

Ответ : SQL основан на SET, что полностью отличается от процедурного / объектно-ориентированного программирования. Типы близки к объектам, но в какой-то момент должно быть соответствие между процедурными / объектно-ориентированными объектами и сущностями базы данных.

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

Ответ : Это хорошая вещь (tm) - вот как вы получаете Model-View-Controller (MVC), поэтому вы можете иметь интерфейс на любом множестве языков без необходимости каждый раз дублировать логику имея дело с причудами каждого языка, чтобы воспроизвести эту логику. Или хорошо, что база данных позволяет добавлять плохие данные, если кто-то подключается напрямую к базе данных? Путешествие туда и обратно между приложением и базой данных - пустая трата времени и ресурсов, которые ваше приложение никогда не окупит.

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

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

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

// add a new user
$user = new User("john", "doe");
$user->save();
// The id is computed by the database see MYPROC_ID_COMPUTATION
print $user->getId();

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

// Computes an ID for the given user
DB->execute("SELECT COMPUTE_ID(" . $user->getLogin() . ") FROM DUAL");

Конечно, это все псевдокод, но я надеюсь, что вы понимаете мою непонятную идею.

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

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

Код контролируется версиями. Базы данных нет. Поэтому, если у вас есть более одного экземпляра вашего кода, вам понадобится какой-то способ автоматического выполнения миграции при обновлении, иначе вы рискуете что-то сломать. И даже при этом вы по-прежнему сталкиваетесь с проблемой «забывания» добавить обновленный SP в сценарий миграции, а затем ломать сборку (возможно, даже не осознавая этого, если вы ДЕЙСТВИТЕЛЬНО не тестируете idepth).

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

Другой аргумент (по линии контроля версий) - нет команды svn st для SP. Так что, если у вас есть разработчик, который вручную изменяет SP, у вас будет уйма времени, чтобы понять это (при условии, что не все они управляются одним администратором баз данных).

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

Вкратце, мое мнение таково:

Используйте хранимые процедуры:

  1. Когда у вас есть несколько приложений, работающих с одним и тем же набором данных
  2. Когда вам нужно перебирать запросы и выполнять другие запросы (предотвращение потерь на уровне TCP может ОЧЕНЬ повысить эффективность)
  3. Когда у вас есть действительно хороший администратор баз данных, так как он будет обеспечивать выполнение всего SQL, обрабатываемого им / ею.

Используйте необработанный SQL / ORM / Сгенерированный SQL примерно в любом другом случае (примерно, поскольку обязательно будут крайние случаи, о которых я не думаю) ...

Опять же, это всего лишь мои 0,02 доллара ...

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

Я слышал, как люди говорят: «Позвольте базе данных делать столько, сколько она может», а другие кричали: «Блин, что вы делаете с производительностью моей базы данных?».

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

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

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

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

Еще одна причина - безопасность. При использовании proc мы передаем идентификатор пользователя (не последовательный, не угадываемый) в каждом вызове proc. Мы проверяем, что пользователь имеет доступ к выполнению этой функции в веб-приложении и еще раз в самой базе данных. Это радикально повышает барьер для хакеров, если наше веб-приложение будет взломано. Они не только не смогут выполнить любой sql, который захотят, но даже для запуска proc им потребуется определенный ключ авторизации. Который было бы трудно получить. (и это не единственная наша защита)

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

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

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