FAQ MySQLConsultez toutes les FAQ
Nombre d'auteurs : 15, nombre de questions : 155, dernière mise à jour : 22 avril 2014 Ajouter une question
Cette FAQ a été conçue à partir des questions fréquemment posées sur le forum MySQL de Developpez.com. Elle ne prétend pas à être exhaustive et peut contenir des erreurs occasionnelles. Si vous relevez une coquille, n'hésitez pas à nous le faire savoir.
Pour participer à cette FAQ, veuillez envoyer vos réponses sur le forum.
- Est-ce que MySQL supporte les clés étrangères (intégrité référentielle) ?
- Est-ce que MySQL supporte les sous requêtes / requêtes imbriquées ?
- Est-ce que MySQL supporte les procédures stockées et triggers ?
- Dans quels langages peuvent être écrites les procédures stockées ?
- Est-ce que MySQL supporte les vues ?
- Est-ce que MySQL supporte les opérateurs EXCEPT, INTERSECT, UNION, MINUS ?
- Quels types de jointures sont supportés ?
- Comment pallier l'absence de requêtes imbriquées dans les versions < 4.1 ?
- J'ai une erreur de syntaxe SQL et pourtant ma requête est correcte selon la documentation. Comment faire ?
- Est-ce que NULL est égal à NULL ?
- MySQL fait-il la différence entre majuscules et minuscules ?
- MySQL gère-t-il le GROUP BY comme les autres SGBD ?
Cela dépend du moteur de stockage ; ainsi, InnoDB prend en charge les contraintes d'intégrité référentielle tandis que MyISAM ne le fait pas.
Attention : La syntaxe FOREIGN KEY sera acceptée quel que soit le moteur. Simplement, les contraintes seront ensuite appliquées si les deux tables sont en InnoDB et non appliquées si l'une des deux ne l'est pas.
Oui, à partir de la version 4.1.
Les procédures stockées et des triggers rudimentaires sont implémentés depuis la version 5.0.
Les procédures stockées de MySQL se conforment à la syntaxe SQL:2003 et pourraient dans l'avenir supporter des langages comme PL/SQL ou T-SQL.
De plus, un framework pour des procédures stockées externes est prévu ; il permettra l'utilisation de langages non-SQL comme le PHP.
Oui, également à partir de la 5.0.
Pour l'instant, seule l'UNION est gérée à partir de la version 4.0. Les autres peuvent souvent être remplacées par des sous-requêtes (NOT IN, etc.) et sont prévues « à moyen terme ».
- table, table
- table [CROSS] JOIN table
- table INNER JOIN table condition_jointure
- table STRAIGHT_JOIN table
- table LEFT [OUTER] JOIN table condition_jointure
- table LEFT [OUTER] JOIN table
- table NATURAL [LEFT [OUTER]] JOIN table
- table RIGHT [OUTER] JOIN table condition_jointure
- table RIGHT [OUTER] JOIN table
- table NATURAL [RIGHT [OUTER]] JOIN table
Attention à l'usage de: table1 JOIN table2 ON ... and table1 JOIN table2 USING ...
Actuellement cette syntaxe ne peut s'utiliser qu'avec LEFT JOIN.
- Avec une jointure pour remplacer une cause IN
Code sql : | Sélectionner tout |
SELECT * FROM table1 WHERE champ1 IN (SELECT champ1 FROM table2)
Code sql : | Sélectionner tout |
1 2 3 | SELECT DISTINCT table1.* FROM table1 INNER JOIN table2 ON table1.champ1=table2.champ1 |
- Avec une jointure externe pour remplacer une clause NOT IN.
Code sql : | Sélectionner tout |
SELECT * FROM table1 WHERE champ1 NOT IN (SELECT champ1 FROM table2)
Code sql : | Sélectionner tout |
1 2 3 | SELECT table1.* FROM table1 LEFT JOIN table2 ON table1.champ1=table2.champ1 WHERE table2.champ1 IS NULL |
- Avec des tables temporaires.
Pour les requêtes plus complexes, on crée une table temporaire où on insère les enregistrements qu'aurait normalement contenus la sous-requête. Puis on fait une jointure entre la table temporaire et la table d'origine.
Ex : pour chaque valeur de champ2, on veut le maximum de champ1 dans la table.
Code sql : | Sélectionner tout |
1 2 3 4 | SELECT * FROM table1 WHERE champ1 IN ( SELECT max(champ1) FROM table1 GROUP BY champ2 ) |
Code sql : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 | CREATE TEMPORARY TABLE table_temp ( Champ2 [type], Maximum [type] ); LOCK TABLES table1 READ; INSERT INTO table_temp SELECT champ2, MAX(champ1) FROM table1 GROUP BY champ2; SELECT table1.* FROM table1, table_temp WHERE table1.champ2=table_temp.champ2 AND table1.champ1=table_temp.maximum; UNLOCK TABLES; DROP TABLE table_temp; |
La plupart du temps, il s'agit de fonctionnalités non reconnues par les versions les plus anciennes (sous-requêtes, etc). Par conséquent, vérifiez que votre version de MySQL supporte bien l'opération que vous voulez effectuer.
Voir ci-dessus pour les fonctionnalités gérées par MySQL.
Supposons que vous ayez deux colonnes a et b, dont vous testez l'égalité :
Code sql : | Sélectionner tout |
1 2 | WHERE a = b |
Ce comportement, a priori surprenant, est logique si l'on considère que le NULL désigne l'inconnu. Autrement dit, si on ne connaît ni la valeur de a, ni celle de b, il est impossible de savoir si elles sont égales !
MySQL propose un opérateur spécifique, le NULL-safe equal to operator, qui s'écrit <=>.
Cette question appelle trois réponses :
- Les termes du langage SQL (SELECT, SUM, etc.) peuvent être écrits indifféremment en majuscules ou minuscules, comme le veut la norme SQL.
- Les noms d'objets de base de données (colonnes, bases, triggers...) peuvent également être écrits sans se soucier de la casse.
Toutefois, les tables sont une exception à cette règle : elles dépendent de la sensibilité à la casse dans les noms de fichiers de l'OS du serveur MySQL. Ainsi, si MySQL est installé sous Windows, matable et MaTable sont bien la même table, tandis que ce seront deux tables différentes si MySQL est installé sous Linux !
Pour limiter les surprises, l'installation standard de MySQL force tous les noms de table en minuscules avec l'option lower_case_table_names, activée par défaut (voir la documentation officielle). - Les données textuelles sont sensibles à la casse ou non selon leur collation.
Non, MySQL applique une optimisation spécifique qui constitue une "extension de la norme" et est donc en contradiction avec celle-ci.
Supposons par exemple que vous ayez une table Vendeurs (IDvendeur, Nom, Prenom) et une table Commandes (IDcomm, Montant, IDvendeur). Si vous souhaitez calculer le chiffre d'affaires de chaque vendeur, avec son nom et prénom, la requête normalisée serait celle-ci :
Code sql : | Sélectionner tout |
1 2 3 4 | SELECT V.IDvendeur, V.Nom, V.Prenom, SUM(C.Montant) AS CA FROM Vendeurs V INNER JOIN Commandes C ON V.IDvendeur = C.IDvendeur GROUP BY V.IDvendeur, V.Nom, V.Prenom |
Code sql : | Sélectionner tout |
1 2 3 4 | SELECT V.IDvendeur, V.Nom, V.Prenom, SUM(C.Montant) AS CA FROM Vendeurs V INNER JOIN Commandes C ON V.IDvendeur = C.IDvendeur GROUP BY V.IDvendeur |
Toutefois, MySQL permettra également d'écrire cette requête :
Code sql : | Sélectionner tout |
1 2 3 4 | SELECT V.Nom, V.Prenom, SUM(C.Montant) AS CA FROM Vendeurs V INNER JOIN Commandes C ON V.IDvendeur = C.IDvendeur GROUP BY V.Nom |
C'est pour éviter ce comportement que la norme impose de copier dans le GROUP BY toutes les colonnes non-agrégées du SELECT. MySQL permet de passer outre, à vos risques et périls.
Proposer une nouvelle réponse sur la FAQ
Ce n'est pas l'endroit pour poser des questions, allez plutôt sur le forum de la rubrique pour çaLes sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2024 Developpez Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.