La vue imbriquée est-elle une bonne conception de base de données?

42

J'ai lu quelque part il y a longtemps. Le livre indique que nous ne devrions pas permettre d'avoir une vue imbriquée dans SQL Server. Je ne suis pas sûr de la raison pour laquelle nous ne pouvons pas faire cela ou je pourrais me souvenir d'une déclaration incorrecte.

Élèves

SELECT studentID, first_name, last_name, SchoolID, ... FROM students

CREATE VIEW vw_eligible_student
AS 
SELECT * FROM students
WHERE enroll_this_year = 1

Enseignants

SELECT TeacherID, first_name, last_name, SchoolID, ... FROM teachers

CREATE VIEW vw_eligible_teacher
AS 
SELECT * FROM teachers
WHERE HasCert = 1 AND enroll_this_year = 1

Écoles

CREATE VIEW vw_eligible_school
AS 
SELECT TOP 100 PERCENT SchoolID, school_name 

FROM schools sh 
JOIN
     vw_eligible_student s 
     ON s.SchoolID = sh.SchoolID
JOIN 
     vw_eligible_teacher t
     ON s.SchoolID = t.SchoolID

Sur mon lieu de travail, j'ai enquêté sur l'une de nos applications de base de données internes. J'ai vérifié à travers les objets que deux ou trois couches de la vue s'empilent. Cela m'a donc rappelé ce que je lisais dans le passé. Quelqu'un peut-il aider à l'expliquer?

Si cela ne vous convient pas, je veux savoir que cela se limite à SQL Server ou à la conception de bases de données en général.

Informations supplémentaires: j'ai mis à jour un exemple de mon entreprise. Je change un peu pour être plus général sans trop de technique (trop de colonnes dans cet exemple). La vue imbriquée que nous avons utilisée est principalement basée sur une vue abstraite ou agrégée. Par exemple, nous avons une grande table d’étudiants avec des centaines de colonnes. Dites, Eligible Student Viewest basé sur les étudiants qui s'inscrivent cette année. Et la vue éligible des étudiants pourrait être utilisée à d’autres endroits, comme dans une procédure stockée.

Richard Sayakanit
la source
3
Je soutiens que les mêmes avantages et inconvénients équivaudraient à peu près quelle que soit la plate-forme spécifique.
Aaron Bertrand

Réponses:

47

Quelle que soit la plate-forme, les remarques suivantes s'appliquent.

(-) Vues imbriquées:

  • sont plus difficiles à comprendre et à déboguer

    Par exemple, à quelle colonne de la table cette colonne de vue fait-elle référence? Lemme creuser à travers 4 niveaux de définitions de vue ...

  • rendre plus difficile pour l'optimiseur de requête de proposer le plan de requête le plus efficace

    Voir ceci , ceci , ceci et cela comme preuve anecdotique. Comparez à cela , ce qui montre que l'optimiseur est souvent suffisamment intelligent pour décompresser correctement les vues imbriquées et sélectionner un plan optimal, mais pas sans coût de compilation.

    Vous pouvez mesurer le coût des performances en comparant la requête d'affichage à une requête équivalente écrite par rapport aux tables de base.

(+) D'autre part, les vues imbriquées vous permettent:

  • centraliser et réutiliser des agrégations ou des règles métier
  • éloignez votre structure sous-jacente (par exemple, des autres développeurs de bases de données)

J'ai trouvé qu'ils sont rarement nécessaires.


Dans votre exemple, vous utilisez des vues imbriquées pour centraliser et réutiliser certaines définitions métier (par exemple, "Qu'est-ce qu'un étudiant éligible?"). Ceci est une utilisation valide des vues imbriquées. Si vous entretenez ou optimisez cette base de données, comparez les coûts de leur conservation à ceux de leur suppression.

  • Conserver: en conservant les vues imbriquées, vous bénéficiez des avantages et des inconvénients énumérés ci-dessus.

  • Supprimer: pour supprimer les vues imbriquées:

    1. Vous devez remplacer toutes les occurrences des vues par leurs requêtes de base.

    2. N'oubliez pas de mettre à jour toutes les requêtes pertinentes si votre définition d'élève / enseignant / école éligible change, par opposition à une simple mise à jour de la définition de vue pertinente.

