it-swarm.com.ru

Хранимые процедуры MySQL используют их или не используют их

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

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

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

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

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

56
Emilio Nicolás

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

  • не переносимый (у каждой базы данных есть своя собственная версия PL/SQL. Иногда разные версии базы данных same несовместимы - я видел это!)
  • не легко тестируемый - вам нужен реальный (dev) экземпляр базы данных, чтобы протестировать их, и, таким образом, модульное тестирование их кода как части сборки практически невозможно
  • не легко обновляется/выпускается - вы должны удалить/создать их, т.е. изменить производственную базу данных, чтобы освободить их
  • нет поддержки библиотеки (зачем писать код, когда кто-то другой)
  • не легко интегрируются с другими технологиями (попробуйте вызвать у них веб-сервис)
  • они используют такой же примитивный язык, как и Фортран, и, следовательно, неэлегатичны и трудоемки, чтобы выполнить полезное кодирование, поэтому трудно выразить бизнес-логику, хотя, как правило, это их основная цель
  • не предлагать отладку/трассировку/регистрацию сообщений и т. д. (некоторые базы данных могут это поддерживать - хотя я этого не видел)
  • не хватает приличного IDE для помощи с синтаксисом и связыванием с другими существующими процедурами (например, как это делает Eclipse для Java)
  • люди, умеющие их кодировать, встречаются реже и дороже, чем программисты приложений
  • их «высокая производительность» является мифом, потому что они выполняются на сервере базы данных, который они обычно увеличивают нагрузка на сервер базы данных, поэтому их использование обычно уменьшает максимальную пропускную способность транзакции
  • неспособность эффективно обмениваться константами (обычно решается путем создания таблицы и выполнения квестов из вашей процедуры - очень неэффективно)
  • и т.п.

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

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

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

58
Bohemian

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

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

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

24
davek

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

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

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

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

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

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

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

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

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

13
Sebas

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

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

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

7
Abhay

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

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

  • Что ты хочешь получить. 

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

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

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

  • Время получить это.

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

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

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

  • 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. Надеюсь, что это может помочь любому, кто спрашивает себя, что лучше использовать.

Hope this may help to anyone asking himself/herself what is better to use.

5
Enyix Mexico

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

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

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

Вы можете

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

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

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

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

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

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

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

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

2
R. van Twisk

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

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

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

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

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

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

2
Charles Bryant

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

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

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

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

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

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

1
Richard

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

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

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

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

  • Сайт называет бизнес-уровень (BL)
  • BL вызывает уровень данных (DL)
  • DL вызывает любое хранилище (SQL, XML, веб-сервис, сокеты, текстовые файлы и т.д.)

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

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

1
BerggreenDK

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

Я бы порекомендовал использовать хранимые процедуры MySQL, если вы выполняете много статических запросов для манипулирования данными. Особенно, если вы перемещаете вещи из одной таблицы в другую (т.е. по какой-либо причине переходите от реальной таблицы к исторической таблице). Конечно, существуют недостатки, заключающиеся в том, что вам придется вести отдельный журнал изменений к ним (теоретически вы можете создать таблицу, в которой будут храниться только изменения хранимых процедур, которые обновляет администратор БД). Если у вас есть много разных приложений, взаимодействующих с базой данных, особенно если, скажем, у вас есть настольная программа, написанная на C #, и веб-программа на PHP, может быть более выгодно хранить некоторые из ваших процедур в базе данных, поскольку они не зависят от платформы. 

На этом сайте есть интересная информация, которую вы можете найти полезной.

https://www.sitepoint.com/stored-procedures-mysql-php/

Как всегда, сначала создайте песочницу и протестируйте. 

0
Dave Babler