Cette page a été traduite automatiquement. Lisez l'original en anglais. English

Bibliothèque IBSurgeon

Vues (InterBase et Firebird)

Alexey Kovyazin, dernière mise à jour le 13 avril 2012

Ceux qui connaissent le langage SQL n’ont pas besoin d’explications détaillées sur ce sujet, mais pour préserver la séquence de présentation, nous introduirons une brève définition des vues.

Une VUE est une table virtuelle créée sur la base d’une requête adressée à des tables ordinaires. Une vue est implémentée comme une requête, stockée sur un serveur et exécutée à chaque fois que l’on fait référence à une vue.

Considérons différentes variantes d’utilisation des vues. Les vues permettent de créer des niveaux de structure de données, permettant de séparer l’implémentation du stockage des données de leur type. Par exemple, nous pouvons créer une vue qui sélectionne les données de plusieurs tables. Si les clients utilisent cette vue au lieu de se référer directement aux tables sous-jacentes, le développeur de base de données pourra modifier la requête sous-jacente à la vue, la changer (pour l’optimiser, par exemple), et le client ne remarquera rien - ce sera la même vue pour lui. Outre le fait qu’elles isolent l’implémentation du stockage des données de l’utilisateur, les vues permettent d’organiser les données de manière plus pratique et plus simple. Le problème de la « simplification » de la structure des données se pose lorsque le nombre de tables dans une base de données devient suffisamment grand et que les interrelations entre elles deviennent compliquées. La vue permet d’éliminer (ou, au contraire, d’ajouter) une partie des données non nécessaires au client concret de la base de données (ou - nécessaires).

De plus, les vues permettent d’organiser plus simplement la sécurité dans une base de données InterBase. Certains utilisateurs peuvent avoir des droits uniquement pour lire / mettre à jour les données dans la vue, mais n’avoir aucun droit (et même aucune idée) sur les tables sous-jacentes à la vue ! Pour plus de détails sur la sécurité dans InterBase, voir le chapitre « Sécurité dans InterBase : utilisateurs, leurs fonctions et droits » (partie 4).

Syntaxe DDL pour travailler avec les vues

Nous allons maintenant considérer les commandes de création et de suppression de vues définies par le DDL (Data Definition Language - sous-ensemble de SQL, voir le glossaire). Pour créer une vue dans InterBase, nous devons utiliser la phrase de syntaxe suivante :

CREATE VIEW nom_vue [(colonne_vue[, colonne_vue…])] AS [WITH CHECK OPTION] ; Ici, nom_vue est le nom de la vue qui doit être unique dans une base de données, puis vient un groupe de noms de champs inclus dans la vue, pas toujours obligatoires : [(colonne_vue [, colonne_vue …])]. Il est essentiel de définir la déclaration qui sélectionne les données incluses dans la vue. Nous discuterons du paramètre optionnel WITH CHECK OPTION un peu plus tard dans la partie « Vues modifiées ».

Pour modifier la vue, nous devrons la recréer, c’est-à-dire la supprimer et la créer à nouveau. Lors de la suppression de la vue, il est nécessaire de supprimer également tous les objets dépendants - les déclencheurs, les procédures stockées et les autres vues. C’est l’un des principaux inconvénients du travail avec les vues : la nécessité de recréer l’arbre des objets utilisant la vue (il existe des utilitaires qui permettent de le faire plus facilement, par exemple IBAlterView, voir l’application « Outils d’administration et de conception pour InterBase »). Nous devons utiliser la commande DDL suivante si nous voulons supprimer la vue :

DROP VIEW nom_vue ;

Exemples de vues

Voici un exemple de vue simple :

CREATE VIEW MyView AS SELECT NAME, PRICE_1 FROM Table_example ;