Nick Chammas
la source
1
+1, sauf que je remplacerais "plus difficile" pour l'optimiseur de requête par "presque impossible". :)
Jason
1
@ Jason - Je suis d'accord et j'aimerais pouvoir citer des exemples concrets. Connaissez-vous des références qui expliquent ou démontrent pourquoi il en est ainsi?
Nick Chammas
1
Tout ce que je peux trouver, ce sont des preuves anecdotiques selon lesquelles, une fois utilisées, les vues imbriquées souffrent de problèmes de performances par rapport au code SQL "aplati". sqlservercentral.com/blogs/2cents/archive/2010/04/05/… Le problème semble résulter du fait que la base de données (SQL Server dans ce cas) n'appliquera pas certains filtres avant de joindre des tables et faire en sorte que la requête prenne plus de temps que prévu.
Jason
7
Je ne suis pas d’accord sur le problème de l’optimiseur de requêtes, car la requête résultante, une fois toutes les vues résolues, sera la même, peu importe le nombre de transformations de vues qu’elle a subies (à l’exception de quelques colonnes supplémentaires dans des ensembles de résultats intermédiaires, que l’optimiseur peut éliminer parfaitement). Cela laisse le débogage; IMO cela facilite le débogage d'avoir des vues imbriquées car je peux regarder les résultats intermédiaires pour voir où ça a mal tourné.
Simon Richter
1
J'ai écrit un serveur de base de données intégré et, selon moi, la solution évidente consistait tout d'abord à résoudre les vues, puis à optimiser la requête résultante, car il est en fait assez improbable que toutes les requêtes sur les vues renvoient toutes les colonnes. Je ne peux même pas penser à une raison pour laquelle obtenir des données de vue au milieu d'une requête permettrait de gagner quelque chose, alors c'était une évidence pour moi.
Simon Richter
26

Parfois, des vues imbriquées sont utilisées pour empêcher la répétition d'agrégats. Supposons que vous ayez une vue qui compte les messages et les regroupe par ID utilisateur. Vous pouvez avoir une vue qui compte le nombre d'utilisateurs ayant plus de 100 messages, ce genre de chose. Ceci est plus efficace lorsque la vue de base est une vue indexée - vous ne voulez pas nécessairement créer une autre vue indexée pour représenter les données avec un groupe légèrement différent, car vous payez maintenant deux fois pour la maintenance de l'index lorsque les performances sont probablement optimales. adéquat contre la vue originale.

Si ce ne sont que des vues imbriquées dans lesquelles vous êtes en train de sélectionner *, mais en modifiant l'ordre ou le haut, il semble que cela serait mieux encapsulé en tant que procédure stockée avec des paramètres (ou fonctions de table inline) plutôt qu'un ensemble de vues imbriquées. A MON HUMBLE AVIS.

Aaron Bertrand
la source
4
"C’est plus efficace lorsque la vue de base est une vue indexée." Point important.
Nick Chammas
7

Les versions ultérieures de SQL (2005+) semblent mieux optimiser l’utilisation des vues. Les vues sont les meilleures pour consolider les règles métier. EG: où je travaille, nous avons une base de données de produits de télécommunications. Chaque produit est affecté à un plan tarifaire, qui peut être échangé et les tarifs du plan tarifaire peuvent être activés / désactivés à mesure que les taux augmentent ou sont modifiés.

Pour faciliter les choses, nous pouvons créer des vues imbriquées. La 1ère vue ne fait que relier les taux tarifaires à leurs taux en utilisant les tables nécessaires et en renvoyant les données nécessaires aux niveaux de vues suivants. La 2e vue (s) peut uniquement isoler les plans de taux actifs et leurs taux actifs. Ou simplement les tarifs clients. Ou les taux des employés (pour la réduction des employés). Ou les tarifs des clients professionnels par rapport aux clients résidentiels. (les plans tarifaires peuvent être compliqués). Le fait est que la vue de base garantit que notre logique métier globale pour les plans tarifaires et les tarifs sont correctement regroupés au même endroit. La couche suivante de vues nous permet de nous concentrer davantage sur des plans de taux spécifiques (types, actif / inactif, etc.).

Je conviens que les vues peuvent gêner le débogage si vous créez des requêtes et des vues en même temps. Toutefois, si vous utilisez une vue éprouvée, cela facilite le débogage. Vous savez que la sonnerie a déjà été passée en revue, vous savez donc que le problème n’est probablement pas à l'origine du problème.

