Question

J'ai une requête assez complexe avec de multiples (imbriqués) sous-requêtes, que je veux mettre à la disposition pour les développeurs d'applications. La requête est générique et génère une vue avec les valeurs calculées sur une collection de jeux de données, et le développeur devrait avoir besoin que des enregistrements de ce que les déclarations de la requête (ils limiteront le résultat de l'ID une entité ou une plage de dates ou d'une telles).

Je peux voir 3 façons de mettre en œuvre ceci:

  1. Laissez les développeurs intégrer la requête dans chaque application et ajouter leurs propres clauses de WHERE au besoin.
  2. Créer une procédure stockée qui accepte comme paramètres toutes les conditions que je pense aux développeurs de besoin (pour le bien de l'argument permet de dire que je peux prédire ce qui sera nécessaire dans un avenir prévisible), et la procédure se déroulera la requête complexe et il filtre selon les paramètres transmis.
  3. Mettre en œuvre la requête en vue avec vue sur plusieurs sous (parce que MySQL ne permet pas de sous-requêtes dans les vues) et ont les développeurs utilisent cela comme un WHERE de table et l'utilisation d'avoir chaque application applique les filtres dont ils ont besoin. Actuellement, je suis à la recherche à 3 sous-vues supplémentaires, la plupart du temps parce que certaines sous-requêtes sont utilisées à plusieurs reprises et les faire en tant que sous-vues empêche la duplication - sinon il aurait pu être pire, -.)

Quelle sera meilleure performance sage? (En supposant que tout l'indexation est équivalente dans tous les cas) Optez pour le pire des scénarios, si vous pouvez.

ce sera mieux en termes de maintenance de code, pensez-vous?

Était-ce utile?

La solution

Je aime des questions qui définissent « bon » -. Vous ai posé des questions sur les performances spécifiquement et maintenabilité, ce qui permet des réponses à parler de ce compromis

D'un point de vue de la performance, je ne pense pas qu'il y ait probablement une différence entre les 3 options, tant que les requêtes et les données s'inscrivent dans vos scénarios attendus. Je teste avec 100 fois plus de données, qui pourrait élargir la clause « where » pour voir ce qui se passe, mais la structure d'indexation, etc. est plus susceptible d'affecter les performances que si vous exécutez la même SQL à partir d'un proc stocké, par un vue, ou à partir d'une application cliente.

La meilleure façon de répondre à cette question est de le tester - il y a, bien sûr, de nombreux détails spécifiques qui pourraient invalider le grand «J'attends x, y ou z » réponses que nous overflowers peut donner. Si la performance est une préoccupation majeure, utilisez un outil de remplissage de base de données (faire Redgate, je l'ai utilisé DBMonster dans le passé) et essayer les 3 options.

D'un point de maintenance de vue, je voudrais fournir une option 4, qui - à mon avis - est de loin le meilleur.

Option 4: construire une bibliothèque d'accès aux données qui encapsule l'accès à vos données. Demandez à la bibliothèque exposer les méthodes et les paramètres pour affiner la sélection des dossiers. Considérons en utilisant le motif de spécification (http://en.wikipedia.org/wiki/Specification_pattern). Utilisez toutes les requêtes sont les meilleurs dans la bibliothèque, et ne dérange pas les développeurs avec les détails de mise en œuvre.

Si cela ne fonctionne pas - le code d'application hétérogène, trop de changement pour une exigence simple - je voudrais évaluer les options comme suit:

  1. Embedded SQL: en fonction du nombre de fois que SQL est réutilisée, ce qui peut bien se passer. S'il n'y a qu'une partie du code qui exécute le SQL, il est logiquement semblable à la bibliothèque d'accès aux données. Si, toutefois, le même extrait a besoin d'obtenir de remploi dans de nombreux endroits, il est une source probable pour les bugs - un petit changement dans le SQL devrait être répétée à plusieurs endroits.

  2. La procédure stockée: Je n'aime généralement les procédures stockées pour des raisons de maintenance - ils ont tendance à devenir cassant par surchargement et créer une manière procédurale de la pensée. Par exemple, si vous avez d'autres exigences pour l'utilisation de ce calcul SQL dans une procédure stockée séparée, très rapidement vous retrouver avec un modèle de programmation procédural, avec procs stockées appelant l'autre.

  3. Vues: ce qui est probablement le meilleur choix. Il met la logique de données spécifique dans un lieu unique, mais favorise l'utilisation de la logique ensembliste parce que la voie d'accès se fait par une instruction SELECT, plutôt que par l'exécution d'une procédure des déclarations. Les vues sont faciles à incorporer dans d'autres requêtes.

Autres conseils

Si elle est bien mis en œuvre, l'une des trois solutions serait bien pour manteinance, mais gardez à l'esprit comment voulez-vous traiter chacun d'entre eux dans un processus de migration (code ou migration de base de données).

Si la requête est grande, la procédure stockée vous donnera un peu supplémentaire performances en raison de moins de frais généraux de la bande passante, car il est l'envoi d'une requête plus petite taille. Vous pouvez également gagner un peu de sécurité supplémentaire avec cette solution.

Pour manteinance solution, je préfère la 1ère et 2ème solution, coz vous pouvez apporter des modifications sur la requête sans faire aucune modification de la base de données. Si vous choisissez la 1ère solution, j'envelopperait l'appel de requête dans une fonction de sorte que vous aurez un seul endroit pour faire des changements.

D'un point de vue du développeur , je choisirais la solution de vue beacuse est le plus un transparent, je veux dire qu'il est comme l'interrogation juste une table régulière, vous pouvez vérifier la structure de la table avec une commande describe, ou tout simplement sélectionner les champs et les conditions que vous devez requête, ou se joindre à une autre table, etc ...

A propos de la où la flexibilité de la clause , vous pouvez obtenir avec l'une des solutions proposées. Vous pouvez ajouter un ou paramètre dans votre fonction d'emballage (1), vous pouvez ajouter un ou paramètre à la procédure stockée, mais être prudent avec des injections (2), ou le développeur peut ajouter une clause where comme d'habitude avec la vue (3)

Compte tenu du fait que dans les vues MySQL ne sont pas des tables temporaires, si la requête est très complexe cette solution ne serait pas le meilleur si la requête est beaucoup utilisé et de différentes manières (désactivation du cache amélioration des performances). Je considérerais une table temporaire Solution (tableau de compteur) qui met à jour chaque période de temps avec une tâche / cron programmée (par exemple un jour, une semaine, chaque fois que nécessaire) ou est mis à jour en définissant les déclencheurs de Propper. Cette solution pourrait améliorer les performances un peu.

Espérons que cela aide, je comme la solution la plus vue, mais peut-être qu'il est plus complexe à développer d'un point de vue de la base de données.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top