Enregistrer des instructions SQL dans une table pour les exécuter ultérieurement est-il une mauvaise idée?

21

Enregistrer des instructions SQL dans une table MySQL pour les exécuter ultérieurement est-il une mauvaise idée? Les instructions SQL seront prêtes à être exécutées, c'est-à-dire qu'il n'y aura pas de paramètres à échanger ou quoi que ce soit, par exemple DELETE FROM users WHERE id=1.

Je suppose que je suis paresseux, mais j'ai pensé à cette idée parce que je travaille sur un projet qui nécessitera pas mal de tâches cron qui exécuteront périodiquement des instructions SQL.

Amged Rustom
la source
Vous devez préciser si vous avez l'intention d'exécuter ces instructions SQL une fois ou si vous souhaitez exécuter le même ensemble d'instructions à plusieurs reprises.
GrandmasterB
10
Toute cette question semble être l'une de ces situations où l'approche fondamentale est erronée. Mais il est difficile de dire exactement quoi, car nous en savons si peu sur l'espace problématique.
Erick Robertson

Réponses:

46

C'est sûr, si c'est ce que vous demandez. Tant que vous êtes aussi attentif à votre sécurité qu'à la sécurité de vos données.

Mais ne réinventez pas la roue, les procédures stockées SONT des bits de SQL stockés dans une table. Et ils soutiennent, voire encouragent, le paramétrage.

Notez également que vous pouvez simplifier votre sécurité ET réduire le nombre de points de défaillance ET réduire les communications réseau en utilisant le MySql Event Scheduler au lieu de cron.

D'autres bases de données ont des équivalents à celles-ci, pour une bonne raison. Vous n'êtes pas le premier à avoir besoin de cette fonctionnalité.

pdr
la source
1
+1 sur l'utilisation du planificateur. Limiter l'accès du planificateur aux seuls procs est meilleur que l'accès à la table.
JeffO
Mais que se passe-t-il si vous devez créer dynamiquement ces requêtes, par exemple à partir d'une interface utilisateur? Par exemple, si vous autorisez les utilisateurs administrateurs à définir dynamiquement des règles d'accès au contenu Web en fonction de requêtes complexes. Vous ne voudriez pas que l'interface utilisateur crée un nouveau proc dans la base de données. Je pense que dans certaines circonstances, les requêtes stockées sont meilleures que les procs.
DiscipleMichael
32

Si vous souhaitez enregistrer des instructions SQL dans une base de données pour une exécution ultérieure, il existe une meilleure option que de les placer dans une table: utilisez la fonctionnalité intégrée fournie à cet effet spécifique. Mettez-les dans des procédures stockées.

Mason Wheeler
la source
2
Alors, où le travail cron stocke-t-il la liste des procédures stockées à exécuter?
JeffO
1
cela peut être utile stackoverflow.com/questions/6560639/… bien qu'il n'utilise pas cron
MetaFight
Je ne sais pas à quoi je pensais. Une liste de procs pourrait tous être exécutée à partir d'un seul proc, donc le travail cron n'a besoin que d'en exécuter un.
JeffO
11

Non, je dirais que ce n'est pas une bonne idée.

Cela signifie que chaque "vraie" requête / mise à jour aura besoin de 2 hits sur la base de données - un pour obtenir la "vraie" requête / mise à jour, et un pour l'exécuter.

Ce n'est peut-être pas un problème énorme dans un petit système, mais plus il y a d'utilisateurs / de transactions, moins il évoluera.

Je suppose que cela vient de la recherche d'une alternative à l'intégration de SQL dans votre code?

Encapsuler le SQL dans une procédure stockée, comme l'a suggéré Mason Wheeler, serait une façon bien meilleure que cette idée.

ozz
la source
+1, c'est la principale raison pour laquelle la solution de @Mason Wheeler est la bonne - il a juste manqué de le souligner. Bien que IMHO ce ne soit pas le problème de performance que je vois ici le plus important - il n'y a tout simplement pas besoin de compliquer les choses en extrayant une instruction SQL de la base de données et en la renvoyant ensuite pour exécution.
Doc Brown
Pourquoi la liste des instructions SQL doit-elle être stockée dans la même base de données / serveur, etc.?
JeffO
1
l'OP est celui qui propose 2 hits sur la base de données. Je dis qu'il ne devrait pas le faire. Vous demandez ensuite pourquoi il doit s'agir du même serveur / base de données. Je demande qui a dit ça? vous demandez alors comment obtenir autrement 2 hits sur la DB. Pourquoi ne dites-vous pas votre véritable question au lieu de ce que vous faites?
ozz
1
@JeffO Même s'il s'agit d'une base de données différente, il reste 2 requêtes de base de données pour ce qui devrait être 1 requête, ce qui est un ralentissement inutile
Izkata
1
@Ozz: vous donnez trop de poids à l'aspect performance de votre réponse - la performance est très probablement négligeable dans la plupart des scénarios du monde réel. Mais la nécessité de deux actions (la première pour obtenir la "vraie" requête / mise à jour, la seconde pour l'exécuter) rend les choses plus compliquées que nécessaire.
Doc Brown
4

Désolé, je ne pense pas que ce soit une bonne idée.

Considérez le cas où le tableau en question change. Supposons que votre colonne d' identification soit renommée en new_id .

