Чи збереження операторів SQL у таблиці для виконання пізніше поганою ідеєю?


21

Чи збереження операторів SQL у таблиці MySQL для подальшого виконання пізньої помилки? Оператори SQL будуть готові до виконання, тобто не буде параметрів, які можна поміняти чи нічого, наприклад DELETE FROM users WHERE id=1.

Я думаю, що я лінуюся, але я подумав над цією ідеєю, тому що я працюю над проектом, який потребуватиме досить декількох завдань, що виконуватимуть SQL-оператори періодично.


Вам слід уточнити, якщо ви збираєтесь запускати ці оператори SQL один раз або якщо ви хочете повторно виконувати один і той же набір операторів.
ГрандмайстерB

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 у збереженій процедурі, як запропонував Мейсон Уілер, був би одним із способів, які будуть набагато кращими, ніж ця ідея.


+1, це головна причина, чому рішення @Mason Wheeler є правильним - він просто пропустив, щоб виділити це. Хоча IMHO не є проблемою з продуктивністю, я бачу тут найважливіше - просто немає необхідності ускладнювати речі, витягуючи SQL-заяву з БД і відправляючи його назад для виконання.
Док Браун

Чому список операторів sql повинен зберігатися в одній базі даних / сервері тощо?
JeffO

1
ОП пропонує 2 звернення до бази даних. Я кажу, що він не повинен цього робити. Потім ви запитуєте, чому це повинна бути однакова база даних / сервер. Я запитую, хто це сказав? Ви запитаєте, як ще ви отримуєте 2 звернення в БД. Чому ви не заявите власне питання замість того, що б ви робили?
ozz

1
@JeffO Навіть якщо мова йде про іншу базу даних, це все-таки 2 запити до бази даних про те, що має бути 1 запит, що є непотрібним уповільненням
Izkata

1
@Ozz: ви надаєте занадто велику вагу аспекту ефективності своєї відповіді - ефективність, швидше за все, нехтується в більшості реальних сценаріїв. Але потреба у двох діях (перша - для отримання "реального" запиту / оновлення, друга - для виконання) робить речі просто складнішими, ніж потрібно.
Док Браун

4

Вибачте, я не думаю, що це гарна ідея.

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

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

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


2

Є вагомі причини зберігання SQL у таблиці. Програмне забезпечення, з яким я працюю зараз, включає систему генерації документів, і документи повинні включати досить складні обчислення з використанням даних у базі даних. Документи оновлюються часто, часто суттєво відрізняються з точки зору необхідних даних та розрахунків, які необхідно виконати. SQL використовується, в основному, як мова скриптів для виконання цих обчислень, і SQL зберігається в таблицях, які також зберігають іншу інформацію для цих документів. Люди, які підтримують ці документи, не є програмістами або DBA, але вони знайомі зі схемою баз даних і знають SQL. Для них було б значним накладні витрати, щоб вони підтримували цей код SQL у вигляді збережених процедур.

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

Хорошим критерієм вирішення питання про те, чи розумно зберігати SQL у таблиці порівняно із збереженою процедурою, є визначення того, хто буде підтримувати цей SQL. Якщо користувачі підтримують цей SQL, тобто вони пишуть його та змінюють його коли завгодно, то, можливо, буде цілком добре, і справді найкраще зберігати цей SQL у таблиці. Якщо розробники підтримуватимуть цей SQL, він повинен зберігатися у формі, яка може бути оновлена ​​вашими (сподіваємось, автоматизованими) процедурами збирання та розгортання, наприклад, зберігається як об’єкт, як збережена процедура в самій базі даних.


1
Дякую за відповідь. Я в кінцевому підсумку використовував події MySQL для планування запуску запитів. Дуже небагато людей подумали, що "фундаментальний підхід невірний" :), коли мені потрібно було лише запустити кілька операторів SQL через 15 хвилин від конкретної дії користувача.
Amged Rustom

2
@AmgadSuliman - важливо бути добродійним для всіх, особливо на сайтах SE. Добре мати думки, але занадто легко їх можна збігати з моделями, проти яких ми любимо інвестувати. Але частина бути добродійною для інших на цих сайтах забезпечує достатній контекст; Занадто багато може затьмарити справжнє питання, але загалом це досить легко виправити шляхом подальшого редагування.
Кенні Евітт

1

Найпростішим виходом було б мати .ini або інший смаковий файл конфігурації для збереження запитів. Таким чином, ви можете мати їх в одному місці, змінити що-небудь, не маючи доступу до бази даних, щоб це зробити, не вдаряючи базу даних кілька разів а також вам може захотіти / потрібно в якийсь момент використовувати параметри або додати умови до ваших запитів (доповнити їх складнішими матеріалами для конкретного випадку у вашому коді).

Звичайно, ви можете тримати їх на рівні бази даних (або в таблиці або, ще краще, як збережені процедури), однак, якщо ви такі ліниві, як і я ;-), але також переймаєтесь продуктивністю, .ini файлом та PHP улюблений метод parse_ini, щоб прочитати його - це шлях (якщо ви збираєтесь використовувати іншу мову програмування, ви самостійно розбираєтесь у подібних підходах)! Зазвичай я читав би цей файл у завантажувачі програми та зберігав його у статичному об'єкті (можливо, із шаром кеша зверху), щоб дійсно прискорити роботу, якщо ми говоримо про дуже велику кількість різних запитів.


1

Якщо вам потрібен оператор SQL лише один раз, наприклад, якщо ви ставите в чергу купу операцій, які потрібно виконати в неробочий час, то так, помістити їх у таблицю буде добре.

Якщо вам потрібно виконати той самий оператор SQL через задані інтервали, то кращий вибір для вас, ймовірно, збережений маршрут процедури, який інші згадали.

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.