Легче ли поддерживать хранимые процедуры?

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

При прочих равных, что делает хранимую процедуру лучше / хуже с точки зрения обслуживания?

Ответов (19)

Решение

Хранимые процедуры - плохая практика по ряду причин.

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

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

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

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

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

Если ваше базовое программное обеспечение развернуто на нескольких сайтах клиентов, большая часть настроек, необходимых для каждого отдельного клиента, может быть выполнена через базу данных (представления и хранимые процедуры). Вы можете думать о SP как о ИНТЕРФЕЙСЕ, передавать стандартные данные туда и обратно, не беспокоясь о том, что происходит внутри.

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

Однако в некоторых случаях настройка в SP вместо .dll позволяет ускорить настройку и позволяет администратору баз данных или эксперту по данным взять на себя ответственность, оставляя программисту работать над кодированием.

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

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

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

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

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

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

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

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

Я занимаюсь программированием CRUD в качестве консультанта более 10 лет в деловом мире. Я могу сказать вам, что я вложил в sprocs и views столько бизнес-логики, сколько смог (и это имеет смысл). Требования, как правило, меняются каждый раз, когда дует ветер, и наличие логики в базе данных позволяет легко изменять и (с приличными комментариями) самодокументируется. Плюс sprocs обеспечивают хорошую безопасность и упрощают повторное использование кода.

FWIW Я использую контроль версий и строгое тестирование на всех своих спроках. Поступать иначе - просто лень.

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

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

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

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

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

два преимущества хранимых процедур

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

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

один недостаток хранимых процедур

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

По моему опыту, я считаю, что основным недостатком является то, что немногие разработчики, с которыми я работал, действительно чувствовали себя комфортно с SQL (в первую очередь, написание его, его отладка). команда, чтобы иметь возможность поддерживать много SQL.

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

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

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

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

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

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

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

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

Это действительно зависит от того, насколько хорошо написаны хранимые процедуры, не так ли? T-SQL и PL-SQL могут стать такими же сложными и сложными в обслуживании, как C# или COBOL, если практикующий код не продумывает и не заботится.

Одно из недавних улучшений, над которыми я работал, я намеренно поместил функциональность в хранимую процедуру, в основном потому, что я хотел, чтобы на эту функциональность было проще ссылаться, а тем более поддерживать (хранимую процедуру можно вызывать на уровне БД, а также на уровне клиента ; если бы я поместил логику на другой уровень, это было бы неверно). Я думал, что хорошо поработал над тем, чтобы сделать PL-SQL достаточно модульным, но когда TOAD проанализировал его, 3 из 4 разделов получили хорошие оценки, а последний - из-за высокой цикломатической сложности. Хех, кажется, я только что доказал свою точку зрения!

Сохраненные процедуры - хорошая идея по ряду причин:

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

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

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

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

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

Внешний код должен передавать данные по сети, а затем работать с ними.

Наконец, не все процедурные языки созданы одинаково. MySQL только что выпустил возможность использовать хранимые процедуры, и они предоставляют вам несколько языков, включая их собственный. Я сомневаюсь, что их серверы могут сравниться с Oracle или SQl Server. Я не буду вдаваться в подробности, потому что я не эксперт ни в чем, кроме Oracle. PL / SQL Oracle имеет множество функций, которые оптимизированы в ядре БД. Я уверен, что MS SQL делает то же самое, а также другие.

Надеюсь, это будет полезно (и имеет смысл - долгий день).

Мы перешли с использования sprocs на сгенерированный DAL для бизнес-логики на основе кода по ряду причин:

  1. Независимость от базы данных - с помощью встроенного SQL или генерации DAL (оба совместимы с ANSI) легче переключиться с Oracle на Postgres, на SQL Server и т. Д.
  2. Принудительный контроль исходного кода (я допускаю, что это могло быть доступно в любом случае, но для нас это очень помогло)
  3. В любом случае мы обновляем графический интерфейс гораздо чаще, чем базу данных, поэтому это упростило обновление.
  4. Разработчику проще устранять проблемы с клиентом

Подумайте об альтернативах ...

  • Для жесткого кодирования запросов в вашу систему
  • Для создания строк запроса на основе пользовательского ввода
  • Чтобы ваш код динамически генерировал запросы на основе ваших бизнес-сущностей и соглашений об именах баз данных (через ORM, LINQ, CodeDom и т. Д.)
  • так далее...

Затем рассмотрите свои требования и среду ...

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

  • Вам нужно часто вносить изменения в схему БД?

  • Как насчет безопасности? Требуется ли вам безопасность вплоть до уровня пользователя базы данных? Было бы проще управлять безопасностью в коде или в БД?

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

  • так далее...

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

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

Между прочим, мир Oracle считает своей лучшей практикой иметь всю бизнес-логику в коде PL / SQL в базе данных, и они кое-что знают о реляционных базах данных!

Рассмотрим следующие варианты использования SP:

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

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

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

Слой абстракции. SP могут абстрагироваться от деталей схемы БД от приложения, при условии, что все взаимодействия приложения / БД осуществляются через SP. Это может быть очень мощная концепция. Учтите, что срок службы БД часто превышает срок службы приложения - приложения приходят и уходят и время от времени переписываются с использованием новейших технологий и архитектурных шаблонов, но ценные данные остаются в той же старой реляционной БД в течение многих лет. Часто несколько приложений разрабатываются в одной и той же БД, даже если это никогда не было изначальной целью. SP в этих сценариях используются для обеспечения тесного, четко определенного API между приложением и БД, который можно тщательно контролировать, чтобы гарантировать согласованное взаимодействие с несколькими приложениями и даже несколькими версиями одного и того же приложения.

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

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