• Aucun résultat trouvé

Sommaire 27 Historique des changements MySQL

1.8 Quels standards respecte MySQL?

1.8.5 Différences entre MySQL et le standard SQL−

Nous tâchons de rendre le serveur MySQL compatible avec le standard ANSI SQL, et le standard ODBC SQL, mais dans certains cas, MySQL se comporte différemment.

Pour les colonnes de type VARCHAR

, les espaces terminaux sont supprimés lors du stockage de la valeur. Erreurs connues et manques de MySQL .

Dans certains cas, les colonnes CHAR

sont transformées automatiquement en colonnes VARCHAR

. Changement de type de colonne automatique .

Les droits d'un utilisateur sur une table ne sont pas supprimés si la table est détruite. Vous devez explicitement utiliser la commande REVOKE

pour supprimer les droits d'un utilisateur sur une table. Syntaxe de GRANT

et REVOKE

.

1.8.5.1 Sous−requêtes

MySQL version 4.1 supporte les sous−requêtes et les tables dérivées (vues anonymes). Une ``sous−requête'' est une commande SELECT

imbriquée dans une autre commande. Une ``table dérivée'' (vues anonymes) est une sous−requête placée dans une clause FROM

d'une autre commande. Syntaxe des sous−requêtes .

Pour les versions de MySQL antérieure à la 4.1, la plupart des sous−requêtes peuvent être réécrites avec des jointures et d'autres méthodes. Voyez Se passer des sous−requêtes pour des exemples d'illustration.

1.8.5.2 SELECT INTO TABLE

Le serveur MySQL ne supporte pas encore l'extension Oracle SQL : SELECT ... INTO TABLE ...

. A la place, le serveur MySQL supporte la syntaxe ANSI SQL INSERT INTO ... SELECT ...

, qui revient au même. Syntaxe de INSERT ... SELECT

.

INSERT INTO tblTemp2 (fldID) SELECT tblTemp1.fldOrder_ID

FROM tblTemp1 WHERE tblTemp1.fldOrder_ID > 100;

Alternativement, vous pouvez utiliser SELECT INTO OUTFILE...

et CREATE TABLE ... SELECT

.Depuis la version 5.0, MySQL supporte SELECT ... INTO

avec les variables serveur. La même syntaxe peut aussi être utilisée dans les procédures stockées, en utilisant les curseurs et les variables locales. Commande SELECT ... INTO

.

1.8.5.3 Transactions et opérations atomiques

Le serveur MySQL (version 3.23 MySQL−max

et toutes les versions 4.0 et plus récent) supporte les transactions avec les gestionnaires de tables InnoDB

et BDB

. InnoDB

dispose aussi de la compatibilité ACID totale . Types de tables MySQL .

Toutefois, les tables non transactionnelles de MySQL telles que MyISAM

exploitent un autre concept pour assurer l'intégrité des données, appelé `` opérations atomiques

''. Les opérations atomiques

disposent d'une bien meilleure protection des données pour des performances également accrues. Comme MySQL supporte les deux méthodes, l'utilisateur est capable de choisir celle qui

correspond à ses besoins, suivant qu'il a besoin de vitesse ou de sécurité. Ce choix peut être fait table par table.

Comment exploiter les capacités de MySQL pour protéger l'intégrité des données, et comment ces fonctionnalités se comparent elles avec les méthodes transactionnelles ?

En mode transactionnel, si votre application a été écrite en dépendant de l'appel de ROLLBACK

au lieu de COMMIT

dans les situations critiques, les transactions sont plus pratiques. Les transactions s'assurent que les modifications non achevées ou les activités corrosives ne sont pas archivées dans la base. Le serveur a l'opportunité d'annuler automatiquement l'opération, et votre base de données est sauve.

Le serveur MySQL, dans la plupart des cas, vous permet de résoudre les problèmes potentiels en incluant de simples vérifications avant les modifications, et en exécutant des scripts simples pour vérifier l'intégrité de vos bases de données, ainsi que les incohérences, et pour réparer automatiquement les problèmes, ou encore vous alerter si une erreur est identifiée. Notez qu'en utilisant simplement le log de MySQL, ou en utilisant un log supplémentaire, vous pouvez normalement réparer à la perfection toutes les tables, sans aucune perte de données.

Souvent, les modifications de données transactionnelles fatales peuvent être réécrites de manière atomique. En général, tous les problèmes d'intégrité que les transactions résolvent peuvent être corrigés avec la commande LOCK TABLES

ou des modifications atomiques, qui assurent que vous n'aurez jamais d'annulation automatique de la base, ce qui est un problème commun des bases transactionnelles.

Même un système transactionnel peut perdre des données si le serveur s'arrête. La