Dans cet exemple, nous créons une vue basée sur une requête à la table Table_example que nous avons considérée dans le chapitre « Tables. Clés primaires et générateurs ». Dans ce cas, la vue sera composée de deux champs - NAME et PRICE_1, qui seront sélectionnés dans la table Table_example sans aucune condition, c’est-à-dire que le nombre d’enregistrements dans la vue MyView sera égal au nombre d’enregistrements dans Table_example. Cependant, les vues ne sont pas toujours aussi simples. Elles peuvent être basées sur les données de plusieurs tables et même sur la base d’autres vues. De plus, les vues peuvent contenir des données obtenues sur la base de différentes expressions - y compris sur la base de fonctions d’agrégation. Afin de considérer plus en détail l’utilisation de cette application de vue, créons deux tables reliées par une relation un-à-plusieurs (souvent une telle relation est appelée maître-détail). Voici le script DDL pour créer ces tables :

/\* Table : WISEMEN */

CREATE TABLE WISEMEN ( ID_WISEMAN INTEGER NOT NULL, WISEMAN_NAME VARCHAR(80));

/\* Définition des clés primaires */

ALTER TABLE WISEMEN ADD CONSTRAINT PK_WISEMEN PRIMARY KEY (ID_WISEMAN);

/\* Table : WISEBOOK */

CREATE TABLE WISEBOOK ( ID_BOOK INTEGER NOT NULL, ID_WISEMAN INTEGER, BOOK VARCHAR(80));

/\* Définition des clés primaires */

ALTER TABLE WISEBOOK ADD CONSTRAINT PK_WISEBOOK PRIMARY KEY (ID_BOOK);

/\* Définition des clés étrangères */

ALTER TABLE WISEBOOK ADD CONSTRAINT FK_WISEBOOK FOREIGN KEY (ID_WISEMAN) REFERENCES WISEMEN (ID_WISEMAN);

Ainsi, nous avons créé deux tables - WISEMEN et WISEBOOK reliées par une relation maître-détail en utilisant une contrainte de clé étrangère - FOREIGN KEY. Supposons que ces tables stockeront les informations sur les grands sages chinois et leurs œuvres. Nous pouvons maintenant créer quelques vues basées sur ces tables. Par exemple, créons la vue montrant combien d’œuvres chaque sage a écrites :

CREATE VIEW WiseBookCount (WISEMAN, HOW_WISEBOOKS) AS SELECT M.WISEMAN_NAME, COUNT(B.BOOK) FROM WISEMEN M, WISEBOOK B WHERE (M.ID_WISEMAN = B.ID_WISEMAN) GROUP BY M.WISEMAN_NAME

Faites attention que lors de l’utilisation de toute expression calculée comme les fonctions d’agrégation COUNT (), SUM (), MAX (), etc., il est essentiel d’utiliser des noms définis pour les champs de la vue, c’est-à-dire de donner des noms à tous les champs retournés par la requête. Comme nous pouvons le voir dans cet exemple, ces noms ne doivent pas nécessairement coïncider avec les noms des champs de la requête, mais leur quantité doit coïncider avec la quantité de champs retournés par la requête. La définition de quel champ retourné par la requête correspond à quel champ de la vue est faite par un numéro de série - le premier champ de la requête sera reflété dans le premier champ de la vue, le deuxième - dans le deuxième, etc.

Et si nous voulions savoir lequel des sages a écrit le plus de livres ? Nous essaierons d’ajouter l’expression de tri - ORDER BY à la requête sous-jacente à la vue. Cependant, cette tentative sera infructueuse : l’utilisation du tri ORDER BY dans les vues n’est pas autorisée et lors de la tentative de création de la vue avec la requête contenant ORDER BY, une erreur se produira. Si nous voulons trier les résultats retournés par la vue, nous devrons le faire au nom du client :

SELECT * FROM WiseBookCount ORDER BY HOW_WISEBOOKS

L’exécution de cette requête SQL conduira à un résultat souhaitable. Outre la contrainte d’utilisation de l’expression ORDER BY dans les vues, nous ne pouvons pas non plus utiliser l’ensemble de données reçu à la suite de l’exécution de procédures stockées comme source de données (voir le chapitre « Procédures stockées » ci-dessous).

Peut-être, vaut-il la peine de donner un autre exemple illustrant l’application des vues. Supposons que nous devions afficher une liste de sages dont le nom commence par la lettre « K ». Dans ce cas, nous utiliserons la vue avec des conditions :