Les problèmes peuvent cependant venir avec votre point de vue. "Que se passe-t-il si un produit est associé uniquement à un plan tarifaire inactif?" ou "et si un plan tarifaire ne comporte que des taux inactifs?" Eh bien, cela peut être bloqué au niveau frontal avec une logique qui détecte les erreurs des utilisateurs. "Erreur, le produit est sur un plan tarifaire inactif ... veuillez corriger". Nous pouvons également exécuter des audits de requête pour le revérifier avant un cycle de facturation. (sélectionnez tous les forfaits et rejoignez la vue de plan de taux actif, renvoyez uniquement les plans pour lesquels un plan de taux actif n'est pas considéré comme un problème à résoudre).

L'avantage est que les vues vous permettent de condenser considérablement les requêtes de rapport, de facturation, etc. Vous pouvez avoir une vue de compte client, puis une vue de second niveau des clients actifs uniquement. Équipe qui avec une vue de l'adresse du client. Equipe qui a une vue du (des) produit (s) (joint (e) à quel (s) produit (s) le client a). Faites en sorte que l’équipe visualise le plan tarifaire du ou des produits. Faites équipe avec la vue des caractéristiques du produit. Voir, voir, voir, chaque essai-n-errored pour assurer l'intégrité. Votre requête de fin utilisant les vues est très compacte.

modifier:

Comme exemple illustrant à quel point la vue aurait été meilleure qu'une simple requête de tables à plat ... nous avons fait appel à un sous-traitant intérimaire pour apporter des modifications. Ils lui ont dit qu'il y avait des points de vue, mais il a décidé d'écraser toutes ses questions. Billing a eu raison de certaines de ses questions. Ils ont continué à obtenir plusieurs plans de taux et des taux sur des choses. Il s'avère que ses requêtes manquaient de critères pour autoriser les tarifs à facturer s'ils étaient entre les dates de début et de fin auxquelles le plan tarifaire était censé utiliser ce / ces tarifs pendant. Oops. S'il avait utilisé la vue, il aurait déjà pris en compte cette logique.

Fondamentalement, vous devez peser performance / santé mentale. Peut-être que vous pouvez faire toutes sortes de choses sophistiquées pour augmenter les performances d'une base de données. Mais, si cela signifie que c'est un cauchemar pour une nouvelle personne à prendre en charge / à entretenir, en vaut-il vraiment la peine? Vaut-il vraiment la peine que le nouveau gars doive jouer à whack-a-mole chercher toutes les questions qui doivent changer de logique (et risquer de l’oublier / de les doigter grossièrement) parce que quelqu'un a décidé que ses opinions sont "mauvaises" et n'a pas consolidé une logique métier de base en une logique pouvant être utilisée dans des centaines d'autres requêtes? Cela dépend vraiment de votre entreprise et de votre équipe informatique / informatique / base de données. Mais, je préférerais la clarté et la consolidation d'une source unique à la performance.

bla bla
la source
4

Le vrai problème n'est pas les vues imbriquées en elles-mêmes. Le vrai problème est la prolifération de vues imbriquées alors que les développeurs superposent des modifications supplémentaires aux vues existantes. J'ai trouvé des requêtes avec une vue imbriquée 4 couches qui se sont réellement jointes à l'une des vues dans sa définition. Notre tendance à choisir la solution de facilité, plutôt que d’analyser et de résoudre un problème, en est la racine.

Rayon
la source
0

Dans mon environnement, nous répliquons un grand nombre de tables du serveur de production vers le serveur de rapports. Sur le serveur de rapports, de nombreuses vues sont basées sur des tables de production répliquées ET sont imbriquées. Avant que la réplication ne commence, nous devons supprimer toutes les vues pour rendre la réplication possible (nous utilisons drop et create car la structure des tables change souvent en production). Une fois la réplication terminée, nous devons reconstruire toutes les vues.

Maintenant, voici la partie amusante: Comme beaucoup de vues sont imbriquées, nous devons les reconstruire dans un ordre spécifique. Lors de toute modification de la définition des vues, nous devons veiller à conserver le bon ordre de reconstruction. C'est un gâchis total. Je déconseille vivement d'utiliser des vues imbriquées si vous utilisez la réplication ou si vous supprimez et reconstruisez simplement vos tables, qui sont la source des vues.

La performance est une autre chose. Les vues basées sur d'autres vues ne sont rien d'autre que plusieurs requêtes à exécuter. Il est plus facile de regrouper une requête plus volumineuse, de créer un travail et d'en faire un tableau. Plus facile et améliore les performances.

Narval
la source