différence entre les systèmes repose alors dans ce petit laps de temps où ils peuvent perdre des données. Aucun système n'est sécurisé à 100%, mais simplement ``suffisamment sécurisé''. Même Oracle, réputé pour être la plus sûre des bases de données

transactionnelles, est montré du doigt pour perdre des données dans ces situations.Pour être tranquille avec MySQL, que vous utilisiez les tables transactionnelles ou pas, vous n'avez besoin que de sauvegardes et de logs de modifications. Avec ces deux outils, vous pourrez vous protéger de toutes les situations que vous pourriez rencontrer avec d'autres bases de données transactionnelles. De toute manière, il est bon d'avoir des sauvegardes, indépendamment de la base que vous utilisez.

La méthode transactionnelle a ses avantages et ses inconvénients. De nombreux utilisateurs et développeurs d'applications dépendent de la facilité de pallier un problème lorsqu'une annulation semble nécessaire ou presque. Cependant, même si vous êtes néophyte des opérations

atomiques, ou plus familier avec les transactions, prenez en considération le gain de vitesse que les tables non transactionnelles offrent. Ces gains vont de 3 a 5 fois la vitesse des tables

transactionnelles les plus rapides et les mieux optimisées.

Dans des situations où l'intégrité est de la plus grande importance, le serveur MySQL assure une intégrité du niveau des transactions, ou encore mieux avec les tables non transactionnelles. Si vous verrouillez les tables avec LOCK TABLES

, toutes les modifications seront bloquées jusqu'à ce que la vérification d'intégrité soit faite (à comparer avec un verrou en écriture), les lectures et insertions sont toujours possibles. Les nouvelles lignes ne seront pas accessibles en lecture tant que le verrou n'aura pas été levé. Avec INSERT DELAYED

, vous pouvez faire attendre les insertions dans une pile, jusqu'à ce que les verrous soit levés, sans que le client n'attende cette levée de verrou. Syntaxe de

INSERT DELAYED

.

``Atomique'', avec le sens que nous lui donnons, n'a rien de magique. Ce terme signifie simplement que vous pouvez être certain que lorsque vous modifiez des données dans une table, aucun autre utilisateur ne peut interférer avec votre opération, et qu'il n'y aura pas d'annulation automatique (ce qui pourrait arriver avec des tables transactionnelles si nous ne sommes pas trop soigneux). Le serveur MySQL garantit aussi qu'il n'y aura pas de lectures erronées.

Voici quelques techniques pour travailler avec des tables non transactionnelles :

Les boucles qui requièrent les transactions peuvent normalement être implémentées avec la commande LOCK TABLES

, et vous n'avez nul besoin de curseur lorsque vous modifiez des lignes à la volée.

Pour éviter d'utiliser l'annulation ROLLBACK

, vous pouvez adopter la stratégie suivante : Utilisez la commande LOCK TABLES ...

pour verrouiller toutes les tables que vous voulez utiliser.

Testez vos conditions.

Modifiez si tout est correct.

Utilisez UNLOCK TABLES

pour libérer vos tables.

Ceci est probablement une méthode bien plus rapide que ne le proposent les transactions, avec des annulations ROLLBACK

possibles mais pas certaines. La seule situation que ce cas ne prend pas en compte est l'interruption du processus au milieu d'une mise à jour. Dans ce cas, tous les verrous seront levés, mais certaines modifications peuvent ne pas avoir été exécutées.

Vous pouvez aussi utiliser des fonctions pour modifier des lignes en une seule opération. Vous pouvez créer une application très efficace en utilisant cette technique :

Modifiez les champs par rapport à leur valeur actuelle.

Modifiez uniquement les champs que vous avez réellement changé.

Par exemple, lorsque nous modifions les données d'un client, nous ne modifions que les données du client qui ont changé et nous vérifions uniquement si les données modifiées ou les données qui en dépendent ont changé comparativement aux données originales. Les tests sur les données modifiées sont faits avec la clause WHERE

dans la commande UPDATE

. Si la ligne a été modifiée, nous indiquons au client : "Some of the data you have changed has been changed by another user"

. En français : "certaines données que vous voulez modifier ont été modifiées par un autre utilisateur". Puis nous affichons l'ancienne ligne et la nouvelle ligne, pour laisser l'utilisateur décider quelle version il veut utiliser.

Cela nous conduit à un résultat proche du verrouillage de ligne, mais en fait, c'est bien mieux, car nous ne modifions que les colonnes qui en ont besoin, en utilisant des valeurs relatives. Cela signifie qu'une commande UPDATE

typique ressemble à ceci :

UPDATE tablename SET pay_back=pay_back+'relative change'; UPDATE customer SET customer_date='current_date', address='new address', phone='new phone', dette=dette+'emprunt' WHERE

customer_id=id AND address='old address' AND phone='old phone';

