Хранимые процедуры MySQL используют их или не используют их - PullRequest
59 голосов
/ 16 июня 2011

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

Мы будем использовать хранимые процедуры только для вставки и обновления сущностей бизнес-модели.Существует несколько таблиц, представляющих сущность модели, и мы бы абстрагировали ее в этих хранимых процедурах insert / update.

С другой стороны, мы можем вызывать insert и update со слоя Model, но не в MySQL, аPHP.

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

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

Ответы [ 12 ]

63 голосов
/ 16 июня 2011

В отличие от реального кода языка программирования, они:

  • не переносимы (у каждой базы данных есть собственная версия PL / SQL. Иногда разные версии базы данных одной и той же несовместимы -Я видел это!)
  • непросто проверить - вам нужен реальный (dev) экземпляр базы данных, чтобы проверить их, и, таким образом, модульное тестирование их кода как части сборки практически невозможно
  • нелегко обновить / освободить - вы должны удалить / создать их, т. Е. изменить производственную базу данных, чтобы освободить их
  • не поддерживают библиотеку (зачем писать код, когда кто-то другойhas)
  • не так просто интегрировать с другими технологиями (попробуйте вызвать у них веб-сервис)
  • они используют такой же примитивный язык, как и Fortran, и, следовательно, не изящны и трудоемки для выполнения полезного кодированияпоэтому трудно выразить бизнес-логику, хотя обычно именно это является их основным назначением
  • , не предлагая отладку / трассировку / ведение сообщений и т. д.c (некоторые базы данных могут поддерживать это - хотя я этого не видел)
  • не хватает достойной IDE для помощи с синтаксисом и связыванием с другими существующими процедурами (например, как Eclipse для java)
  • люди, умеющие их кодировать, встречаются реже и дороже, чем кодировщики приложений
  • их "высокая производительность" - миф, потому что при выполнении на сервере базы данных они обычно увеличивают нагрузку на сервер базы данных, поэтомуих использование обычно уменьшает вашу максимальную пропускную способность транзакции
  • неспособность эффективно обмениваться константами (обычно это решается путем создания таблицы и выполнения квестов из вашей процедуры - очень неэффективно)
  • и т. д.

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

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

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

27 голосов
/ 16 июня 2011

