Professional Documents
Culture Documents
Type
CHAR(n) INTEGER VARCHAR(n) DECIMAL(m,n) DATE TIME DATETIME TEXT
Description Chaine de longueur fixe gale n caractres. Entier. Chaine de longueur maximale n. Numrique sur m chiffres avec n dcimales. Date avec le jour, le mois, l'anne. Horaire avec heures, minutes, secondes. Date et horaire runis (non ANSI) Texte de longueur quelconque (non ANSI)
Les types numriques exacts sont ceux dont la prcision est dtermine l'avance comme INTEGER et DECIMAL. Ils acceptent l'option ZEROFILL qui permet de remplir avec des 0 l'espace restant. Le type UNSIGNED permet d'interdire les nombres ngatifs (en supprimant le bit de signe).
Le type DECIMAL permet de spcifier le nombre de chiffres avant et aprs la virgule mais il n'admet par l'option UNSIGNED.
FLOAT [(m,n)] [ZEROFILL]
Les numriques flottants en revanche ont une prsentation propre la machine: FLOAT correspond aux flottants en simple prcision. DOUBLE correspond aux flottants en double prcision.
Les chanes de caractres peuvent tre stockes dans les deux types: CHAR qui spcifie un nombre de caractres fixe infrieur 255 et VARCHAR qui spcifie un nombre de caractres maximal infrieur 65535. L'option BINARY permet les comparaisons de chaine prenant en compte la casse.
TEXT et BLOB permettent de rpondre la problmatique des chaines qui contiennent plus de 65535 caractres. TEXT ne prend pas en compte la casse contrairement BLOB.
Ces deux derniers types ne sont pas conformes la norme ANSI. Posez-vous toujours la question, avant de les utiliser, de savoir si vous avez rellement besoin de disposer de chanes de plus de 65535 caractres (soit l'quivalent de 40 pages standards).
1.3 Dates
Les dates de type DATE sont stockes selon le format AAAA-MM-JJ. Le type TIME stocke les informations d'heure de la manire suivante: HH:MM:SS. Quant au format DATETIME, il permet de combiner les deux prcdents avec un format du type: AAAA-MM-JJ HH:MM:SS. Seul le type DATE est conforme au standard SQL.
Les types ENUM et SET sont spcifiques MySQL. Ils permettent d'numrer la liste des valeurs disponibles pour un champ (jusqu' 65535 valeurs). SET (contrairement ENUM) autorise le choix de plusieurs valeurs la fois au sein de la liste. Ces types peuvent rendre service pour des champs admettant peu d'options dont vous tes sr qu'elles n'volueront pas. Par exemple: sexe ENUM ("Femme", "Homme") Peu de chance qu'une troisime option se prsente avant un certain temps.
Exemple:
CREATE TABLE batiment (id INTEGER NOT NULL, nom VARCHAR (100) NOT NULL, annee INTEGER DEFAULT 1900, adresse VARCHAR (100), architecte VARCHAR (100) NOT NULL);
La syntaxe est assez simple comprendre: il faut donner un nom chaque champs, le typer, et prciser un certains nombre de contraintes s'il y a lieu.
Le premier exemple indique que le champ nom doit tre rempli. Le second exemple indique que dans le cas o aucune valeur ne serait insre dans le champ nom, celui-ci vaudrait 'toto' (a nous fait une belle jambe hein!).
ou encore
nomChamp PRIMARY KEY
MySQL fournit une option AUTO_INCREMENT qui lui est spcifique (non ANSI). Elle permet d'incrmenter automatiquement l'id dclar comme clef primaire chaque insertion.
Pour dclarer une clef trangre, c'est--dire qu'un champ de votre table fait rfrence un champ d'une autre table, on utilise la syntaxe: FOREIGN KEY (nomChamp) REFERENCES nomTable(nomChamp) Exemple:
CREATE TABLE batiment (id INTEGER NOT NULL AUTO_INCREMENT, nom VARCHAR (100) NOT NULL, annee INTEGER DEFAULT 1900, adresse VARCHAR (100), id_Architecte INTEGER NOT NULL, PRIMARY KEY (id), FOREIGN KEY (id_architecte) REFERENCES architecte(id)) ENGINE=InnoDB;
ou id_Architecte rfrence la clef primaire de la table architecte qui pourrait tre dfinie ainsi:
CREATE TABLE architecte (id INTEGER NOT NULL, nom VARCHAR (100) NOT NULL, prenom VARCHAR (100), anneeNais INTEGER, anneeMort INTEGER) ENGINE=InnoDB;
MySQL indexe automatiquement les clefs primaires et trangres. Les requtes qui se basent sur elles sont donc trs rapides. Dans cet exemple, on dfinit une relation de un plusieurs entre les tables architecte et batiment: un architecte peut avoir construit 0 ou plusieurs btiments et tout btiment a un architecte (ce qui relve dj de l'interprtation puisqu'un btiment pourrait ne pas avoir d'architecte connu). La dfinition d'une clef trangre permet en principe d'viter toute modification affectant un lien entre deux tables dans le cas d'une insertion, d'une modification ou d'une suppression (la requte est alors rejete). Mais cela n'est effectif que si votre table utilise un moteur qui respecte l'intgrit rfrentielle (InnoDB). Une mise jour ou une suppression peut alors tre rpercute en cascade sur les tables lies l'aide des vnements ON UPDATE et ON DELETE. La rpercussion consiste mettre la clef trangre NULL (SET NULL) ou rpercuter la mme opration qu' l'enregistrement auquel il est fait rfrence (CASCADE). Exemple:
CREATE TABLE batiment (id INTEGER NOT NULL AUTO_INCREMENT, nom VARCHAR (100) NOT NULL, annee INTEGER DEFAULT 1900, adresse VARCHAR (100), id_Architecte INTEGER NOT NULL, PRIMARY KEY (id), FOREIGN KEY (id_architecte) REFERENCES architecte(id) ON DELETE SET NULL); ON DELETE SET NULL permet lors de la suppression d'un architecte auquel il est fait rfrence via id_architecte de mettre le contenu de ce champ id_architecte NULL (mais on pourrait faire la mme chose lors d'une mise jour avec ON UPDATE). La syntaxe ON DELETE CASCADE sur la clef trangre entranerait la suppression de l'enregistrement batiment
correspondant lors de la destruction d'un architecte (ce qui en l'occurrence serait dangereux: si je supprime un architecte qui a fait 15 btiments, ces 15 btiments disparatraient en cascade!).
UNIQUE (annee, adresse) En revanche, si notre application a une vise historique, il faudra prendre en compte que deux btiments de notre base ont pu au fil des sicles avoir t construits la mme adresse. Autrement dit une contrainte d'unicit portant sur la combinaison de ces deux champs invaliderait le fonctionnement de notre application.
Le champ annee ne peut alors comprendre que des valeurs comprises entre 1900 et 1999 (ce qui peut avoir son intrt dans le cadre d'une base consacre au XXe sicle). Et le champ adresse ne peut alors comprendre que une des 3 adresses mentionnes (ce qui est videment excessivement restrictif). Attention: la contrainte CHECK est accept par MySQL mais ne donne lieu aucun contrle. MySQL dispose de types qui permettent le contrle: ENUM et SET (qui ne font pas partie de la norme SQL). Exemple: adresse ENUM ('rue Vandrezanne', 'boulevard Auriol', 'rue de Tolbiac') Si la valeur insre dans le champs adresse n'appartient pas l'ensemble dfini par ENUM, MySQL affecte une chane vide. Ce type de procd manque cependant de souplesse. Pour bien faire, il faudrait crer une nouvelle table rue contenant tous les noms de rues et lier cette table la table batiment l'aide d'une clef trangre id_rue. Cela permettrait d'uniformiser l'orthographe des noms de rue et de faciliter l'ajout de nouveaux noms. Ainsi on pourrait imaginer une table rue ayant la structure suivante: #type est l pour distinguer les 'rue de', 'rue de la', 'rue de l\'' #et permettre des requtes rapides sur le champ 'nom' dont l'ordre alphabtique est important pour l'utilisateur
CREATE TABLE rue (id INTEGER NOT NULL AUTO_INCREMENT, type VARCHAR (100) NOT NULL, nom VARCHAR (200) NOT NULL);
ou UNIQUE [INDEX] [nomIndex] (nomChamp,...) ou [CONSTRAINT contrainte] FOREIGN KEY nomIndex (nomChamp,...) [rfrences] ou CHECK (valeurs);
optionSelect:
[IGNORE|REPLACE] SELECT ... (requte SQL)
rfrences:
REFERENCES nomTable(nomChamp) [ON DELETE optionRf] [ON UPDATE optionRf]
optRf: CASCADE|SET NULL|SET DEFAULT L'option TEMPORARY indique que la table est cre pour la connexion courante. L'option IF NOT EXISTS est utile lorsque vous stockez de nombreuses requtes de cration de table dans un fichier externe. Cela vite de supprimer ou remplacer de manire intempestive des tables qui existent dj lorsque vous lancez votre fichier. La commande INDEX permet de crer un index sur un ou une combinaison de champs.
En revanche les contraintes de clef primaire et trangre ne sont pas reproduites. Mais on peut procder de manire plus slective en prcisant les champs que l'on veut copier. Exemple:
CREATE TABLE copie_batiment AS SELECT nom FROM batiment;
Dans ce cas on copie dans la nouvelle table copie_batiment uniquement le champ nom de la table batiment. On peut pousser encore plus loin et prciser sur quel critre se fait la copie: Exemple:
CREATE TABLE copie_batiment (nv_nom) AS SELECT nom FROM batiment WHERE nom LIKE 'L%';
Dans ce cas on copie dans la nouvelle table copie_batiment uniquement le champ nom des batiments dont le nom commence par 'L'.
Pour ajouter une colonne, on utilise le mot-clef ADD suivi du nom et du type de la colonne:
ALTER TABLE batiment ADD no VARCHAR(100);
On ajoute un champ no la table batiment. On peut galement modifier le type d'un champ existant avec MODIFY:
ALTER TABLE batiment MODIFY no VARCHAR(200);
Attention: MySQL se charge de faire la conversion de l'ancien vers le nouveau type de donne, pour le meilleur et pour le pire. Il existe des tables de conversion mais en la matire ne faites jamais confiance votre mmoire: faites toujours un test sur une copie de votre table avant de massacrer l'original. Enfin vous pouvez supprimer un champ l'aide de la commande DROP.
ALTER TABLE batiment DROP id;
Attention: la suppression d'un champ entraine la perte de toutes les donnes qu'il contient.
altrations:
ADD [COLUMN] commandeCration [FIRST|AFTER nomChamp] ou ADD INDEX [nomIndex] (nomChamp,...) ou ADD PRIMARY KEY (nomChamp,...) ou ADD UNIQUE [nomIndex] (nomChamp,...) ou ALTER [COLUMN] nomChamp ou CHANGE [COLUMN] ancienNomChamp commandeCration ou MODIFY [COLUMN] commandeCration ou DROP [COLUMN] nomChamp ou DROP PRIMARY KEY ou DROP INDEX nomIndex ou RENAME [AS|TO] nomTable
4. Requtes MySQL
Les exemples qui suivent portent sur une base de donne de gestion de syndic constitue de 4 tables selon le schma suivant:
Cette base rpond aux problmatiques suivantes: - un appartement peut tre possd en indivision: c'est--dire qu'il peut tre la proprit de plusieurs personnes, chacune de ces personnes possdant une quote-part de l'appartement. - une personne peut possder plusieurs appartements - un appartement a un locataire et un seul (celui qui paye le loyer) - il peut y avoir plusieurs appartements par immeuble La relation entre la table PERSONNE et la table APPARTEMENT peut tre de deux natures: - soit une relation qui indique la possession et qui passe par la table intermdiaire POSSEDE qui rsulte d'une relation de plusieurs plusieurs (un appartement peut tre possd par plusieurs personnes et une personne peut possder plusieurs appartements), - soit une relation de location La relation entre la table APPARTEMENT et la table IMMEUBLE permet d'indiquer dans quel immeuble se trouve chaque appartement (en vitant la redondance d'information). Vous pouvez charger ces 4 tables et quelques donnes l'aide du fichier suivant: immeuble.sql. De manire gnrale, lorsque vous faites des requtes sur une base de donne, il est bon d'avoir sous les yeux le schma de cette base. N'hsitez pas vous crayonner le schma de la base de gestion de syndic sur une feuille de papier pour suivre correctement les exemples.
Mais on aurait galement pu utiliser la syntaxe suivante o l'toile est une syntaxe raccourcie qui dsigne l'ensemble des champs:
SELECT * FROM personne
Ne vous affolez pas si la syntaxe des requtes vous parait complexe: dans cette partie il s'agit de saisir la structure gnrale des requtes, nous revenons sur le dtail de la syntaxe dans les chapitres suivants (4.2 et 4.3). Notez que la machine ne travaille pas du tout dans l'ordre nonc. Elle commence par dterminer les sources mentionnes par FROM, puis elle slectionne les donnes conformes aux conditions nonces dans le WHERE et s'occupe finalement d'afficher les champs recenss dans le SELECT. Concrtement, c'est comme si vos donnes passaient au travers de trois tamis avant d'tre affiches: - le premier tamis consiste slectionner les tables dont vous avez besoin (et vous avez rarement besoin de toutes vos tables) - le second tamis slectionne les donnes dans ces tables selon certains critres logiques - le troisime tamis slectionne les donnes afficher dans le rsultat final
Si on a souvent recours une table calcule, il peut tre judicieux de crer ce qu'on appelle une vue (disponible partir de MySQL 5.0).
CREATE VIEW Koudalou AS SELECT nom, adresse FROM immeuble WHERE id=1; SELECT nom, adresse FROM Koudalou;
Enfin on peut vouloir slectionner le contenu de plusieurs tables. Par dfaut, la requte qui suit renvoie toutes les associations possibles entre les lignes de la table immeuble et les lignes de la table appartement. C'est ce qu'on appelle le produit cartsien de deux tables et c'est rarement tel quel que vous en aurez besoin.
SELECT * FROM immeuble, appartement;
La plupart du temps vous chercherez raliser des jointures, c'est--dire un produit cartsien restreint par une condition qui peut s'crire de la manire suivante:
SELECT * FROM immeuble JOIN appartement ON (immeuble.id=appartement.id_immeuble);
qui ne renvoie que les appartements rfrencs dans la table immeuble. Pas de panique devant cette syntaxe que vous n'avez probablement jamais vu: il faudra vous y habituer, SQL permet souvent d'crire une mme opration de plusieurs faons (dans le cas prsent vous auriez prfr un WHERE, a tombe bien, on y vient justement).
Les tests les plus traditionnels sont possibles: Afficher les appartements de plus de 50 m2:
SELECT * FROM appartement WHERE surface > 50;
Afficher les appartements de plus de 50 m2 et situs au-dessus du 3me tage ou les appartements situs dans l'immeuble n2:
SELECT * FROM appartement WHERE (surface > 50 AND etage > 3) OR id_immeuble=2;
Les requtes imbriques comme cette dernire sont viter. Il y a en gnral des solutions plus lgantes et surtout plus lisibles.
La documentation MySL prcise toutes les fonctions et oprateurs disponibles. Vous pouvez d'ailleurs utiliser MySQL uniquement pour afficher le rsultat d'une opration en omettant la clause FROM comme dans l'exemple qui suit:
SELECT 2 + 2; SELECT ROUND(1.235,2);
Attention: il ne doit pas y avoir d'espace entre la fonction MySQL et la premire parenthse ouvrante qui suit.
Construction d'expression
Si on indique explicitement les champs sans utiliser l'toile '*', ceux-ci dterminent le nombre de champs afficher. Par dfaut le nom de chaque colonne est celui du champ mais on peut modifier ce nom l'aide de l'alias AS. La fonction MySQL CONCAT() vous permet galement de prsenter plusieurs champs au sein d'une seule colonne comme le montre l'exemple suivant:
SELECT CONCAT(nom, ' (', prenom, ')') AS 'Nom et prnom' FROM personne;
L'exemple prcdent retourne un rsultat NULL. Pour viter ce type d'affichage, MySQL fournit la fonction IFNULL() qui permet d'attribuer une valeur par dfaut aux valeurs NULL comme dans l'exemple suivant:
SELECT IFNULL(prenom, 'rien') AS 'Prenom' FROM personne;
Vous pouvez galement effectuer des calculs dans la clause SELECT comme l'exemple suivant qui calcule le loyer de chaque appartement sur la base de 18 euros du mtre carr.
SELECT id AS 'Appartement', CONCAT(surface*18, ' euros') AS 'Loyer' FROM appartement;
La clause WHERE
La clause WHERE utilise les oprateurs de comparaison standards savoir: <, <=, =, !=, >=, > ainsi que les oprateurs logiques: AND, OR, NOT et IN qui teste l'appartenance un ensemble comme dans l'exemple qui suit:
SELECT * FROM personne WHERE profession='Acteur' OR profession='Rentier';
Pour les comparaisons portant sur des chanes de caractre, vous disposez de l'oprateur LIKE, qui fait partie de la norme SQL et qui fonctionne avec le '%' (qui remplace n'importe quelle chaine) et le '_' (qui remplace n'importe quel caractre).
SELECT * FROM personne WHERE nom LIKE '%m_t';
MySQL fournit galement l'oprateur REGEXEP qui permet d'utiliser les expressions rgulires. Attention: REGEXP n'est pas un standard SQL.
SELECT * FROM personne WHERE nom REGEXP 'Ramut';
Attention: la comparaison de chane, par dfaut, ne tient pas compte de la casse, sauf si vous le prcisez avec l'oprateur BINARY.
SELECT * FROM personne WHERE nom LIKE BINARY 'r%';
ne retourne rien puisque la premire lettre des noms est toujours en majuscule.
Rsultat des courses, si on veut slectionner des champs qui ont une valeur nulle, on recoure au test IS NULL:
SELECT * FROM personne WHERE prenom LIKE '%' OR prenom IS NULL;
Tris
Lorsque vous faites une requte globale, MySQL ne vrifie pas si certaines informations sont redondantes:
SELECT surface FROM appartement;
Mfiez-vous du DISTINCT dans le cas de tables importantes: cette fonction utilise beaucoup de ressource et peut ralentir notablement vos requtes.
MySQL permet galement de trier par ordre croissant (ASC, tri par dfaut) ou dcroissant (DESC) les rsultats retourns pour un champ l'aide de la syntaxe ORDER BY qui vient se placer la fin de la requte: SELECT * FROM appartement ORDER BY surface, etage;
ou
La clause LIMIT
Attention, la clause LIMIT, qui permet de spcifier le nombre de lignes retournes par la requte est une spcificit MySQL que vous ne retrouverez pas chez tous les autres SGBD.
LIMIT premiereLigne, nbLigne
ou
LIMIT nbLigne [OFFSET premiereLigne]
Nous avons pris l'exemple du cas le plus gnral: celui o la jointure se fait entre clef primaire et clef trangre. Dans cet exemple, il tait ncessaire de prciser de quelles tables relevaient les champs id homonymes. Mais d'autres cas peuvent se prsenter. Si par exemple vous vouliez connatre les appartements d'un mme immeuble qui ont une mme surface, vous seriez amen comparer les enregistrements de la table appartement avec eux-mmes. Vous tes alors conduit crer deux alias de la mme table pour rsoudre le problme:
SELECT a1.id, a1.surface, a1.etage, a2.id, a2.surface, a2.etage FROM appartement a1, appartement a2 WHERE a1.id_immeuble=a2.id_immeuble AND a1.surface=a2.surface AND a1.id!=a2.id;
Essayez de rsoudre la srie d'exercices qui suit sur les jointures. Faites-l et refates-l jusqu' ce que le raisonnement qui conduit au rsultat soit fluide pour vous. N'hsitez pas vous faire un petit schma sur papier de l'organisation de vos tables: Qui habite un appartement de plus de 200m2?
SELECT nom, prenom FROM personne, appartement a WHERE surface > 200 AND id_appartement=a.id;
SELECT i.nom, no, etage, surface FROM personne p, possede p2, appartement a, immeuble i WHERE p.id=p2.id_personne /*Jointure personne possede*/ AND p2.id_appartement = a.id /*Jointure possede appartement*/ AND a.id_immeuble=i.id /*Jointure appartement immeuble*/ AND p.nom='Black' AND p.prenom='Alice';
Attention: il faut toujours donner un alias une table calcule (mme si on ne s'en sert pas). Qui habite un appartement de plus de 200m2?
SELECT nom, prenom FROM personne AS p, (SELECT id_appartement FROM appartement WHERE surface>200) AS a WHERE p.id=a.id_appartement;
Quoique cela fonctionne, MySQL dconseille cette pratique qui consiste inclure une condition de slection dans la jointure. En thorie la jointure est l uniquement pour faire les comparaisons de clefs.
Dans ce cas je dtermine une table directrice (celle de gauche par convention) dont toutes les lignes, mme celles qui ne trouvent pas de correspondance dans l'autre table seront prises en compte. La table de droite est dite optionnelle. Afficher tous les appartements avec leur locataire ventuel s'crit donc de la manire suivante:
SELECT id_immeuble, no, etage, surface, nom, prenom FROM appartement a LEFT OUTER JOIN personne p ON (p.id_appartement=a.id);
retourne une liste comprenant les noms des immeubles et des personnes qui sont dans la base. Mais pourquoi faire?
4.4 Agrgation
On appelle agrgats des regroupements de lignes en fonction de certains champs. Ce regroupement est spcifi par la clause GROUP BY. Si on ne mentionne aucun groupe, SQL considre par dfaut qu'il s'agit de la table tout entire (c'est un groupe sommaire mais c'est un groupe). Les fonctions d'agrgation s'appliquent alors la table tout entire comme le montre l'exemple suivant:
SELECT COUNT(*), COUNT(prenom), count(nom) FROM personne;
La clause GROUP BY permet de spcifier sur quel champ doit se faire le regroupement. Ds lors, tous les enregistrements possdant la mme valeur pour ce champ sont regroups. Ainsi, on peut obtenir la somme des quote-parts pour chaque appartement:
SELECT id_appartement, SUM(quote) FROM possede GROUP BY id_appartement;
Dans un premier temps, MySQL regroupe les enregistrements qui ont le mme id_appartement dans la table possede. Puis pour chacun de ces regroupements on affiche l'id_appartement et la somme des quote parts des diffrents enregistrements regroups. Si vous avez bien saisi le principe, vous devez comprendre que la requte prcdente doit retourner 100 pour chaque appartement (puisqu'il s'agit de la somme des parts de chacun des propritaires de l'appartement). Il est possible galement d'exprimer des conditions sur ces valeurs agrges pour ne conserver qu'un ou plusieurs des groupes constitus. Ces conditions portent sur des groupes de lignes et non sur des lignes prises une une, c'est pourquoi on emploie ici la clause HAVING plutt que WHERE. Par exemple on peut slctionner les appartements pour lesquels on connat au moins deux copropritaires:
SELECT id_appartement, COUNT(*) FROM possede GROUP BY id_appartement HAVING COUNT(*) >=2;
Ici la clause HAVING porte sur le rsultat de la fonction d'agrgation GROUP BY. On peut ainsi calculer la surface possde par chaque propritaire dans l'immeuble 1 en fonction de la quote-part qu'ils ont dans chaque appartement possd. On regroupe les appartements par propritaire et on trie sur la surface possde:
SELECT nom, prenom, SUM(quote*surface/100) AS 'Surface possedee' FROM personne p1, possede p2, appartement a WHERE id_immeuble=1 AND p1.id=p2.id_personne AND a.id=p2.id_appartement GROUP BY p1.id ORDER BY 'Surface possedee' DESC;
Vous remarquez au passage un autre usage possible d'un alias portant sur un champ calcul.
Si l'insertion ne concerne que certains champs, il faut alors les numrer comme dans l'exemple suivant: INSERT INTO immeuble(id, nom, adresse) VALUES (1, 'Koudalou', '3, rue Blanche');
4.4.2 Destruction
La destruction s'effectue avec clause DELETE et selon la syntaxe suivante:
DELETE FROM table WHERE condition;
4.4.3 Modification
La modification s'effectue avec la clause UPDATE et selon la syntaxe suivante:
UPDATE table SET A1=v1, A2=v2, ... WHERE condition;
ou An sont les noms de champ et vn les nouvelles valeurs. Attention: tout ce qui suit n'est disponible qu'avec la version 5 de Mysql.
Une vue se construit et s'utilise comme une table ceci prs qu'elle est une table dynamique puisqu'elle repose sur d'autres tables. Sa syntaxe n'a donc rien de surprenant par rapport ce que vous avez dj vu:
CREATE [OR REPLACE] VIEW nomVue [(listeAttibuts)] AS requete [WITH CHECK OPTION]
Pour crer une vue affichant le nom, l'adresse et le nombre d'appartements grs dans l'immeuble Koudalou, on peut crire:
CREATE OR REPLACE VIEW koudalou AS SELECT nom, adresse, COUNT(*) AS nbAppartement FROM immeuble i, appartement a WHERE i.id=a.id_immeuble AND i.id=1 GROUP BY i.id;
Dsormais cette vue apparait au mme titre que les tables de votre bases lorsque vous faites un SHOW TABLES;. La seule limite des vues par rapport aux tables est qu'on ne peut insrer des donnes que de manire extrmement limit: les vues qui peuvent servir l'insertion ne doivent porter que sur une table o les colonnes non rfrences dans la vue doivent pouvoir tre mises NULL ou disposer d'une valeur par dfaut. Autrement dit ces vues d'insertion n'ont d'utilit que sur le plan de la scurit (si vous dcidez de limiter l'accs votre base aux vues que vous avez cres).