Comme vous pouvez le voir, c'est très efficace, et fonctionne même si un autre client a modifié la valeur pay_back

ou dette

.

Dans de nombreuses situations, les utilisateurs ont souhaité les commandes ROLLBACK

et/ou LOCK TABLES

afin de gérer des identifiant uniques pour certaines tables. Ils peuvent être gérés bien plus efficacement en utilisant une colonne de type AUTO_INCREMENT

, en corrélation avec la fonction LAST_INSERT_ID()

ou la fonction C mysql_insert_id()

. Fonctions d'informations . mysql_insert_id()

. Vous pouvez éviter le verrouillage de ligne. Certaines situations le requièrent vraiment, mais elles sont rares. Les tables InnoDB

supportent le verrouillage de ligne. Avec les tables MyISAM

,

vous pouvez utiliser une colonne de type sémaphore, et faire ceci :

UPDATE tbl_name SET row_flag=1 WHERE id=ID;

MySQL retournera 1 pour le nombre de lignes affectées si la ligne a été trouvée, car row_flag

ne vaut pas déjà 1 dans la ligne originale.

Vous pouvez comprendre la requête ci−dessus comme si le serveur MySQL avait utilisé la commande suivante :

UPDATE tbl_name SET row_flag=1 WHERE id=ID AND row_flag <> 1;

1.8.5.4 Procédures stockées et triggers

Les procédures stockées sont implémentées en version 5.0. Procédures stockées et fonctions . Un trigger est une procédure stockée qui est activée lorsqu'un événement particulier survient. Par exemple, vous pouvez installer une procédure stockée qui est déclenchée dès qu'une ligne est effacée dans une table d'achat, pour que le client soit automatiquement effacé si tous ses achats sont effacés.

1.8.5.5 Les clés étrangères

En MySQL version 3.23.44 et plus récentes, les tables InnoDB

supportent les vérifications d'intégrité référentielles. Le moteur de tables InnoDB

. Pour les autres types de tables, le serveur mySQL accepte la syntaxe FOREIGN KEY

dans la commande CREATE TABLE

, mais ne la prend pas en compte. Pour les autres moteurs de stockage que InnoDB

, MySQL analyse la clause FOREIGN KEY

de la commande

CREATE TABLE

, mais ne l'utilise pas et ne la stocke pas. Dans le futur, l'implémentation va stocker cette information dans le fichier de spécifications de tables, pour qu'elle puisse être lue par mysqldump

et ODBC. Ultérieurement, les contraintes de clé étrangères seront incluses dans les tables MyISAM

. Voici des avantages aux contraintes de clés étrangères :

En supposant que les relations soient proprement conçues, les clés étrangères rendent plus difficile pour un programmeur d'insérer des valeurs incohérentes dans la base.

La vérification centralisée de contraintes par le serveur de base de données rend inutiles l'application de ces vérifications du coté de l'application. Cela élimine la possibilité que d'autres applications ne fassent pas les vérifications de la même façon que les autres.

L'utilisation des modifications et effacement en cascade simplifie le code du client.

Les règles de clés étrangères proprement conçues aident à la documentation des relations entre les tables.

Gardez bien en tête que ces avantages ont un coût supérieur pour le serveur de bases, qui doit effectuer les tests. Les vérifications supplémentaires affectent les performances, ce qui est parfois suffisamment rebutant pour des applications qui les éviteront. Certaines applications commerciales ont placé la logique de vérification dans l'application, pour cette raison.

MySQL donne aux développeurs de bases de données le choix de leur approche. Si vous n'avez pas besoin des clés étrangères, et que vous voulez éviter leur surcoût, vous pouvez choisir un autre type de table, comme MyISAM

. Par exemple, les tables MyISAM

sont extrêmement rapides pour les applications qui font essentiellement des opérations INSERT

et SELECT

, car elles peuvent être utilisées simultanément. Problèmes avec le verrouillage de tables .

Si vous décidez de ne pas tirer avantage des contraintes d'intégrité, vous devez garder en tête ces conseils :

En l'absence de vérification du coté du serveur, l'application doit se charger de ces

vérifications. Par exemple, elle doit s'assurer que les lignes sont insérées dans le bon ordre, et que les lignes ne sont pas orphelines. Il faut aussi pouvoir rattraper une erreur au milieu d'une opération multiple.

Si la clause ON DELETE

est la seule fonctionnalité nécessaire, notez que depuis MySQL version 4.0, vous pouvez utiliser des commandes DELETE

multi−tables pour effacer les lignes dans plusieurs tables en une seule commande. Syntaxe de DELETE

.

Un palliatif au manque de ON DELETE

est d'ajouter la commande DELETE

appropriée lorsque vous effacez des lignes dans une table qui dispose d'une clé étrangère,. EN pratique, c'est souvent plus rapide que d'utiliser les clés étrangères, et c'est plus portable.