CREATE VIEW WiseMen2 (WISEMAN) AS SELECT M.WISEMAN_NAME FROM WISEMEN M WHERE M.WISEMAN_NAME LIKE ‘K%’

Ainsi, il est facile de créer des vues qui jouent le rôle de fournisseurs de données constamment mis à jour, les sélectionnant dans une base de données selon des conditions définies.

Vues modifiées

Nous avons mentionné ci-dessus qu’il existe une capacité de créer des vues de données modifiées. C’est vraiment le cas - il existe une capacité non seulement de lire les données de la vue, mais aussi de les modifier !

Il y a deux façons de rendre la vue modifiée. La première façon est appliquée lorsque la vue est créée sur la base d’une table unique (ou d’une autre vue modifiée), et toutes les colonnes de la table donnée doivent permettre la présence de NULL. Ainsi, la requête sur laquelle la vue est basée ne peut pas contenir de sous-requêtes, de fonctions d’agrégation, d’UDF, de procédures stockées, de déclarations DISTINCT et HAVING. Si toutes ces conditions sont remplies, la vue devient automatiquement modifiée, c’est-à-dire que nous pouvons exécuter les requêtes DELETE, INSERT et UPDATE pour elle, qui modifieront les données dans la table source.

La liste des conditions est plutôt impressionnante et contraint fortement l’application de telles vues modifiées, par conséquent elles sont utilisées assez rarement.

Afin de rendre modifiée une vue qui viole l’une des conditions ci-dessus énumérées, le mécanisme des déclencheurs est appliqué. Pour plus de détails sur les déclencheurs, voir le chapitre « Déclencheurs » (partie 1). Maintenant, nous ne considérerons que les principes généraux de l’organisation de la modification des données dans une VIEW.

Pour l’implémentation d’une vue mise à jour à l’aide de déclencheurs, ce qui suit doit être fait. Créer 3 déclencheurs pour la vue donnée pour les événements : BEFORE DELETE, BEFORE UPDATE et BEFORE INSERT. Décrire dans ces déclencheurs ce qui doit être fait avec les données lors de la suppression, de la mise à jour et de l’insertion.

Ensuite, nous devons utiliser la vue donnée dans les requêtes de modification - DELETE, INSERT ou UPDATE. Lorsque InterBase recevra cette requête, il vérifiera s’il existe des déclencheurs appropriés pour la vue donnée, c’est-à-dire BEFORE DELETE/INSERT/UPDATE. Si le déclencheur pour l’action exécutable existe, InterBase l’appellera pour modifier les données réelles dans les tables sous-jacentes à la vue (bien que cela puisse être d’autres données - il n’y a pas de contraintes textuelles de ces déclencheurs), puis relira la chaîne (ou les chaînes) sur laquelle la modification a été effectuée.

Ainsi, il existe une capacité de réaliser des chaînes complexes de mise à jour de données dans les vues.

L’option WITH CHECK OPTION a été mentionnée dans la description de la syntaxe de création de la vue. Si cette option est définie lors de la création d’une vue modifiée, chaque chaîne de données insérée ou modifiée dans cette vue sera vérifiée sur une condition d’entrée dans la vue. Cela peut être expliqué ainsi : si un nouvel enregistrement inséré par l’utilisateur ou reçu à la suite de la mise à jour de l’enregistrement existant ne satisfait pas aux conditions de la requête, qui est le fournisseur de données pour la VIEW, l’insertion de cet enregistrement sera annulée et une erreur se produira.

Conclusion

Malgré la simplicité apparente de la création et de l’utilisation des vues, elles offrent de grandes capacités pour améliorer l’organisation des données dans une base de données et permettent de créer une hiérarchie d’organisation des données.

Certains concepteurs d’applications de bases de données utilisent très souvent les vues dans leur travail, d’autres évitent leur application, en la motivant par une complexité de modification des vues et une tendance à préserver le schéma de base de données aussi simple et efficace que possible. C’est à vous de décider comment vous appliquerez les vues dans votre travail. Le point le plus important est de se souvenir de l’existence d’un outil aussi puissant qu’est la vue, et de savoir comment l’utiliser.