10
votes

Meilleur modèle pour les constantes dans SQL?

J'ai vu plusieurs modèles utilisés pour "surmonter" le manque de constantes dans SQL Server, mais aucun d'entre eux ne semble satisfaire les performances et les préoccupations de la lisibilité / de la main-d'œuvre.

Dans l'exemple ci-dessous, en supposant que nous avons une intégrale Classification «Statut» sur notre table, les options semblent être: p>

  • juste pour le code dur, et éventuellement juste "commentaire" le statut li> ul>

    p> xxx pré>

    • à l'aide d'une table de recherche pour les états, puis rejoignez cette table de sorte que le où code> clause référente le nom sympathique. LI> ul>

      sous-requête: strong> p>

      p> xxx pré>

      ou joint p >

      SELECT ... FROM [Table] WHERE StatusId = LoadedStatus();
      
      • Un tas de Scalar UDF est défini pour les constantes de retour, VIZ LI> ul>

        p> xxx pré>

        et ensuite p> xxx pré>

        (IMO ceci provoque beaucoup de pollution dans la base de données - Cela peut être correct dans un emballage Oracle Package) P>

        • et des motifs similaires avec des fonctions valorisées de table contenant les constantes avec des valeurs en tant que lignes ou colonnes, qui sont appliquées code> retour sur [tableau] li> li> li> ul>

          Comment d'autres utilisateurs ont-ils résolu ce problème commun? p>

          edit forte>: Bounty - Quelqu'un a-t-il une méthode de la meilleure pratique pour maintenir $ (variables) dans DBPROJ DDL / Schema scripts selon Remus Réponse et commentaire? P> P>


0 commentaires

4 Réponses :


3
votes

J'ai utilisé l'option de fonction scalaire dans notre dB et ça marche bien et que, selon ma vue, est le meilleur moyen de cette solution.

Si plus de valeurs liées à un élément, vous avez suivi une recherche si vous chargez que vous chargez Combobox ou tout autre contrôle avec une valeur statique, utilisez la recherche qui est le meilleur moyen de le faire.


0 commentaires

15
votes

codé dur. Avec la performance SQL Trumpers de la maintenabilité.

Les conséquences du plan d'exécution entre l'utilisation d'une constante que l'optimiseur peut inspecter le temps de génération de plan par rapport à une forme d'indirection (UDF, jointure, sous-requête) est souvent dramatique. SQL 'Compilation' est un processus extraordinaire (dans le sens qui n'est pas «ordinaire» comme la génération de code IL) dans le résultat est déterminé non seulement par la construction de langue étant compilée (c.-à-d. Le texte réel de la requête) mais également Par le schéma de données (index existants) et les données réelles de ces index (statistiques). Lorsqu'une valeur codée dur est utilisée, l'optimiseur peut donner un meilleur plan car elle peut réellement vérifier la valeur par rapport aux statistiques de l'indice et obtenir une estimation du résultat.

Une autre considération est qu'une application SQL n'est pas une autre considération. Code seulement, mais par une grande marge est le code et les données. «Refactoring» Un programme SQL est ... différent. Où dans un programme C # peut changer une constante ou enum, recompiler et exécuter joyeusement l'application, dans SQL ONE ne peut pas le faire, car la valeur est probablement présente dans des millions d'enregistrements dans la base de données et la modification de la valeur constante implique également de modifier également la modification de GBS de données. , souvent en ligne tandis que de nouvelles opérations se produisent.

juste parce que la valeur est codée dur dans les requêtes et les procédures observées par le serveur ne signifie pas nécessairement que la valeur doit être codée dur dans le code source d'origine du projet. Divers outils de génération de code peuvent s'occuper de cela. Considérez quelque chose comme trivial que de tirer parti du Variables de script SQLCMD :

définit.sql : xxx

somesource.sql : xxx

quelque sothersource.sql : xxx


6 commentaires

Merci - nous utilisons dbpro et cela m'a conduit à blogs.msdn.com/b/gertd/archive/2007/01/08/...


Malheureusement, DBPRO n'accepte pas la substitution $ (variable) dans chaque fichier source Source .SQL, uniquement dans les fichiers de script .sql (le script exécuté après le déploiement du schéma). Ce serait génial si vous pouviez utiliser des variables dans la définition de procédures ...


Merci Remus - si nous pouvons contourner cette limitation, ce serait une solution parfaite IMHO. J'ai ajouté une prime;)


+1, codé dur. Avec la performance SQL Trumps de la maintenabilité.


