Является ли сохранение операторов SQL в таблице для выполнения позже плохой идеей?

21

Является ли сохранение операторов SQL в таблице MySQL для последующего выполнения плохой идеей? Операторы SQL будут готовы к выполнению, то есть не будет, например, параметров для обмена или чего-либо еще DELETE FROM users WHERE id=1.

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

Amged Rustom
источник
Вы должны уточнить, собираетесь ли вы запускать эти операторы SQL один раз или хотите, чтобы один и тот же набор операторов выполнялся повторно.
GrandmasterB
10
Весь этот вопрос кажется одной из тех ситуаций, где фундаментальный подход неверен. Но трудно сказать, что именно, потому что мы так мало знаем о проблемном пространстве.
Эрик Робертсон

Ответы:

46

Это безопасно, если ты об этом. Пока вы заботитесь о своей безопасности так же, как о безопасности своих данных.

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

Также обратите внимание, что вы можете упростить свою безопасность, уменьшить количество точек отказа и уменьшить сетевую связь, используя планировщик событий MySql вместо cron.

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

прецизионный самописец
источник
1
+1 при использовании планировщика. Ограничение доступа планировщика только к процессам лучше, чем доступ к таблице.
JeffO
Но что, если вам нужно динамически создавать эти запросы, скажем, из пользовательского интерфейса? Например, если вы разрешите администраторам динамически устанавливать правила доступа к веб-содержимому на основе сложных запросов. Вы бы не хотели, чтобы пользовательский интерфейс создавал новый процесс в базе данных. Я думаю, что в некоторых случаях хранимые запросы лучше, чем процедуры.
DiscipleMichael
32

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

Мейсон Уилер
источник
2
Так где же задание cron хранит список хранимых процедур для запуска?
JeffO
1
это может быть полезно stackoverflow.com/questions/6560639/… хотя он не использует cron
MetaFight
Не знаю, о чем я думал. Список процедур может быть выполнен из одного процесса, поэтому заданию cron нужно выполнить только один.
JeffO
11

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

Это означает, что для каждого «реального» запроса / обновления потребуется 2 обращения к базе данных - один для получения «реального» запроса / обновления и один для его выполнения.

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

Я предполагаю, что это происходит из-за поиска альтернативы встраиванию SQL в ваш код?

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

Ozz
источник
+1, это главная причина, по которой решение @Mason Wheeler является правильным - он просто не смог это подчеркнуть. Хотя ИМХО это не проблема производительности, я вижу здесь самое важное - просто нет необходимости усложнять ситуацию, извлекая оператор SQL из БД и отправляя его обратно для исключения.
Док Браун
Почему список операторов SQL должен храниться в той же базе данных / сервере и т. Д.?
JeffO
1
ОП - это тот, кто предлагает 2 попадания в базу данных. Я говорю, что он не должен этого делать. Затем вы спрашиваете, почему это должна быть та же база данных / сервер. Я спрашиваю, кто сказал, что сделал? Затем вы спрашиваете, как еще вы получаете 2 попадания в БД. Почему бы вам не сформулировать свой фактический вопрос вместо того, что вы делаете?
Оз
1
@JeffO Даже если это другая база данных, это все равно 2 запроса к базе данных для того, что должно быть 1 запросом, что является ненужным замедлением
Izkata
1
@Ozz: вы слишком придаете весу аспект производительности вашего ответа - производительность, скорее всего, пренебрежима в большинстве реальных сценариев. Но необходимость в двух действиях (первое, чтобы получить «реальный» запрос / обновление, второе, чтобы выполнить его) делает вещи просто более сложными, чем необходимо.
Док Браун
4

Извините, я не думаю, что это хорошая идея.

Рассмотрим случай, когда рассматриваемая таблица изменяется. Скажем, ваш столбец идентификаторов переименован в new_id .

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

Для такого изменения, как я описал, я обычно смотрю на автономные файлы SQL, хранимые процедуры, триггеры, встроенный SQL в клиентском коде (VB, C #, C ++ и т. Д.), Но последнее место, на которое я бы хотел посмотреть находится в таблицах базы данных. Хотя, может быть, я буду сейчас! :)

Робби Ди
источник
2

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

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

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

Кенни Эвитт
источник
1
Спасибо за ответ. Я закончил тем, что использовал события MySQL, чтобы запланировать выполнение запросов. Многие считали, что «фундаментальный подход неверен» :), когда все, что мне было нужно, это запустить несколько операторов SQL через 15 минут после определенного действия пользователя.
Amged Rustom
2
@AmgadSuliman - важно быть благотворительным для всех, особенно на сайтах SE. Хорошо иметь сильные мнения, но слишком легко переоценивать модели, с которыми мы получаем удовольствие. Но часть благотворительности по отношению к другим на этих сайтах обеспечивает достаточный контекст; слишком многое может скрыть реальный вопрос, но, как правило, это довольно легко исправить с помощью последующего редактирования.
Кенни Эвитт
1

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

Конечно, вы можете хранить их на уровне базы данных (либо в виде таблицы, либо, что еще лучше, в виде хранимых процедур), однако, если вы так же ленивы, как и я ;-), но также интересует производительность, файл .ini и PHP Любимый метод parse_ini, чтобы прочитать его, это путь (если вы выбираете другой язык программирования, вы сами выясняете аналогичные подходы)! Обычно я читал этот файл в загрузчике приложения и держал его в статическом объекте (возможно, с кеш-слоем сверху), чтобы действительно ускорить процесс, если мы говорим об очень большом количестве различных запросов.

Thyamarkos
источник
1

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

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

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

GrandmasterB
источник