En plus du changement lui-même, il existe une version de votre code écrite pour un ancien millésime de la base de données qui peut ne plus fonctionner. Bien sûr, vous devriez peut-être vérifier la table de code, mais ce n'est pas immédiatement évident pour quelqu'un d'autre.

Pour un changement tel que je l'ai décrit, je regarde généralement les fichiers SQL autonomes, les procédures stockées, les déclencheurs, le SQL en ligne dans le code client (VB, C #, C ++, etc.), mais le dernier endroit où je penserais à regarder est dans les tables de base de données. Mais peut-être que je le ferai maintenant! :)

Robbie Dee
la source
2

Il existe des raisons valables de stocker SQL dans une table. Le logiciel avec lequel je travaille au travail comprend maintenant un système de génération de documents et les documents doivent inclure des calculs assez complexes utilisant des données dans une base de données. Les documents sont mis à jour fréquemment, sont souvent très différents en termes de données nécessaires et de calculs à effectuer. SQL est utilisé, fondamentalement, comme langage de script pour effectuer ces calculs et que SQL est stocké dans des tables qui stockent également d'autres informations pour ces documents. Les personnes qui gèrent ces documents ne sont pas des programmeurs ou des administrateurs de base de données, mais ils connaissent le schéma de base de données et maîtrisent SQL. Ce serait une surcharge importante pour eux de maintenir ce code SQL sous la forme de procédures stockées.

Pour ce que vous avez décrit - "... un projet qui nécessitera pas mal de tâches cron qui exécuteront périodiquement des instructions SQL" - les autres réponses sont probablement correctes en suggérant que vous avez utilisé des procédures de stockage, ou l'équivalent, pour le SGBD que vous ' réutiliser.

Un bon critère pour décider s'il est judicieux de stocker du SQL dans une table par rapport à une procédure stockée est de déterminer qui maintiendra ce SQL. Si les utilisateurs maintiennent ce SQL, c'est-à-dire qu'ils l'écrivent et le modifient quand ils le souhaitent, alors il peut être parfaitement correct, et même préférable, de stocker ce SQL dans une table. Si les développeurs maintiennent ce SQL, il doit être stocké sous une forme qui peut être mise à jour par vos procédures de construction et de déploiement (espérons-le automatisées), par exemple stockées en tant qu'objet comme une procédure stockée dans la base de données elle-même.

Kenny Evitt
la source
1
Merci pour la réponse. J'ai fini par utiliser des événements MySQL pour planifier l'exécution des requêtes. Beaucoup de gens pensaient que "l'approche fondamentale est fausse" :) alors que tout ce dont j'avais besoin était d'exécuter quelques instructions SQL après 15 minutes à partir d'une action utilisateur spécifique.
Amged Rustom
2
@AmgadSuliman - il est important d'être charitable envers tout le monde, en particulier sur les sites SE. Il est bon d'avoir des opinions bien arrêtées, mais il est trop facile de sur-assortir les modèles par rapport auxquels nous aimons l'inveigh. Mais une partie de la charité envers les autres sur ces sites fournit suffisamment de contexte; trop peut obscurcir la vraie question, mais en général, c'est assez facile à résoudre par une édition ultérieure.
Kenny Evitt
1

Le moyen le plus simple serait d'avoir un fichier .ini ou un autre fichier de configuration pour conserver les requêtes. De cette façon, vous pouvez les avoir au même endroit, changer quoi que ce soit sans avoir à accéder à la base de données pour le faire, ne pas frapper la base de données plusieurs fois et vous pouvez également vouloir / besoin à un moment donné d'utiliser des paramètres ou d'ajouter des conditions à vos requêtes (augmentez-les avec des choses plus complexes pour un cas particulier dans votre code).

Bien sûr, vous pouvez les garder au niveau de la base de données (soit dans une table ou, mieux encore, en tant que procédures stockées), mais si vous êtes aussi paresseux que moi ;-) mais vous êtes également préoccupé par les performances, un fichier .ini et PHP la méthode bien-aimée parse_ini pour le lire, est la voie à suivre (si vous optez pour un autre langage de programmation, vous êtes seul à trouver des approches similaires)! Habituellement, je lis ce fichier dans le chargeur de démarrage de l'application et le conserve dans un objet statique (peut-être avec une couche de cache en haut) pour vraiment accélérer les choses si nous parlons d'un très grand nombre de requêtes distinctes.

Thyamarkos
la source
1

Si vous n'avez besoin de l'instruction SQL qu'une seule fois, par exemple, si vous mettez en file d'attente un tas d'opérations à effectuer pendant les heures creuses, alors oui, les mettre dans une table fonctionnera très bien.

Si vous devez exécuter la même instruction SQL à des intervalles spécifiés, la route de procédure stockée mentionnée par d'autres est probablement un meilleur choix pour vous.

Cela dit, ce que vous demandez est assez inhabituel et peut être le signe d'un autre problème. Par exemple, si vous attendez de supprimer un utilisateur d'une base de données, il peut être préférable d'appeler un script planifié qui effectue l'opération via votre code d'application, plutôt que d'enregistrer les instructions SQL réelles. De cette façon, le SQL et le code ne sont jamais désynchronisés.

GrandmasterB
la source