La seule solution de contournement que je connaisse pour les variables dbpro dans les scripts non pré / post Déployer est d'utiliser des étapes de construction explicites pour transformer les fichiers de modèle en fichiers source et modifier / modifier uniquement les modèles. Voir blogs.msdn.com / B / PSIRR / Archive / 2009/207/31 / ... , spécifiquement le modèle VS add-in, ils s'agront là-bas. Personnellement, je pense que cette approche introduit plus de problèmes que cela ne résout, mais je dois le mentionner non moins.


Merci Remus - The Bounty est à vous - tenant des pouces qu'une version future de DataDude va résoudre ce problème!



2
votes

Vous pouvez également ajouter plus de champs à votre tableau d'état qui agissent comme des marqueurs ou des groupeurs uniques pour les valeurs d'état. Par exemple, si vous ajoutez un champ isolé sur votre tableau d'état, l'enregistrement 87 pourrait être le seul à définir la valeur du champ, et vous pouvez tester la valeur du champ iselé au lieu de la description du disque dur 87 ou de l'état. < / p>


2 commentaires

Bonjour Beth, merci pour la réponse - intéressant, définitivement un modèle de lisibilité valide. J'ajouterais donc des champs de bits pour chaque état ischargé, issu, IssemeSotherstatus, puis chaque État n'aurait que son ensemble de bits applicable. Je suppose que l'inconvénient est toujours que la participation supplémentaire à un statut est nécessaire dans la poursuite de la lisibilité.


C'est vraiment plus une chose d'entretien. Vous ne voulez pas de texte de statut dans vos requêtes sous forme de critères car le texte peut changer, et parfois, les ID finissent par changer également. Pour éviter une jointure, vous devez tester la valeur dans la table principale, comme dans votre premier exemple.



6
votes

Pendant que je suis d'accord avec Remus Rusanu, IMO, la maintenabilité du code (et donc la lisibilité, le moins d'étonnement, etc.) Trump Autres préoccupations, à moins que la différence de performance ne soit suffisamment significative pour justifier le contraire. Ainsi, la requête suivante perd sur la lisibilité: xxx

en général, lorsque j'ai des valeurs dépendantes du système qui seront référencées dans le code (peut-être imiter dans une énumération par nom), j'utilise des clés principales de chaîne) pour les tables dans lesquelles ils sont conservés. Contrastez cela aux données modifiables par l'utilisateur dans lesquelles j'utilise généralement des touches de substitution. L'utilisation d'une clé primaire nécessitant une entrée aide (bien que non parfaitement) d'indiquer à d'autres développeurs que cette valeur n'est pas destinée à être arbitraire.

Ainsi, ma table "status" ressemblerait à: xxx

Ceci rend la requête plus lisible, il ne nécessite pas de jointure à la table d'état et ne nécessite pas l'utilisation d'un nombre magique (ou de GUID). En utilisant des fonctions définies par l'utilisateur, IMO est une mauvaise pratique. Au-delà des implications de la performance, aucun développeur ne s'attendrait jamais à ce que UDF soit utilisé de cette manière et viole ainsi les critères les moins étonnants. Vous seriez presque obligé d'avoir un UDF pour chaque valeur constante ; Sinon, ce que vous passez dans la fonction: un nom? une valeur magique? Si un nom, vous pourriez aussi bien conserver le nom dans une table et l'utiliser directement dans la requête. Si une valeur magique, vous êtes de retour sur le problème d'origine.


3 commentaires

Yup, a du sens, cependant, le «plus petit INT» est une norme de conception de la DB dans notre société (l'argument standard de la clé de substitution VS Natural Keys a déjà été joué en faveur des substituts). Notre DBA est comme des indices étroits qu'il semble, et une colonne comme le statut est fortement filtrée dans les requêtes.


@nonnB - Avoir une société Norme de clés naturels VS Keys de substitution suppose faussement que une seule et une seule solution a du sens pour toutes les tables. Il est apparentant de demander à toutes les portes d'avoir un seul bouton des doubles portes ou des portes qui n'ont pas besoin de bouton. Les deux types de clés ont leur place. Utiliser des clés de substitution pour les monnaies, par exemple, constituerait une mauvaise décision de design imo. Il ajoutera des jointures inutiles et encouragera le Code difficile à lire. En bref, cela coûtera de l'argent de l'entreprise. Un code d'état unique du personnage serait toujours meilleur qu'un nombre magique et reprendre le même espace qu'un tinytinint.


vous prêchez à la convertie. J'ai passé une année à maintenir une pick / univers dB il n'y a pas si longtemps, et les avantages de codifier des "clés étrangères" (pas que U2 n'avait aucune) et que, ainsi, économisez sur la jointure totalement clearystal :)