Работа без хранимых процедур или триггеров

Мы работали над сложной базой данных и клиентским интерфейсом в течение последних 18 месяцев. Мы регулярно добавляем новые функциональные возможности в это приложение, и теперь оно ежедневно используется десятками пользователей во всех наших офисах, включая сайты и за рубежом. Это просто чтобы сказать вам, что это РЕАЛЬНОЕ приложение с РЕАЛЬНОЙ базой данных.

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

Точно так же нам все еще не нужны были триггеры. Фактически, единственными SP и триггерами являются системные или добавленные для целей репликации.

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

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

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

РЕДАКТИРОВАТЬ:

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

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

Я должен признаться, что я пытаюсь найти некоторые отстаивающие аргументы, когда все эти фанаты SQL, работающие над другими нашими базами данных, смотрят на нас свысока, говоря своим друзьям: "Вы знаете, что? Они даже не используют SP и триггеры! Ха-ха!"

10 ответов

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

Нет, ты не можешь.

Нормализация и хранимые процедуры полностью отделены друг от друга.

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

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

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

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

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

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

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

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

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

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

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

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

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

"Сколько триггеров настроено для обновления некоторых полей таблицы или для пересчета итогов или других агрегированных данных?"

Использование триггера для выполнения сложных обновлений на основе бизнес-правил не является недостатком. Это предпочтительный метод. Все бизнес-правила должны применяться на уровне базы данных, если вы хотите сохранить целостность данных. Помимо пользовательского интерфейса, существуют другие способы воздействия на данные в базе данных, и бизнес-правила должны применяться независимо от используемого метода. Таким образом, импортированные данные должны будут следовать правилам, новые функциональные возможности должны будут следовать правилам (вместо того, чтобы помнить, что существуют правила и найти функциональность, созданную вами для обеспечения их соблюдения), люди массово обновляют данные из инструмента запросов (думаю поднять все цены на 10%) придется соблюдать правила и т.д.

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

Как вы получаете данные обратно из базы данных? вы строите строки SQL и выполняете их? Если да, то как вы проверяете записи, которые не собираются уничтожать базу данных? Хранимые процедуры помогают значительно снизить риск этого благодаря тому факту, что текст обрабатывается сервером как текст, а не как команда.

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

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

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

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

Вот один пример, когда SP абсолютно необходимы: пользовательский интерфейс - это только малая часть всего приложения. И когда весь процесс происходит независимо от пользователей. Например, я работаю над проектом, который включает в себя много обработки данных из разных источников. Таким образом, мы получаем эти файлы, а затем просто запускаем Script Shell, которая просто запускает SP, чтобы импортировать все данные из файлов, проверить их, манипулировать ими и т. Д. И знаете что? этот же SP может также использоваться пользователем из пользовательского интерфейса, без необходимости перезаписывать все запросы на обработку данных снова!

Конечно, если эти запросы обработки были просто SELECT, вы могли бы поспорить о необходимости SP, но когда вам нужно ОБНОВИТЬ десятки таблиц, вычислить поля, очистить данные, очистить данные, тогда SP будут благословлены. И это не означает, что в нашей базе данных отсутствует нормализация, но когда вы ежедневно обрабатываете миллиарды данных, не все может быть простым.

Если у вас есть семь разных приложений, обращающихся к базе данных пользователей, разве не имеет смысла иметь хранимый процесс под названием "createUser", а не семь разных приложений, создающих эту инструкцию INSERT самостоятельно?

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

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

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

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

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

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

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

Мои $.02

пс. Я не писал строки SQL в приложении в течение многих лет. Все идет в хранимых процедурах. Будь то простой выбор, вставка, обновление, сложный отчет или обновление, которое фактически является единым объектом в приложении, но хранится в 7 разных таблицах в базе данных.

Другие вопросы по тегам