В отличие от программного кода, они:

  • делают атаки внедрения SQL практически невозможными (если вы не
    создаете и выполняете динамический
    SQL из ваших процедур)
  • требуется намного меньше данных для отправки через IPC как часть выноски
  • позволяет базе данных гораздо лучше кешировать планы и наборы результатов (по общему признанию, это не так эффективно с MySQL из-завнутренние структуры кеширования
  • легко тестируются изолированно (т.е. не являются частью тестов JUnit)
  • являются переносимыми в том смысле, что они позволяют вам использовать специфичные для БД функции, абстрагированные позадиимя процедуры (в коде вы застряли с общими вещами типа SQL)
  • почти никогда не медленнее, чем SQL, вызываемый из кода

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

13 голосов
/ 08 ноября 2013

Что касается производительности, у них есть потенциал , чтобы быть действительно производительным в будущей версии MySQL (под SQL Server или Oracle они являются настоящим удовольствием!).Тем не менее, для всех остальных ... Они полностью взорвать конкуренцию.Подведу итог:

  • Безопасность: вы можете дать своему приложению только EXECUTE, все в порядке.Ваш SP вставит обновление select ... без какой-либо возможной утечки.Это означает глобальный контроль над вашей моделью и принудительную защиту данных.

  • Безопасность 2: я знаю, что это редко, но иногда php-код просачивается с сервера (то есть становится видимым для общественности),Если он включает ваши запросы, возможные злоумышленники знают вашу модель.Это довольно странно, но я все равно хотел сигнализировать об этом

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

  • Инкапсуляция бизнес-уровня: использование хранимых процедур полностью изолирует бизнес, к которому он относится: чертова база данных.

  • Быстрая проверка: одна командная строка под вашей оболочкой и ваш код проверяются.

  • Независимость от клиентской технологии: если завтра вы захотите перейти с php на что-то другое, нет проблем.Хорошо, просто хранение SQL в отдельном файле тоже поможет.Также, хороший комментарий в комментариях о том, что если вы решите переключить движки SQL, у вас будет много работы.В любом случае, у вас должна быть веская причина для этого, потому что для больших проектов и крупных компаний такое случается редко (в основном из-за затрат и управления персоналом)

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

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

7 голосов
/ 16 июня 2011

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

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

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

5 голосов
/ 19 февраля 2012

Я сообщу свое мнение, несмотря на то, что мои проблемы, возможно, не имеют прямого отношения к вопросу.:

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

  • То, что вы хотите получить.

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

  • Что у вас есть для того, чтобы его получить.

Какие у вас технологии баз данных?Что за инфраструктура?Ваша команда полностью обучена технологии баз данных?Ваша команда лучше способна создать решение, основанное на базе данных?

  • Время для его получения.

Никаких секретов об этом.

  • Архитектура.

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

  • Mainteinance.

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

  • Управление изменениями.

Видите ли вы, что ваша технология баз данных изменится в короткие, средние и длительные сроки?Как вы считаете, потребуется ли часто мигрировать решение?

  • Стоимость

Сколько будет стоить внедрение этого решения с использованием той или иной стратегии?

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

Использование хранимых процедур более целесообразно, когда:

  1. Технология вашей базы данных не может быть изменена в течение короткого времени.
  2. Ваша технология базы данных можетобрабатывать параллельные операции, разбиения таблиц или любую другую стратегию для разделения рабочей нагрузки на несколько процессоров, памяти и ресурсов (кластеризация, сетка).
  3. Технология вашей базы данных полностью интегрирована с языком определения хранимых процедур, то есть поддержкойнаходится внутри механизма базы данных.
  4. У вас есть команда разработчиков, которая не боится использовать процедурный язык (язык 3-го поколения) для получения результата.
  5. Операции, которые вы хотите выполнить, созданы-внутри или поддерживаются внутри базы данных (экспорт в данные XML, управление целостностью и согласованностью данных с помощью триггеров, запланированных операций и т. д.).
  6. Переносимость не является важной проблемой, и вы не вносите никаких изменений в технологиюкороткое время в вашей организации, даже,это не желательно.Обычно переносимость рассматривается разработчиками, ориентированными на приложения, и ориентированными на многие уровни.С моей точки зрения, переносимость не является проблемой, когда ваше приложение не требуется для развертывания на нескольких платформах, меньше, когда нет причин для изменения технологии или если усилия по переносу всех организационных данных выше, чемвыгода для внесения изменений.То, что вы можете выиграть, используя подход, основанный на уровне приложений (переносимость), вы можете потерять в производительности и стоимости, полученной из вашей базы данных (зачем тратить тысячи долларов, чтобы получить Ferrari, который вы будете ездить со скоростью не более 60 миль / час?).
  7. Производительность - это проблема. Во-первых: в нескольких случаях вы можете достичь лучших результатов, используя один вызов хранимой процедуры, чем несколько запросов данных из другого приложения. Более того, некоторые характеристики, которые вам необходимо выполнить, могут быть встроены в вашу базу данных, и ее использование обходится дешевле с точки зрения рабочей нагрузки. Когда вы используете решение на уровне приложений, вы должны учитывать затраты, связанные с установлением соединений с базой данных, вызовами к базе данных, сетевым трафиком, переносом данных (т. Е. При использовании Java или .NET неявные затраты возникают, когда использование вызовов JDBC / ADO.NET, поскольку вы должны обернуть свои данные в объекты, представляющие данные базы данных, поэтому создание экземпляров сопряжено с затратами в плане обработки, памяти и сети, когда данные поступают и выходят наружу).

Использование решений на уровне приложений обычно более целесообразно, когда:

  1. Переносимость является важной проблемой.
  2. Приложение будет развернуто в нескольких местах только с одним или несколькими хранилищами базы данных.
  3. Ваше приложение будет использовать строгие бизнес-ориентированные правила, которые должны быть независимы от базовой технологии баз данных.
  4. Вы хотите сменить поставщиков технологий в зависимости от тенденций рынка и бюджета.
  5. Ваша база данных не полностью интегрирована с языком хранимых процедур, который обращается к базе данных.
  6. Возможности вашей базы данных ограничены, и ваши требования выходят за рамки того, что вы можете достичь с помощью технологии базы данных.
  7. Ваше приложение может поддерживать наказание, присущее внешним вызовам, оно в большей степени основано на транзакциях с правилами, специфичными для бизнеса, и должно абстрагировать модель базы данных от бизнес-модели для пользователей.
  8. Распараллеливание операций с базой данных не важно, более того, ваша база данных не имеет возможностей распараллеливания.
  9. У вас есть команда разработчиков, которая недостаточно хорошо знакома с технологией баз данных и более продуктивна благодаря использованию технологии, основанной на приложениях.

Надеюсь, это может помочь любому, кто спрашивает себя, что лучше использовать.

3 голосов
/ 16 июня 2011

Я бы порекомендовал вам не использовать хранимые процедуры:

  • Их язык в MySQL очень дерьмовый
  • Невозможно отправить массивы, списки или другие типы структуры данных в хранимую процедуру
  • Хранимая процедура не может когда-либо изменять свой интерфейс; MySQL не разрешает ни именованные, ни дополнительные параметры
  • Это усложняет развертывание новых версий вашего приложения - скажем, у вас есть 10x серверов приложений и 2 базы данных, которые вы сначала обновляете?
  • Все ваши разработчики должны выучить и понять язык хранимых процедур - что очень дерьмо (как я уже говорил)

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

Вы можете

  • Обновите эту библиотеку и отправьте ее на серверы приложений вместе с приложением
  • Имеют расширенные типы данных, такие как массивы, структуры и т. Д.
  • Модульное тестирование этой библиотеки вместо хранимых процедур.

По производительности:

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

Раньше я использовал MySql, и мое понимание sql в лучшем случае было плохим, я провел немало времени, используя Sql Server, у меня есть четкое разделение уровня данных и прикладного уровня, в настоящее время я присматриваю за сервером с0,5 терабайта.

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

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

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

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

Мой совет - выучить и понять достаточно sql, и ваши приложения действительно выиграют.

2 голосов
/ 17 июня 2011

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

Разработчики также не имеют доступа к БД, отлично!Оставьте это на усмотрение разработчиков баз данных и сопровождающих.Если вы также решите, что структура таблицы будет изменена, вы можете скрыть это за своим интерфейсом.n-Tier, помните ??

Высокая производительность и реляционные БД - это не то, что сочетается, даже с MySQL InnoDB работает медленно, MyISAM уже должен быть выброшен из окна.Если вам нужна производительность с веб-приложением, вам нужен надлежащий кеш, memcache или др.

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

Совет: Поскольку вы упомянули Web-проект, вы когда-нибудь задумывались о nosql-подобном решении?Кроме того, вам нужна быстрая БД, почему бы не использовать PostgreSQL?(пытаясь защитить здесь ...)

1 голос
/ 07 октября 2017

Здесь много информации, чтобы сбить людей с толку, разработка программного обеспечения эволюционная. То, что мы делали 20 лет назад, сейчас не лучшая практика. Раньше с классическим клиентским сервером вы не мечтали ни о чем, кроме SP.

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

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

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

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

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

1 голос
/ 16 июня 2011

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

Я прошел через множество проектов, в которых они внезапно хотят переключить платформу БД, и код внутри SP обычно не очень переносим.= дополнительная работа и возможные ошибки.

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

Относительно вашей модели / уровня / уровня: да, придерживайтесь этого.

  • Веб-сайт вызывает Бизнес-уровень (BL)
  • BL вызывает Уровень данных (DL)
  • DL вызывает любое хранилище (SQL, XML, Webservice, Sockets, Textfiles и т. Д.)

Таким образом, вы можете поддерживать логический уровень между уровнями.ЕСЛИ И ТОЛЬКО ЕСЛИ вызовы DL кажутся очень медленными, вы можете начать возиться с хранимыми процедурами, но где-то сохранить исходный код без SP, если вам вдруг потребуется перенести БД на совершенно новую платформу.Обладая всем облачным хостингом в бизнесе, вы никогда не знаете, что будет следующей платформой БД ...

Я внимательно слежу за Amazon AWS по той же причине.

...