Soyez conscient que l'utilisation des clés étrangères dans certaines circonstances peuvent conduire à des problèmes :

Les clés étrangères règlent des problèmes de cohérence, mais il est nécessaire de concevoir les contraintes correctement, pour éviter les contraintes circulaires, ou des cascades d'effacements incorrects.

Il n'est pas exceptionnel pour un administrateur de créer une topologie de relations qui rende difficile la restauration de bases à partir d'une sauvegarde. MySQL résout ce problème en vous permettant de désactiver temporairement les contraintes. Contraintes

FOREIGN KEY

. Depuis MySQL 4.1.1, mysqldump

génère un fichier d'export qui exploite cette possibilité de désactivation automatique à l'import.

Notez que les clés étrangères SQL sont utilisées pour assurer la cohérence des données, et non pas pour joindre des tables. Si vous voulez obtenir des résultats de tables multiples dans une commande SELECT

, vous devez le faire avec une jointure :

SELECT * FROM t1, t2 WHERE t1.id = t2.id;

Syntaxe de JOIN

. Utiliser les clefs étrangères .La syntaxe FOREIGN KEY

sans ON DELETE ...

est souvent utilisée par les applications ODBC pour produire automatiquement des clauses WHERE

.

1.8.5.6 Les vues

Il est prévu d'implémenter les vues dans la version 5.0 ou 5.1 du serveur MySQL.

Historiquement, MySQL a été utilisé dans des applications et sur les systèmes Web, où l'auteur de l'application a un contrôle complet sur le système de base de données. L'utilisation a évolué au cours du temps, et de nombreux utilisateurs pensent maintenant que c'est important.

Les vues anonymes ( tables dérivées , une sous−requête de la clause FROM

de la commande SELECT

) sont déjà disponibles en version 4.1.

Les vues sont la plupart du temps utiles pour donner accès aux utilisateurs à un ensemble de relations représentées par une table (en mode inaltérable). Beaucoup de bases de données SQL ne permettent pas de mettre à jour les lignes dans une vue, vous devez alors faire les mises à jour dans les tables séparées. Sécurité générale et accès à MySQL .

De nombreuses bases de permettent pas les modifications de vues, mais permettent les mises à jour dans des tables individuelles. Lors de la conception de notre système de vues, nous

envisageons le support complet de la règle ``numéro 6 de Codd'' (autant que possible en SQL) : toutes les vues qui sont théoriquement modifiables, et doivent l'être en pratique.

1.8.5.7 '−−' comme début de commentaire

Certaines bases de données SQL utilisent '−−'

comme début de commentaire. Le serveur MySQL utilise '#'

. Vous pouvez aussi utiliser la syntaxe du langage C /* ceci est un commentaire */

. Syntaxe des commentaires .

MySQL version 3.23.3 et plus récent supporte les commentaires de type '−−'

, si ce commentaire est suivi d'un espace. Ceci est dû au fait que ce type de commentaire a causé beaucoup de problèmes avec les requêtes générées automatiquement, qui contiennent du code tel que celui−ci, où nous insérons automatiquement la valeur du paiement dans la table !payment!

:

UPDATE tbl_name SET credit=credit−!payment!

Pensez à ce qui se passe lorsque la valeur de payment

est négative, comme −1

:

UPDATE account SET credit=credit−−1 credit−−1

est une expression légale en SQL mais −−

est interprété comme un commentaire et la fin de l'expression est ignorée. Le résultat est que la commande prend une signification complètement différente :

UPDATE account SET credit=credit

La commande ne produit aucun changement! Cela montre que l'utilisation des commentaires de type '−−'

peuvent avoir des conséquences graves.

En utilisant notre implémentation des commentaires avec le serveur MySQL version 3.23.3 et plus récent, 1−− ceci est un commentaire

ne pose pas ce type de problème.

Une autre fonctionnalité supplémentaire est que le client en ligne de commande mysql

supprime toutes les lignes qui commencent par '−−'

.

Les informations suivantes sont destinées aux utilisateurs de MySQL avec des versions antérieures à la version 3.23.3 :

Si vous avez un programme SQL dans un fichier texte qui contient des commentaires au format '−−'

, il est recommandé d'utiliser l'utilitaire replace

pour assurer la conversion en caractères '#'

:

shell> replace " −−" " #" < text−file−with−funny−comments.sql \ | mysql database

au lieu du classique :

shell> mysql database < text−file−with−funny−comments.sql

Vous pouvez aussi éditer le fichier de commande ``lui−même'' pour remplacer les commentaires '−−'

par des commentaires '#'

:

shell> replace " −−" " #" −− text−file−with−funny−comments.sql

Puis, rétablissez−les avec :

shell> replace " #" " −−" −− text−file−with−funny−comments.sql