Подтвердить что ты не робот

Просмотр или хранимая процедура для сложных запросов?

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

Я вижу три способа реализовать это:

  • Пусть разработчики внедряют запрос в каждое приложение и при необходимости добавляют свои собственные предложения WHERE.
  • Создайте хранимую процедуру, которая принимает в качестве параметров все условия, которые, как мне кажется, нужны разработчикам (ради аргумента можно сказать, что я могу предсказать, что будет необходимо в обозримом будущем), и процедура будет запускать сложный запрос и фильтровать его в соответствии с переданными параметрами.
  • Реализовать запрос как представление с несколькими подзонами (поскольку MySQL не разрешает подзапросы в представлениях), и разработчики используют это как таблицу и используют WHERE, чтобы каждое приложение применяло нужные им фильтры. В настоящее время я рассматриваю 3 дополнительных подзадача, главным образом потому, что некоторые подзапросы используются несколько раз и делают их в качестве подзадач, что предотвращает дублирование - в противном случае это могло бы быть хуже: -).

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

что будет лучше в условиях обслуживания кода, как вы думаете?

4b9b3361

Ответ 1

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

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

Лучший способ ответить на этот вопрос - проверить его - есть, конечно, множество конкретных деталей, которые могут привести к аннулированию общих ответов "Я бы ожидал x, y или z", которые мы можем передать переполнениям. Если производительность очень важна, используйте инструмент заполнения базы данных (Redgate make on, я использовал DBMonster в прошлом) и попробуйте все 3 варианта.

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

Вариант 4: постройте библиотеку доступа к данным, которая инкапсулирует доступ к вашим данным. Попросите библиотеку выставить методы и параметры, чтобы уточнить выбор записей. Рассмотрите возможность использования шаблона спецификации (http://en.wikipedia.org/wiki/Specification_pattern). Используйте любые запросы лучше всего в библиотеке, и не мешайте разработчикам детали реализации.

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

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

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

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

Ответ 2

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

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

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

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

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

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

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