Table des matières
SELECT
,
INSERT
, UPDATE
,
DELETE
CREATE
,
DROP
, ALTER
Ce chapitre décrit la syntaxe des commandes que MySQL supporte.
DELETE [LOW_PRIORITY] [QUICK] [IGNORE] FROM table_name [WHERE where_definition] [ORDER BY ...] [LIMIT row_count]
Syntaxe multi-tables :
DELETE [LOW_PRIORITY] [QUICK] [IGNORE] table_name[.*] [, table_name[.*] ...] FROM table-references [WHERE where_definition]
ou :
DELETE [LOW_PRIORITY] [QUICK] [IGNORE] FROM table_name[.*] [, table_name[.*] ...] USING table-references [WHERE where_definition]
DELETE
efface les enregistrements de
nom_de_table
qui satisfont la condition
donnée par clause_where
, et retourne le
nombre d'enregistrements effacés.
Si vous exécutez un DELETE
sans clause
WHERE
, tous les enregistrements sont
effacés. Si vous le faites en mode
AUTOCOMMIT
cela aura le même effet qu'un
TRUNCATE
. See Section 13.1.9, « Syntaxe de TRUNCATE
».
Avec MySQL 3.23, DELETE
sans clause
WHERE
retournera zéro comme nombre
d'enregistrements affectés.
Si vous voulez vraiment savoir combien d'enregistrements ont
été effacés quand vous videz une table, et que vous êtes
prêts à souffrir d'un léger ralentissement, vous pouvez
utiliser une requête DELETE
de ce genre :
mysql> DELETE FROM nom_de_table WHERE 1>0;
Notez que c'est plus lent que DELETE FROM
nom_de_table
sans clause WHERE
,
parce que cela efface un enregistrement à la fois.
Si vous effacez des lignes contenant la valeur maximum d'une
colonne AUTO_INCREMENT
, la valeur sera
réutilisée pour par une table ISAM
ou
BDB
, mais pas pour une table
MyISAM
ou InnoDB
. Si vous
effacez toutes les lignes dans une table avec une commande
DELETE FROM tbl_name
(avec une clause
WHERE
) avec le mode
AUTOCOMMIT
, la séquence redémarrer à zéro
pour tous les types de table sauf InnoDB
et,
depuis MySQL 4.0, MyISAM
. Il y a des
exceptions à ce comportement pour les tables
InnoDB
, qui sont présentées dans la section
Section 15.7.3, « Comment les colonnes AUTO_INCREMENT
fonctionnent avec
InnoDB
».
Pour les tables MyISAM
et
BDB
, vous pouvez spécifier une autre colonne
AUTO_INCREMENT
dans une clé multi-colonnes.
Dans ce cas, la réutilisation des clés à partir de la fin de
la séquence se fait aussi pour les tables
MyISAM
. See
Section 3.6.9, « Utiliser AUTO_INCREMENT
».
La commande DELETE
supporte les clauses
suivantes :
Si vous spécifiez le mot clé
LOW_PRIORITY
, l'exécution de la commande
DELETE
est repoussée jusqu'à ce
qu'aucun client ne soit en train de lire la table.
Pour les tables MyISAM
, si vous
spécifiez l'option QUICK
, le moteur de
stockage ne compacte pas les index durant l'effacement, ce
qui peut accélérer certains effacements.
L'option IGNORE
fait que MySQL ignore les
erreurs durant le traitement des lignes. Les erreurs
rencontrées durant la phase d'analyse sont traitées comme
d'habitude. Les erreurs qui sont ignorées grâce à cette
options sont listées comme des alertes. Cette option a
été ajoutée en MySQL 4.1.1.
La vitesse d'exécution des opérations de suppressions peut
être affectées par les facteurs présentés dans la section
Section 7.2.16, « Rapidité des requêtes DELETE
».
Dans les tables de type MyISAM
, les
enregistrements effacés sont maintenus dans une liste liée et
les requêtes INSERT
suivantes réutilisent
les vieux emplacements. Pour recouvrir l'espace inutilisé ou
réduire la taille des fichiers, utilisez la commande
OPTIMIZE TABLE
ou l'utilitaire
myisamchk
pour réorganiser les tables.
OPTIMIZE TABLE
est plus simple, mais
myisamchk
est plus rapide. Voyez
Section 13.5.2.5, « Syntaxe de OPTIMIZE TABLE
» et
Section 5.7.3.10, « Optimisation de table ».
La clause spécifique MySQL LIMIT row_count
de la commande DELETE
indique au serveur le
nombre maximal de ligne à supprimer avant de rendre le
contrôle au client. Elle peut être utilisée pour s'assurer
qu'une commande DELETE
ne prend pas trop de
temps. Vous pouvez simplement répéter la commande
DELETE
jusqu'à ce que le nombre de lignes
effacées est inférieure à la valeur de
LIMIT
.
Si la commande DELETE
inclut la clause
ORDER BY
, les lignes sont effacées dans
l'ordre spécifiée par cette clause. Elle n'est vraiment
utilise que lorsqu'elle est couplée avec la clause
LIMIT
. Par exemple, la commande suivante
applique la condition WHERE
, trie les lignes
avec la colonne timestamp
, et efface la ligne
la plus ancienne :
DELETE FROM somelog WHERE user = 'jcole' ORDER BY timestamp LIMIT 1
ORDER BY
peut être utilisée avec
DELETE
depuis MySQL version 4.0.0.
Depuis MySQL version 4.0, vous pouvez spécifier plusieurs
tables dans la commande DELETE
, pour effacer
des lignes dans plusieurs tables, en fonction d'une condition de
liaison. Cependant, vous ne pouvez pas utiliser les clauses
ORDER BY
et LIMIT
dans une
suppression DELETE
multi-tables.
La première syntaxe de DELETE
multi-table
est supportée depuis MySQL 4.0.0. La deuxième syntaxe de
DELETE
multi-table est supportée depuis
MySQL 4.0.2. La partie table_references
liste
les tables impliquées dans la jointure. Sa syntaxe est décrite
dans la section Section 13.1.7.1, « Syntaxe de JOIN
».
L'idée est que seul les lignes concordante dans les tables
énumérées avant le FROM
ou avant la clause
USING
sont effacés. Le but est de pouvoir
effacer des lignes de plusieurs tables en même temps tout en
ayant d'autres tables pour les recherches.
Le code .*
après les noms de tables n'est
présent que pour assurer la compatibilité avec
Access
:
DELETE t1,t2 FROM t1,t2,t3 WHERE t1.id=t2.id AND t2.id=t3.id
ou :
DELETE FROM t1,t2 USING t1,t2,t3 WHERE t1.id=t2.id AND t2.id=t3.id
Dans les cas précédents, nous n'avons supprimé les lignes
correspondantes que dans les tables t1
et
t2
.
Les exemples ci-dessus présente des jointures internes, en
utilisant l'opérateur virgule, mais les
DELETE
multi-tables peuvent utiliser
n'importe quel type de jointure qu'une commande
SELECT
accepte, comme un LEFT
JOIN
.
La syntaxe autorise .*
après le nom de la
table pour assurer la compatibilité avec
Access
.
Si vous utilisez une commande DELETE
multi-tables avec des tables InnoDB
pour
lesquelles il y a des contraintes de clés étrangères,
l'optimiseur MySQL risque de traiter les tables dans un ordre
qui diffère de celui des relations parent/enfant de la clé.
Dans ce cas, la commande échouera, et s'annulera. Pour
résoudre ce problème, effacez les lignes tables par table, et
utilisez les fonctionnalités ON DELETE
que
InnoDB
fournit pour que les autres tables
soient correctement traitées.
Note : en MySQL 4.0, vous devez utiliser le véritable nom de table. En MySQL 4.1, vous devez utiliser l'alias éventuel, lorsque vous nommez la table :
En MySQL 4.0 :
DELETE test FROM test AS t1, test2 WHERE ...
En MySQL 4.1 :
DELETE t1 FROM test AS t1, test2 WHERE ...
La raison qui nous a poussé à ne pas faire ce changement en version 4.0, est la compatibilité ascendante avec les vieilles applications 4.0, qui utilisent la vieille syntaxe.
DO expression, [expression, ...]
Exécute l'expression mais ne retourne aucun résultat. C'est un
alias de SELECT expression, expression
, mais
il a l'avantage d'être plus rapide quand on n'a pas besoin du
résultat.
Cela s'avère très utile avec les fonctions qui ont des effets
secondaires, comme RELEASE_LOCK
.
HANDLER tbl_name OPEN [ AS alias ] HANDLER tbl_name READ index_name { = | >= | <= | < } (value1,value2,...) [ WHERE ... ] [LIMIT ... ] HANDLER tbl_name READ index_name { FIRST | NEXT | PREV | LAST } [ WHERE ... ] [LIMIT ... ] HANDLER tbl_name READ { FIRST | NEXT } [ WHERE ... ] [LIMIT ... ] HANDLER tbl_name CLOSE
La commande HANDLER
fournit un accès direct
à l'interface de gestion de la table MyISAM
.
La première forme de HANDLER
ouvre la table,
la rendant accessible via la requête HANDLER ...
READ
qui la suit. Cette objet table n'est pas partagé
par les autres threads et ne sera refermé que si le thread
appelle HANDLER nom_de_table CLOSE
ou que
celui ci se termine.
La seconde forme récupère une ligne (ou plus, à spécifier
dans la clause LIMIT
) où l'index spécifié
remplit les conditions et où la clause WHERE
est répondue. Si l'index se compose de plusieurs parties,
(s'étend sur plusieurs colonnes) les valeurs sont spécifiées
dans une liste séparée par des virgules, fournir des valeurs
pour quelques premières colonnes est possible. Par exemple :
HANDLER ... index_name = (col_a_val,col_b_val,col_c_val) ... HANDLER ... index_name = (col_a_val,col_b_val) ... HANDLER ... index_name = (col_a_val) ...
La troisième forme récupère une ligne (ou plus, à spécifier
dans la clause LIMIT
) de la table dans
l'ordre de l'index, qui répond à la clause
WHERE
.
La quatrième forme (sans spécifications relatives à l'index)
récupère une ligne (ou plus, à spécifier dans la clause
LIMIT
) de la table dans un ordre naturel des
lignes (comme stocké dans le fichier de données) qui
correspond à la condition WHERE
. C'est plus
rapide que HANDLER nom_de_table READ
nom_index
quand une lecture entière de la table est
requise. See Section 13.1.7, « Syntaxe de SELECT
».
HANDLER ... CLOSE
ferme une table qui a été
ouverte avec HANDLER ... OPEN
.
Note : pour utiliser l'interface HANDLER
avec la clé primaire d'une table PRIMARY
KEY
, utilisez l'identifiant entre guillemets obliques
`PRIMARY`
:
HANDLER tbl_name READ `PRIMARY` > (...);
HANDLER
est en quelque sorte une commande
bas-niveau. Par exemple, elle ne propose pas de consistance. En
clair, HANDLER ... OPEN
ne se base
pas sur une image de la table, et ne
verrouille pas la table. Cela signifie
qu'après l'exécution d'une requête HANDLER ...
OPEN
, les données de la table peuvent être
modifiées (par ce ou un autre thread) et ces modifications
peuvent apparaître partiellement dans les lectures de
HANDLER ... NEXT
ou HANDLER ...
PREV
.
Les raisons d'utiliser cette interface plutôt que les commandes MySQL usuelles sont :
Plus rapide qu'un SELECT
car :
Un pointeur sur table dédié est alloué au thread dans
HANDLER open
.
Il y a moins de traitements.
Pas de pertes de temps en optimisation ou vérifications de requêtes.
La table utilisée n'a pas besoin d'être verrouillée entre deux requêtes de gestion.
L'interface de gestion n'a pas à fournir une vue consistante des données (par exemple, les lectures corrompues sont autorisées), ce qui permet au gestionnaire d'effectuer des optimisations que SQL ne permet pas.
Cela facilite le port des applications qui utilisent l'interface ISAM pour MySQL.
Cela permet de traverse plus facilement la base de données qu'avec SQL (dans certains cas, cette opération est impossible avec SQL). L'interface de gestion amène une fa¸on plus naturelle de manipuler les données lorsque vous travaillez avec des applications qui proposent une interface interactive entre l'utilisateur et la base de données.
INSERT [LOW_PRIORITY | DELAYED] [IGNORE] [INTO] tbl_name [(col_name,...)] VALUES ({expr | DEFAULT},...),(...),... [ ON DUPLICATE KEY UPDATE col_name=expr, ... ]
ou :
INSERT [LOW_PRIORITY | DELAYED] [IGNORE] [INTO] tbl_name SET col_name={expr | DEFAULT}, ... [ ON DUPLICATE KEY UPDATE col_name=expr, ... ]
ou :
INSERT [LOW_PRIORITY | DELAYED] [IGNORE] [INTO] tbl_name [(col_name,...)] SELECT ...
INSERT
insère une nouvelle ligne dans une
table existante. La syntaxe INSERT ... VALUES
insère une ligne à partir de valeurs explicitement fournies.
La syntaxe INSERT ... SELECT
insère des
valeurs à partir d'une autre table. La syntaxe INSERT
... VALUES
avec plusieurs valeurs est supportées à
partir de MySQL 3.22.5 ou supérieure. la syntaxe
nom_colonne=expression
est supportée à
partir de la version 3.22.10 de MySQL.
INSERT ... SELECT
est présenté plus en
détails : See Section 13.1.4.1, « Syntaxe de INSERT ... SELECT
».
nom_de_table
est le nom de la table dans
laquelle les valeurs seront insérées. La liste de noms de
colonne ou la clause SET
indiquent les
colonnes qui seront affectées:
La liste des noms de colonnes ou la clause
SET
indique explicitement les colonnes
utilisées.
Si vous ne spécifiez pas de liste de colonnes avec
INSERT ... VALUES
ou INSERT ...
SELECT
, les valeurs pour toutes les colonnes
doivent être fournies dans la clause
VALUES()
ou par la commande
SELECT
. Si vous ne connaissez pas l'ordre
des colonnes, utilisez la commande DESCRIBE
nom_de_table
pour le connaître.
Les valeurs des colonnes peuvent être spécifiées de plusieurs fa¸ons :
A chaque fois qu'on ne donne pas explicitement une valeur
pour une colonne, celle prend la valeur par défaut. Par
exemple, si on définit une liste de colonnes qui ne compte
pas toutes les colonnes de la tables, toutes les colonnes
qui ne sont pas nommées prendront leur valeur par défaut.
La définition de la valeur par défaut se fait avec
Section 13.2.5, « Syntaxe de CREATE TABLE
».
MySQL a toujours une valeur par défaut pour chaque champs. C'est obligatoire pour MySQL pour pouvoir fonctionner aussi bien avec des tables supportant les transactions qu'avec des tables ne les supportant pas.
Nous pensons que le contrôle du contenu des champs devrait être fait pas l'application et non par le serveur de base de données.
Note : si vous voulez que les commandes
INSERT
génèrent une erreur si vous ne
spécifiez pas explicitement de valeur pour toutes les
colonnes qui requièrent des valeurs non-nulles
(NULL
), vous pouvez aussi configurer
MySQL avec l'option
DONT_USE_DEFAULT_FIELDS
. Ce comportement
n'est pas disponible si vous compilez MySQL depuis le
source. See Section 2.4.2, « Options habituelles de configure
».
Vous pouvez utiliser le mot clé DEFAULT
pour donner explicitement à une colonne sa valeur par
défaut. Cette fonctionnalité a été ajoutée en MySQL
version 4.0.3. Cela rend plus simple l'écriture de
commandes INSERT
lors de l'assignation de
quelques colonnes, sans écrire de valeurs
VALUES
incomplètes. Sinon, il faut
écrire la liste des colonnes utilisées pour chaque valeur
de la liste VALUES
.
Si la liste de colonnes et de valeurs
VALUES
sont vides,
INSERT
crée une ligne pour chaque
colonne avec sa valeur par défaut :
mysql> INSERT INTO tbl_name () VALUES();
Une expression
peut faire référence à
n'importe quelle colonne qui a été définie précédemment
dans une liste de valeurs. Par exemple, on peut dire ceci :
mysql> INSERT INTO nom_de_table (col1,col2) VALUES(15,col1*2);
Mais vous ne pouvez pas faire cela, car la valeur de
col1
fait référence à
col2
, qui est assigné après
col1
:
mysql> INSERT INTO nom_de_table (col1,col2) VALUES(col2*2,15);
Les commandes INSERT
supportent les options
suivantes :
Si vous spécifiez l'option DELAYED
, le
serveur met la ligne ou les lignes à insérer dans un
tampon, et le client qui a émis la commande INSERT
DELAYED
est immédiatement libéré. Si la table
est occupée, le serveur conserve les lignes. Lorsque la
table se libère, il va insérer les lignes, tout en
vérifiant périodiquement s'il n'y a pas de lectures dans
la table. Si une lecture arrive, l'insertion est suspendue
jusqu'à la prochaine libération. See
Section 13.1.4.2, « Syntaxe de INSERT DELAYED
».
Si on spécifie le mot LOW_PRIORITY
,
l'exécution de INSERT
sera retardé
jusqu'à ce qu'il n'y ait plus de clients qui lisent la
table. Dans ce cas le client doit attendre jusqu'à la fin
de l'opération d'insertion, ce qui peut prendre beaucoup de
temps si la table est fréquemment accédée. C'est la
grande différence avec INSERT DELAYED
,
qui laisse le client continuer tout de suite. See
Section 13.1.4.2, « Syntaxe de INSERT DELAYED
». On peut remarquer que, en
principe, LOW_PRIORITY
ne devrait pas
être utilisé avec des tables de type
MyISAM
, étant donné que celles-ci
n'autorisent pas les insertions simultanées. See
Section 14.1, « Le moteur de tables MyISAM
».
Si on spécifie le mot IGNORE
dans un
INSERT
avec les valeurs de plusieurs
lignes, chaque ligne qui qui ferait doublon avec une clé
PRIMARY
ou UNIQUE
existante dans la table sera ignoré et ne sera pas
insérée. Si on ne spécifie pas IGNORE
,
l'insertion est abandonnée si quelque ligne que ce soit
fait doublon avec une clé existante. La fonction
mysql_info()
de l'API C permet de savoir
combien de lignes ont été insérées dans la table.
Si vous spécifiez la clause ON DUPLICATE KEY
UPDATE
(nouveau en MySQL 4.1.0), et qu'une ligne
insérée engendre un doublon pour une clé
PRIMARY
ou UNIQUE
, une
commande UPDATE
sera faite à la place de
l'insertion. Par exemple, les commandes ont le même effet :
mysql>INSERT INTO table (a,b,c) VALUES (1,2,3)
->ON DUPLICATE KEY UPDATE c=c+1;
mysql>UPDATE table SET c=c+1 WHERE a=1;
Note : si la colonne
b
est aussi unique, la commande
UPDATE
sera réécrite telle que
mysql> UPDATE table SET c=c+1 WHERE a=1 OR b=2 LIMIT 1;
Si a=1 OR b=2
trouve plusieurs lignes,
uniquement une ligne sera mise à jour! En
général, il faut éviter d'utiliser la clause ON
DUPLICATE KEY
sur des tables avec des clés
UNIQUE
multiples.
Depuis MySQL version 4.1.1, on peut utiliser la fonction
VALUES(col_name)
pour faire référence à la
valeur de la colonne dans la clause INSERT
d'une commande INSERT ... UPDATE
: c'est la
valeur qui sera insérée s'il n'y a pas de conflit de clé.
Cette valeur est particulièrement utile dans les commandes
INSERT ... UPDATE
et retourne
NULL
sinon.
Exemple :
mysql>INSERT INTO table (a,b,c) VALUES (1,2,3),(4,5,6)
->ON DUPLICATE KEY UPDATE c=VALUES(a)+VALUES(b);
La commande ci-dessus est identique à :
mysql>INSERT INTO table (a,b,c) VALUES (1,2,3)
->ON DUPLICATE KEY UPDATE c=3;
mysql>INSERT INTO table (a,b,c) VALUES (4,5,6)
->ON DUPLICATE KEY UPDATE c=9;
Lors de l'utilisation de ON DUPLICATE KEY
UPDATE
, l'option DELAYED
est
ignorée.
Vous pouvez trouver la valeur utilisée pour une colonne
AUTO_INCREMENT
en utilisant la fonction
LAST_INSERT_ID()
. Depuis l'interface C,
utilisez la fonction mysql_insert_id()
.
Cependant, notez que les deux fonctions ne se comportement pas
de la la même fa¸ons dans toutes les circonstances. Le
comportement des commandes INSERT
avec les
colonnes AUTO_INCREMENT
sont décrites dans
la section Section 12.8.3, « Fonctions d'informations » et
Section 24.2.3.33, « mysql_insert_id()
».
Si vous utilisez une commande INSERT ...
VALUES
avec plusieurs listes de valeurs ou
INSERT ... SELECT
, la commande retourne les
informations sous ce format :
Records: 100 Duplicates: 0 Warnings: 0
Records
indique le nombre de ligne qui ont
été traitées par cette commande. Ce n'est pas forcément le
nombre de ligne insérées. Duplicates
peut
être non-nulle. Duplicates
indique le nombre
de lignes qui n'ont pas peut être insérées pour cause de
conflit avec une clé unique existante.
Warnings
indique le nombre de tentatives
d'insertion de valeurs dans une colonne qui ont généré des
problèmes. Les Warnings
peuvent apparaître
dans les conditions suivantes:
Insertion de NULL
dans une colonne
déclarée NOT NULL
. Pour les commandes
d'insertions multiples INSERT
ou les
commandes INSERT ... SELECT
, la colonne
prend la valeur par défaut adaptée au type de colonne.
C'est 0
pour les types numériques, la
chaîne vide pour les textes et la valeur ``zéro'' pour les
types temporels
Enregistrement dans une colonne numérique d'une valeur qui déborde de la taille de la colonnes. Cette valeur a été tronquée à l'extrémité la plus adaptée de la colonne.
Attribution à une colonne numérique d'une valeur telle que
'10.34 a'
. Celle valeur refusée est
séparée, et la partie numérique résultante est
insérée. Si cette valeur n'a pas une valeur numérique
sensée, la valeur 0
est insérée.
L'insertion d'une chaîne dans une colonne
CHAR
, VARCHAR
,
TEXT
, ou BLOB
qui
dépasse la taille maximale de la colonne. La valeur est
tronquée à la taille maximale de la colonne.
L'insertion d'une valeur illégale pour une colonne de type
DATE
ou TIME
. La
colonne est alors enregistrée avec la valeur de zéro
appropriée pour le type.
Si vous utilisez l'interface C, la chaîne d'information peut
être obtenue en invoquant la fonction
mysql_info()
. See
Section 24.2.3.31, « mysql_info()
».
INSERT [LOW_PRIORITY] [IGNORE] [INTO] nom_de_la_table [(liste des colonnes)] SELECT ...
La requête INSERT ... SELECT
permet de
rapidement insérer dans une table un grand nombre de lignes
d'une ou plusieurs autres tables.
INSERT INTO tblTemp2 (fldID) SELECT tblTemp1.fldOrder_ID FROM tblTemp1 WHERE tblTemp1.fldOrder_ID > 100;
Les conditions suivantes s'appliquent à la requête
INSERT ... SELECT
:
Avant MySQL version 4.0.1, INSERT ...
SELECT
opérait implicitement en mode
IGNORE
. Depuis MySQL version 4.0.1,
vous devez spécifier le mode IGNORE
explicitement, pour ignorer les lignes qui causeront des
erreurs de doublons pour les index uniques.
N'utilisez pas DELAYED
avec
INSERT ... SELECT
.
Avant MySQL version 4.0.14, la table de destination de la
requête INSERT
ne peut apparaître
dans la clause FROM
de la partie
SELECT
de la requête car il est
interdit par le ANSI SQL de lire la table dans laquelle on
est en train de faire un insert. (le problème est que le
SELECT
pourrait trouver des
enregistrements qui aurait été insérés auparavant dans
la même exécution. L'utilisation de "subselect" peut
rendre la situation confuse !)
Les colonnes AUTO_INCREMENT
fonctionnent comme d'habitude.
Pour s'assurer que les journaux des modifications ou les
journaux binaires puissent être utilisés pour re-créer
les tables originales, MySQL n'autorise pas les inserts
concurrents pendant INSERT ... SELECT
.
Il est bien sûr possible d'utiliser
REPLACE
à la place de
INSERT
pour remplacer les anciennes lignes.
INSERT DELAYED ...
L'option DELAYED
de la commande
INSERT
est une option spécifique à MySQL
très utile si vos clients ne peuvent pas attendre que
INSERT
se termine. C'est un problème
fréquent quand on utilise MySQL pour des logs, mais aussi
quand on utilise souvent des commandes
SELECT
ou UPDATE
qui
prennent beaucoup de temps. DELAYED
a été
ajouté à MySQL dans la version 3.22.15. C'est une extension
de MySQL au ANSI SQL 92.
En utilisant INSERT DELAYED
, le client
re¸oit immédiatement un aquitement, et la ligne sera
insérée quand la table ne sera plus utilisée par un autre
thread.
Un autre avantage de INSERT DELAYED
est que
les insertions des clients sont regroupés, et écrits d'un
seul bloc. C'est beaucoup plus rapide que de faire des
insertions séparés.
Il y a quelques contraintes à l'utilisation de
DELAYED
:
INSERT DELAYED
ne fonctionne qu'avec
les tables MyISAM
et
ISAM
. Pour les tables
MyISAM
, s'il n'y a plus de blocs libres
au milieu du fichier de données, les
SELECT
et INSERT
simultanés sont supportés. Dans ces circonstances, vous
n'aurez que très rarement besoin de INSERT
DELAYED
avec MyISAM
. See
Section 14.1, « Le moteur de tables MyISAM
».
INSERT DELAYED
doit être utilisé
uniquement avec les commandes INSERT
qui spécifie une liste de valeur. C'est le cas depuis
MySQL 4.0.18. Le serveur ignore DELAYED
pour les commandes INSERT DELAYED ...
SELECT
.
Le serveur ignore DELAYED
dans les
commandes INSERT DELAYED ... ON DUPLICATE
UPDATE
.
Comme la commande s'exécute immédiatement, sans que la
ligne ne soit insére, vous ne pouvez pas utiliser
LAST_INSERT_ID()
pour lire la valeur
que la colonne AUTO_INCREMENT
va
générer.
Les lignes DELAYED
ne sont visibles par
les commandes SELECT
que lorsqu'elles
ont été réellement insérées.
Actuellement, les lignes en attente sont uniquement stockées
en mémoire tant qu'elle ne sont pas insérées dans la table.
Cela signifie que si on tue mysqld
violemment, (kill -9
) ou si
mysqld
meurt accidentellement, toutes les
lignes en attente qui n'auront pas été écrites sur le
disque seront perdues !
Les paragraphes suivants décrivent en détail ce qu'il se
passe quand on utilise l'option DELAYED
dans une requête INSERT
ou
REPLACE
. Dans cette description, ``thread''
est un thread qui re¸oit une commande INSERT
DELAYED
ans ``handler'' est un thread qui gère
toutes les opérations de INSERT DELAYED
pour une table donnée.
Quand un thread exécute une opération
DELAYED
sur une table, un thread de
gestion est créé pour exécuter toutes les opérations
DELAYED
pour cette table - si ce thread
de gestion n'existe pas.
Le thread vérifie que a déjà re¸u un verrou
DELAYED
; sinon, il dit au thread de
gestion de le faire. le verrou DELAYED
peut être obtenu même si d'autres threads ont des
verrous READ
ou
WRITE
sur la table. Cependant le
gestionnaire attendra que tous les verrous ALTER
TABLE
ou FLUSH TABLES
soient
finis pour s'assurer que la structure de la table est à
jour.
Le thread exécute une opération
INSERT
, mais plutôt que d'écrire la
ligne dans la table, il va placer une copie de la ligne
finale dans une file d'attente gérée par le thread de
gestion. Le programme client est avertit de toutes les
erreurs de syntaxe.
Le client ne peut pas faire de rapport sur le nombre de
duplicata ou sur la valeur de
AUTO_INCREMENT
de la ligne
enregistrée; il ne peut pas les obtenir du serveur, car
le INSERT
est validé avant que
l'opération d'insert n'ait été effectuée. Si vous
utilisez l' API C, la fonction
mysql_info()
ne retourne pas de valeur
intéressante, pour la même raison.
Le journal de modification est mis à jour par le thread de gestion au moment où la ligne est insérée dans la table. Si plusieurs lignes sont insérées en même temps, le journal des modifications est mis à jour quand la première ligne est insérée.
Une fois que toutes les lignes
delayed_insert_limit
sont écrites, le
gestionnaire vérifie si des requêtes
SELECT
sont en attente, et si c'est le
cas, il leur permet de s'exécuter avant de continuer.
Quand le thread de gestion n'a plus de ligne dans sa file,
la table est déverrouillée. Si aucun INSERT
DELAYED
n'est re¸u avant
delayed_insert_timeout
secondes, le
gestionnaire s'arrête.
Si plus de delayed_queue_size
lignes
sont déjà en attente d'un gestionnaire de file donné,
le thread qui demande le INSERT DELAYED
doit attendre qu'il y ait une place dans la file. Cela
permet d'être sûr que mysqld
n'utilisera pas toute la mémoire pour la mémoire des
files d'attente d'insertions retardés.
Le thread de gestion apparaîtra dans la liste des
processus de MySQL avec delayed_insert
dans la colonne Command
. Il sera tué
si on exécute une commande FLUSH
TABLES
ou si on le tue avec KILL
thread_id
. Cependant, il commencera par stocker
toutes les lignes en attente dans la table avant de
sortir. Pendant ce temps, il n'acceptera aucune commande
INSERT
d'aucun autre thread. Si on
exécute une commande INSERT DELAYED
après cela, un nouveau thread de gestion sera créé.
Il faut noter que les commandes INSERT
DELAYED
ont une plus grande priorité que les
commandes INSERT
normales si un
gestionnaire de INSERT DELAYED
existe
déjà! les autres commandes de modification devront
attendre que la file d'attente de INSERT
DELAYED
soit vide, que quelqu'un tue le
gestionnaire (avec KILL thread_id
), ou
que quelqu'un exécute FLUSH TABLES
..
Les variables suivantes fournissent des informations
relatives à la commande INSERT
DELAYED
:
Variable | Signification |
Delayed_insert_threads | Nombre de threads de gestion |
Delayed_writes | Nombre de lignes écrites avec INSERT DELAYED |
Not_flushed_delayed_rows | Nombre de lignes en attente d'être écrites. |
On peut voir ces variables avec la commande SHOW
STATUS
ou en exécutant la commande
mysqladmin extended-status
.
Il faut noter que INSERT DELAYED
est plus
lent qu'un INSERT normal si la table n'est pas utilisée.
L'utilisation d'un thread de gestion séparé pour chaque
table sur lesquelles on utilise INSERT
DELAYED
rajoute également une surcharge au serveur.
Ce qui signifie qu'il vaut mieux utiliser INSERT
DELAYED
uniquement quand c'est vraiment nécessaire!
LOAD DATA [LOW_PRIORITY | CONCURRENT] [LOCAL] INFILE 'file_name.txt' [REPLACE | IGNORE] INTO TABLE tbl_name [FIELDS [TERMINATED BY '\t'] [[OPTIONALLY] ENCLOSED BY ''] [ESCAPED BY '\\' ] ] [LINES [STARTING BY ''] [TERMINATED BY '\n'] ] [IGNORE number LINES] [(col_name,...)]
La commande LOAD DATA INFILE
lit les lignes
dans un fichier texte et les insère à très grande vitesse.
Pour plus d'informations sur l'efficacité des commandes
INSERT
comparativement à LOAD DATA
INFILE
et pour accélérer les commandes LOAD
DATA INFILE
, voyez Section 7.2.14, « Vitesse des requêtes INSERT
».
Vous pouvez aussi charger des fichiers de données en utilisant
l'utilitaire mysqlimport
; Il opère en
envoyant la commande LOAD DATA INFILE
au
serveur. L'option --local
fais que
mysqlimport
lit les fichiers de données chez
le client. Vous pouvez spécifier l'option
--compress
pour avoir de meilleurs performances
avec les connexions lentes si le client et le serveur supportent
le protocole compressé. See Section 8.10, « mysqlimport
, importer des données depuis des
fichiers texte ».
Si vous spécifiez le mot clef LOW_PRIORITY
,
l'exécution de la commande LOAD DATA
est
ajournée jusqu'à ce qu'aucun client ne lise plus de la table.
Si vous spécifiez le mot clef CONCURRENT
avec un table au format MyISAM
, les autres
threads pourront accéder à la table durant l'exécution de la
commande LOAD DATA
. L'utilisation de cette
option ralentira un peu les performances de LOAD
DATA
même si aucun thread n'utilise la table en même
si aucun autre thread n'accède à la table en même temps.
Si le mot clé LOCAL
est spécifié, il est
interprété en suivant les règles suivantes :
Si LOCAL
est spécifié, le fichier est
lu par le programme client, et envoyé vers l'hôte.
Si LOCAL
n'est pas spécifiée, le
fichier doit être sur le serveur hôte, et sera lu
directement par le serveur.
LOCAL
est disponible depuis MySQL 3.22.6 ou
plus récent.
Pour des raisons de sécurité, lorsque les fichiers sont lus
sur le serveur, ils doivent se trouver dans le répertoire de la
base de données courante, ou bien être lisible par tous. Pour
utiliser la commande LOAD DATA INFILE
sur des
fichiers du serveur, vous devez avoir le droit de
FILE
sur le serveur. See
Section 5.5.3, « Droits fournis par MySQL ».
Utiliser LOCAL
est plus lent que de laisser
le serveur accéder directement aux fichiers, car le contenu du
fichier doit être envoyé via le réseau au serveur. D'un autre
coté, vous n'aurez pas besoin de droits de
FILE
pour faire un chargement local.
Depuis MySQL 3.23.49 et MySQL 4.0.2 (4.0.13 sur Windows),
LOCAL
fonctionne uniquement si votre serveur
et votre client ont été configuré pour. Par exemple, si
mysqld
a été lancé avec
--local-infile=0
, LOCAL
ne
fonctionnera pas. See Section 5.4.4, « Problèmes de sécurité avec LOAD DATA LOCAL ».
Si vous avez besoin de lire des données LOAD
DATA
depuis un pipe, vous devez utiliser la technique
suivante :
mkfifo /mysql/db/x/x chmod 666 /mysql/db/x/x cat < /dev/tcp/10.1.1.12/4711 > /mysql/db/x/x mysql -e "LOAD DATA INFILE 'x' INTO TABLE x" x
Si vous utilisez une version de MySQL plus ancienne que 3.23.25,
vous pouvez uniquement utiliser cette technique avec
LOAD DATA LOCAL INFILE
.
Si vous utilisez une version de MySQL antérieure à la 3.23.24
vous ne pouvez lire à partir d'un FIFO avec LOAD DATA
INFILE
. Si vous avez besoin de lire à partir d'un
FIFO (par exemple la sortie de gunzip), utilisez LOAD
DATA LOCAL INFILE
.
Lorsque les fichiers de données sont sur le serveur, celui-ci utilise les règles suivantes :
Si un chemin absolu est fourni, le serveur utilise le chemin tel quel.
Si un chemin relatif est fourni, avec un ou plusieurs éléments de dossiers, le serveur recherche le fichier relativement à son dossier de données.
Si le fichier n'a pas d'éléments de dossier, le serveur recherche les données dans le dossier de base de données courante.
Notez que ces règles font qu'un fichier tel que
./myfile.txt
est lu dans le dossier de
données du serveur, alors que s'il est nommé
myfile.txt
, il sera lu dans le dossier de
base de données courante. Par exemple, la commande
LOAD DATA
suivante lit le fichier
donnees.txt
dans le dossier de la base
db1
car db1
est la base de
données courante, même si la commande charge explicitement le
fichier dans la base de données db2
:
mysql>USE db1;
mysql>LOAD DATA INFILE "donnees.txt" INTO TABLE db2.ma_table;
Les mots réservés REPLACE
et
IGNORE
contrôlent la méthode d'insertion de
lignes lorsque des doublons apparaissent pour les clés uniques.
Si vous spécifiez REPLACE
, les nouvelles
lignes remplaceront les anciennes. See
Section 13.1.6, « Syntaxe de REPLACE
».
Si vous spécifiez IGNORE
, les nouvelles
lignes seront ignorées. Si vous ne spécifiez pas cette option,
une erreur sera générée à chaque doublon, et le reste du
fichier sera ignoré. Avec l'option LOCAL
, le
comportement par défaut est le même que si
IGNORE
est spécifié : ceci est dû au fait
que le serveur n'a pas moyen de stopper la transmission du
fichier au milieu de l'opération.
Si vous chargez un fichier sur votre machine client avec
l'option LOCAL
, le serveur ne peut pas
interrompre la transmission du fichier au milieu de
l'opération : par défaut, il utilisera l'option
IGNORE
.
Si vous voulez ignorer les clés étrangères le temps du
chargement du fichier, utilisez la commande SET
FOREIGN_KEY_CHECKS=0
avant d'exécuter LOAD
DATA
.
Si vous utilisez LOAD DATA INFILE
sur une
table vide de type MyISAM
, tous les index
non-uniques seront créés dans un processus séparé (tout
comme REPAIR
). Cela rend LOAD DATA
INFILE
beaucoup plus rapide si vous avez plusieurs
index. See Section 5.7.3, « Utilisation de myisamchk
pour la maintenance des
tables et leur recouvrement ».
LOAD DATA INFILE
est le complémentaire de
SELECT ... INTO OUTFILE
. See
Section 13.1.7, « Syntaxe de SELECT
». Pour écrire des données depuis une
table dans un fichier, utilisez SELECT ... INTO
OUTFILE
. Pour lire les données dans la table,
utilisez LOAD DATA INFILE
. La syntaxe des
clauses FIELDS
et LINES
est la même pour les deux commandes. Ces deux clauses sont
optionnelles, mais FIELDS
doit précéder
LINES
, si les deux sont spécifiées.
Si vous spécifiez la clause FIELDS
, les
sous-clauses TERMINATED BY
,
[OPTIONALLY] ENCLOSED BY
, et ESCAPED
BY
sont aussi optionnelles, mais vous devez en
spécifier au moins une.
Si vous ne spécifiez par de clause FIELDS
,
les valeurs par défaut sont :
FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\'
Si vous ne spécifiez par de clause LINES
,
les valeurs par défaut sont :
LINES TERMINATED BY '\n'
En d'autres termes, les valeurs par défaut font que
LOAD DATA INFILE
lit les données comme
suit :
Recherche des limites de lignes parmi les nouvelles lignes.
Si LINES STARTING BY prefix
est utilisé,
lit jusqu'au préfixe, et commence à lire après le
préfixe. Si la ligne n'inclut pas de préfixe, elle sera
ignorée.
Scinde les lignes en champs avec les tabulations.
Ne suppose pas que les champs sont entourés de guillemets.
Interprète les occurrences de tabulation, nouvelle ligne,
‘'\'
’ précédées par
‘'\'
’ comme des caractères
littéraux qui font partie de la valeur d'un champs.
A l'inverse, les valeurs par défaut font que SELECT
... INTO OUTFILE
écrit les données comme ceci :
Ecrivez des tabulations entre les champs.
N'entourez pas les champs de guillemets.
Utilisez ‘\
’ pour échapper
les occurrences de tabulation, nouvelle ligne,
‘\
’ trouvées dans les
valeurs.
Insère une nouvelle ligne entre les lignes.
Notez que pour utiliser FIELDS ESCAPED BY
'\\'
, vous devez spécifier deux anti-slash pour que
cette valeur soit interprétée comme un anti-slash simple.
Note : si vous avez généré
le fichier sur Windows, vous devrez peut-être utiliser
LINES TERMINATED BY '\r\n'
pour lire le
fichier correctement, car les programmes Windows utilisent
généralement deux caractères comme fin de ligne. Certains
programmes, comme WordPad
, peuvent utiliser
\r
comme terminateur de ligne lors de
l'écriture. Pour lire ces fichiers, utilisez LINES
TERMINATED BY '\r
.
L'option IGNORE nombre LINES
sert à ignorer
une en-tête de fichier, telle que des noms de colonnes, qui
débutent parfois un fichier à charger :
mysql> LOAD DATA INFILE "/tmp/nom_fichier" INTO TABLE test IGNORE 1 LINES;
Lorsque vous utilisez SELECT ... INTO OUTFILE
conjointement avec LOAD DATA INFILE
pour
écrire des données dans un fichier et les relire dans une
table, les options de FIELDS
et
LINES
doivent être identiques. Sinon,
LOAD DATA INFILE
ne pourra pas interpréter
le contenu du fichier correctement. Supposez que la commande
SELECT ... INTO OUTFILE
ait écrit un fichier
délimité par des virgules :
mysql>SELECT * INTO OUTFILE 'donnees.txt'
->FIELDS TERMINATED BY ','
->FROM ...;
Pour lire ce fichier, la commande correcte serait :
mysql>LOAD DATA INFILE 'donnees.txt' INTO TABLE table2
->FIELDS TERMINATED BY ',';
Si au contraire, vous essayez de lire le fichier avec la
commande ci-dessous, cela ne fonctionnera pas, car la commande
LOAD DATA INFILE
essaie de lire des
tabulations entre les champs :
mysql>LOAD DATA INFILE 'donnees.txt' INTO TABLE table2
->FIELDS TERMINATED BY '\t';
Il est probable que chaque ligne d'entrée sera interprétée que comme un seul champ.
La commande LOAD DATA INFILE
peut être
utilisée pour lire des données issues d'autres sources. Par
exemple, un fichier au format dBASE présente des champs
séparés par des virgules, et entourés de guillemets doubles.
Si les lignes sont terminées par de nouvelles lignes, la
commande ci-dessous illustre la relecture d'un tel fichier avec
MySQL :
mysql>LOAD DATA INFILE 'donnees.txt' INTO TABLE nom_de_table
->FIELDS TERMINATED BY ',' ENCLOSED BY '"'
->LINES TERMINATED BY '\n';
Les clauses FIELDS
et
LINES
peuvent prendre des chaînes vides
comme valeur. S'il la chaîne n'est pas vide, FIELDS
[OPTIONALLY] ENCLOSED BY
et FIELDS ESCAPED
BY
ne doivent avoir qu'un seul caractère. Les valeurs
de FIELDS TERMINATED BY
et LINES
TERMINATED BY
peuvent avoir plus d'un caractère. Par
exemple, pour écrire des lignes terminées par le couple retour
chariot/nouvelle ligne, ou pour lire un tel fichier, spécifiez
la clause LINES TERMINATED BY '\r\n'
.
Par exemple, pour charger un fichier de blagues, qui sont
séparées par une ligne de %%
, dans une
table vous pouvez faire :
CREATE TABLE blagues ( a INT NOT NULL AUTO_INCREMENT PRIMARY KEY, blague TEXT NOT NULL ); LOAD DATA INFILE "/tmp/blagues.txt" INTO TABLE blagues FIELDS TERMINATED BY "" LINES TERMINATED BY "\n%%\n" (blague);
FIELDS [OPTIONALLY] ENCLOSED BY
contrôle la
mise entre guillemets des champs. Pour l'écriture de fichier
(SELECT ... INTO OUTFILE
), si vous omettez le
mot OPTIONALLY
, tous les champs seront
entourés par le caractère spécifié dans la clause
ENCLOSED BY
. Par exemple, si la virgule est
utilisée comme séparateur de champs :
"1","une chaîne","100.20" "2","une chaîne contenant une , virgule","102.20" "3","une chaîne contenant un \" guillemet","102.20" "4","une chaîne contenant un \", guillemet et une virgule","102.20"
Si vous spécifiez OPTIONALLY
, le caractère
ENCLOSED BY
n'est utilisé que pour protéger
les colonnes de types CHAR
et
VARCHAR
:
1,"une chaîne",100.20 2,"une chaîne contenant une , virgule",102.20 3,"une chaîne contenant un \" guillemet",102.20 4,"une chaîne contenant un \", guillemet et une virgule",102.20
Notez que les occurrences du caractère ENCLOSED
BY
dans un champs sont échappée en les préfixant
avec le caractère ESCAPED BY
. Notez aussi
que si vous spécifiez un caractère d'échappement vide, il
n'est pas possible de garantir que les champs seront
correctement relus par LOAD DATA INFILE
. Par
exemple, l'exemple ci-dessus apparaîtra comme montré
ci-dessous. Notez que le second champ de la quatrième ligne
comporte une virgule suivant un guillemet qui semble (mais c'est
faux) terminer la ligne :
1,"une chaîne",100.20 2,"une chaîne contenant une , virgule",102.20 3,"une chaîne contenant un " guillemet",102.20 4,"une chaîne contenant un ", guillemet et une virgule",102.20
Lors des lectures, le caractère ENCLOSED BY
,
s'il est présent, est supprimé des extrémités de la valeur
du champ. (ce qui est vrai, qu'il y ait l'option
OPTIONALLY
ou pas). Les occurrences du
caractère ENCLOSED BY
, précédées par le
caractère ESCAPED BY
sont interprétées
comme faisant partie de la valeur du champ. Les caractères
ENCLOSED BY
doublées, apparaissant dans la
chaîne, sont interprétés comme le caractère
ENCLOSED BY
lui-même. Par exemple, si
ENCLOSED BY '"'
est spécifié, les
guillemets sont gérés comme ceci :
"Le ""GRAND"" chef" -> Le "GRAND" chef Le "GRAND" chef -> Le "GRAND" chef Le ""GRAND"" chef -> Le ""GRAND"" chef
FIELDS ESCAPED BY
contrôle les caractères
spéciaux. Si le caractère FIELDS ESCAPED BY
n'est pas vide, il est utilisé pour préfixer les caractères
suivants en écriture :
La caractère FIELDS ESCAPED BY
Le caractère FIELDS [OPTIONALLY] ENCLOSED
BY
Le premier caractère des valeurs de FIELDS
TERMINATED BY
et LINES TERMINATED
BY
ASCII 0
(en fait, ce qui est écrit
après le caractère d'échappement est le caractère ASCII
'0'
, et non pas le code ASCII de zéro)
Si le caractère FIELDS ESCAPED BY
est vide,
aucun caractère ne sera échappé. Ce n'est probablement pas
une bonne idée de spécifier un caractère d'échappement vide,
en particulier si les valeurs dans vos champs risquent
d'utiliser l'un des caractères de la liste ci-dessus.
En lecture, si le caractère FIELDS ESCAPED
BY
n'est pas vide, les occurrences de ce caractère
sont supprimées, et le caractère suivant est lu
littéralement. Les exceptions à cette règle sont
‘0
’ ou
‘N
’ (par exemple,
0
ou \N
si le caractère
d'échappement est ‘\
’). Ces
séquences sont interprétées comme l'octet nul (ASCII
0
) et la valeur NULL
.
Voyez plus bas pour la gestion des valeurs
NULL
.
Pour plus d'informations sur la syntaxe avec les caractères
d'échappement ‘\
’, consultez
Section 9.1, « Littéraux : comment écrire les chaînes et les nombres ».
Dans certains cas, les options de FIELDS
et
LINES
interfèrent entre elles :
Si le caractère de LINES TERMINATED BY
est une chaîne vide et que celui de FIELDS
TERMINATED BY
ne l'est pas, ce dernier sera celui
utilisé pour LINES TERMINATED BY
.
Si les valeurs FIELDS TERMINATED BY
et
FIELDS ENCLOSED BY
sont vides toutes les
deux (''
), un format à taille de champ
fixe est utilisé. Avec ce format, aucun délimiteur n'est
utilisé entre les champs. Au lieu de cela, les valeurs des
colonnes sont écrites avec leur configuration d'affichage.
Par exemple, si une colonne a été déclarée
INT(7)
, la valeur de cette colonne sera
écrite avec 7 caractères. Lors de la relecture, la valeur
de la colonne sera obtenue en lisant à nouveau 7
caractères. Ce format à taille fixe affecte la gestion de
la valeur NULL
; voyez plus loin pour
cela. Notez que ce format ne fonctionne pas avec les jeux de
caractères multi-octets.
La gestion des valeurs NULL
dépend des
options FIELDS
et LINES
que vous utilisez :
Pour les valeurs par défaut de FIELDS
et
LINES
, NULL
est écrit
\N
et \N
est lu
NULL
(en supposant que le caractère
d'échappement est ‘\
’).
Si FIELDS ENCLOSED BY
n'est pas vide, un
champ contenant le mot NULL
comme valeur
sera lu comme la valeur NULL
(ce qui
diffère du mot NULL
, entouré du
caractère FIELDS ENCLOSED BY
, qui sera
lu comme le mot 'NULL'
).
Si FIELDS ESCAPED BY
est vide,
NULL
est écrit comme le mot
'NULL'
.
Avec le format à taille fixe (ce qui arrive si
FIELDS TERMINATED BY
et FIELDS
ENCLOSED BY
sont tous les deux vides), les valeurs
NULL
sont écrites sous forme de chaîne
vide. Notez que cela fait que NULL
et les
chaînes vides seront représentées par une valeur qui ne
les distingue pas l'une de l'autre. Si vous avez besoin de
différencier entre les deux, n'utilisez par ce format !
Certains cas ne sont pas supportés par LOAD DATA
INFILE
:
Lignes à tailles fixes (FIELDS TERMINATED
BY
et FIELDS ENCLOSED BY
sont
tous les deux vides) et les types de colonne
BLOB
ou TEXT
.
Si vous spécifiez un séparateur qui est le même qu'un
autre préfixe, LOAD DATA INFILE
ne sera
pas capable de relire proprement le résultat. Par exemple,
la clause FIELDS
suivante posera
sûrement des problèmes :
FIELDS TERMINATED BY '"' ENCLOSED BY '"'
Si FIELDS ESCAPED BY
est vide, une valeur
de colonne qui contient une occurrence de FIELDS
ENCLOSED BY
ou de LINES TERMINATED
BY
suivi du caractère FIELDS TERMINATED
BY
interrompra la lecture de LOAD DATA
INFILE
trop tôt. Cela est dû au fait que
LOAD DATA INFILE
ne peut pas faire la
différence entre la valeur dans le champ et la fin de la
ligne.
L'exemple suivant charge toutes les colonnes de la table
persondata
:
mysql> LOAD DATA INFILE 'persondata.txt' INTO TABLE persondata;
Aucun champ n'est spécifié, ce qui fait que LOAD DATA
INFILE
s'attend à ce que les lignes lues contiennent
le bon nombre de champs. Les valeurs par défaut de
FIELDS
et LINES
sont
utilisées.
Si vous voulez charger uniquement quelques colonnes dans une table, spécifiez la liste des champs :
mysql>LOAD DATA INFILE 'persondata.txt'
->INTO TABLE persondata (col1,col2,...);
Vous devez aussi spécifier les champs si l'ordre dans lequel ils seront lus diffère de l'ordre des colonnes dans la table. Sinon, MySQL ne pourra pas savoir à quelle colonne correspond une valeur.
Si une ligne a trop peu de champs, les colonnes omises prendront
leur valeur par défaut. Les affectations de valeurs par défaut
sont décrites dans Section 13.2.5, « Syntaxe de CREATE TABLE
».
Une valeur de champs vide et un champ manquant ne seront pas interprétés de la même fa¸on :
Pour les types chaîne, la colonne est remplie avec la chaîne vide.
Pour les types numériques, la colonne est mise à
0
.
Pour les types dates et heures, la colonne est mise au zéro approprié pour le type. See Section 11.3, « Les types date et heure ».
Notez que vous obtiendrez le même résultat en assignant à ces
différents types de champs la chaîne vide dans une commande
INSERT
ou UPDATE
.
Les colonnes TIMESTAMP
prendront la date et
l'heure courante uniquement si on leur affecte la valeur
NULL
, ou (pour la première colonne
TIMESTAMP
seulement) si la colonne
TIMESTAMP
est ignorée de la liste des
colonnes spécifiée.
Si une ligne d'entrée comporte trop de colonnes, les champs en trop sont ignorés, et le nombre d'alertes est incrémenté.
LOAD DATA INFILE
considère toutes les
valeurs lues comme des chaînes de caractères : vous ne
pourrez donc pas utiliser la forme numérique des colonnes
ENUM
ou SET
, comme
d'habitude. Toutes les colonnes ENUM
et
SET
doivent être spécifiée comme des
chaînes !
Si vous utilisez l'API C, vous pouvez obtenir des informations
à propos de la requête en utilisant la fonction
mysql_info()
quand LOAD DATA
INFILE
se termine. Le format de la chaîne
d'informations est le suivant :
Records: 1 Deleted: 0 Skipped: 0 Warnings: 0
Les alertes sont générées dans les mêmes circonstances que
pour la commande INSERT
(see
Section 13.1.4, « Syntaxe de INSERT
»), excepté que LOAD DATA
INFILE
génère aussi des alertes s'il y a trop peu ou
trop de champs dans une ligne. Les alertes ne sont pas
stockées; le nombre d'alertes est la seule indication. Si vous
recevez des alertes et vous voulez savoir exactement ce qui
s'est passé, exécutez une commande SELECT ... INTO
OUTFILE
dans un autre fichier et comparez le avec le
fichier original.
En MySQL version 4.1.1 vous pouvez utiliser SHOW
WARNINGS
pour obtenir la liste des premières
max_error_count
alertes. See
Section 13.5.3.19, « SHOW WARNINGS | ERRORS
».
Pour plus d'informations sur les performances de
INSERT
comparées à LOAD DATA
INFILE
et accélérer LOAD DATA
INFILE
: See Section 7.2.14, « Vitesse des requêtes INSERT
».
REPLACE [LOW_PRIORITY | DELAYED] [INTO] tbl_name [(col_name,...)] VALUES ({expr | DEFAULT},...),(...),...
ou :
REPLACE [LOW_PRIORITY | DELAYED] [INTO] tbl_name SET col_name={expr | DEFAULT}, ...
ou :
REPLACE [LOW_PRIORITY | DELAYED] [INTO] tbl_name [(col_name,...)] SELECT ...
REPLACE
fonctionne exactement comme
INSERT
, sauf que si une vieille ligne dans la
table à la même valeur qu'une nouvelle pour un index
UNIQUE
ou une PRIMARY KEY
,
la vielle ligne sera effacée avant que la nouvelle ne soit
insérée. See Section 13.1.4, « Syntaxe de INSERT
».
En d'autres termes, vous ne pouvez pas accéder aux valeurs de
l'ancienne ligne à partir d'une requête
REPLACE
. Dans quelques vieilles versions de
MySQL, il apparaît que c'était possible, mais c'etait un
dysfonctionnement qui a été corrigé depuis.
Pour utiliser REPLACE
vous devez avoir les
privilèges INSERT
et
DELETE
sur la table.
Quand vous utilisez une commande REPLACE
,
mysql_affected_rows()
retournera 2 si une
nouvelle ligne en remplace une existante, et cela parce qu'il y
aura eu une insertion puis une suppression.
Cela aide à savoir si REPLACE
a ajouté ou a
remplacé une ligne : Testez si le nombre de lignes affectées
est égal à 1 (ajout) ou s'il est égal à 2 (remplacement).
Notez que si vous n'utilisez pas un index
UNIQUE
ou une PRIMARY KEY
,
utiliser un REPLACE
n'a pas de sens vu que
cela revient à utiliser un INSERT
. Il
devient équivalent à INSERT
, car il n'y a
pas d'index à utiliser pour déterminer si un nouvelle ligne
est un double d'une autre.
Voici quelques détails sur l'algorithme utilisé : Il est
aussi utilisé par LOAD DATA ... REPLACE
.
Insertion de la ligne dans la table
Si une erreur de clé dupliqué ou de clé unique ou de clé primaire survient :
Annuler les changements de clés
Essayer à nouveau d'insérer la clé primaire et unique dans la table
SELECT [STRAIGHT_JOIN] [SQL_SMALL_RESULT] [SQL_BIG_RESULT] [SQL_BUFFER_RESULT] [SQL_CACHE | SQL_NO_CACHE] [SQL_CALC_FOUND_ROWS] [HIGH_PRIORITY] [DISTINCT | DISTINCTROW | ALL] select_expression,... [INTO {OUTFILE | DUMPFILE} 'nom_fichier' export_options] [FROM table_references [WHERE where_definition] [GROUP BY {unsigned_integer | nom_de_colonne | formula} [ASC | DESC], ... [HAVING where_definition] [ORDER BY {unsigned_integer | nom_de_colonne | formula} [ASC | DESC] ,...] [LIMIT [offset,] lignes] [PROCEDURE procedure_name(argument_list)] [FOR UPDATE | LOCK IN SHARE MODE]]
SELECT
est utilisé pour obtenir des
enregistrements venant d'une ou plusieurs tables. Le support des
commandes UNION
et des sous-requêtes est
disponibles depuis MySQL 4.0 et 4.1, respectivement. Voir
Section 13.1.7.2, « Syntaxe de UNION
» et Section 13.1.8, « Sous-sélections (SubSELECT
) ».
Chaque select_expr
indique une colonne à
lire.
table_references
indique la ou les tables
à utiliser. La syntaxe est décrite dans
Section 13.1.7.1, « Syntaxe de JOIN
».
where_definition
indique les conditions
que les lignes sélectionnées doivent satisfaire.
SELECT
peut aussi être utilisée pour lire
des lignes calculées, sans référence à une table.
Par exemple :
mysql> SELECT 1 + 1;
-> 2
Tous les mots-clés utilisés doivent être donnés exactement
dans le même ordre que ci-dessus. Par exemple, une clause
HAVING
doit être placée après toute clause
GROUP BY
et avant toute clause ORDER
BY
.
Une expression SELECT
peut recevoir un
alias en utilisant AS
. L'alias est
utilisé de la même fa¸on que le nom du champ et peut
être employé avec des clauses ORDER BY
ou HAVING
. Par exemple :
mysql> SELECT CONCAT(last_name,', ',first_name) AS full_name
FROM mytable ORDER BY full_name;
Le mot clé AS
est optionnel lors de la
création d'un alias pour une expression
SELECT
. L'exemple précédent aurait pu
être écrit comme ceci :
mysql> SELECT CONCAT(last_name,', ',first_name) full_name
FROM mytable ORDER BY full_name;
Comme AS
est optionnel, un problème
subtil peut survenir si vous oubliez une virgule entre deux
expressions de SELECT
: MySQL va
interpréter la seconde comme un alias de la première. Par
exemple, dans la commande suivante,
columnb
est traité comme un nom
d'alias :
mysql> SELECT columna columnb FROM mytable;
Il n'est pas possible d'utiliser un alias de champ dans une
clause WHERE
, car la valeur du champ peut
ne pas être définie lorsque la clause
WHERE
est exécutée. See
Section A.5.4, « Problèmes avec les alias
».
La clause FROM table_references
indique
les tables à partir desquelles nous allons obtenir les
enregistrements. Si vous indiquez le nom de plusieurs
tables, vous faites une jointure. Pour davantage
d'informations sur la syntaxe des jointures, consultez
Section 13.1.7.1, « Syntaxe de JOIN
». Pour chaque table spécifiée, vous
pouvez éventuellement indiquer un alias.
tbl_name [[AS] alias] [[USE INDEX (key_list)] | [IGNORE INDEX (key_list)] | [FORCE INDEX (key_list)]]
L'utilisation de USE INDEX
,
IGNORE INDEX
, FORCE
INDEX
pour donner des conseils d'optimisation à
l'optimiseur d'index. Section 13.1.7.1, « Syntaxe de JOIN
».
En MySQL 4.0.14, vous pouvez utiliser SET
MAX_SEEKS_FOR_KEY=value
comme une alternative pour
forcer MySQL à choisir un scan d'index, plutôt qu'un scan
de table.
Vous pouvez faire référence à une table avec
nom_de_table
(au sein de la base de
données courante), ou avec
dbname.nom_de_table
pour expliciter le
nom de la base de données. Vous pouvez vous référer à un
champ avec nom_de_colonne
,
nom_de_table.nom_de_colonne
, ou
db_name.nom_de_table.nom_de_colonne
. Vous
n'êtes pas obligés d'indiquer de préfixe
nom_de_table
ou
db_name.nom_de_table
pour une référence
à un champ dans un SELECT
, à moins que
la référence ne soit ambigue. Consultez
Section 9.2, « Noms de bases, tables, index, colonnes et alias », pour des exemples
d'ambiguîtés qui nécessitent des formes plus explicites
de référence à des champs.
Depuis la version 4.1.0, vous êtes autorisés à spécifier
DUAL
comme nom de table, dans les
situations ou aucune table n'est référencé. C'est une
fonctionnalité pure de compatibilité, car certains autres
serveurs requièrent cette syntaxe.
mysql> SELECT 1 + 1 FROM DUAL;
-> 2
Une référence à une table peut être aliasée en
utilisant nom_de_table [AS] alias_name
:
mysql>SELECT t1.name, t2.salary FROM employee AS t1, info AS t2
->WHERE t1.name = t2.name;
mysql>SELECT t1.name, t2.salary FROM employee t1, info t2
->WHERE t1.name = t2.name;
Dans la clause WHERE
, vous pouvez
utiliser toutes les fonctions que MySQL supporte, hormis les
fonctions d'agrégation. See Chapitre 12, Fonctions à utiliser dans les clauses SELECT
et
WHERE
.
Les colonnes sélectionnées dans le résultat peuvent être
nommées dans les clauses ORDER BY
et
GROUP BY
en utilisant leur nom de
colonne, les alias ou leur position de colonne. Les
positions commencent à 1 :
mysql>SELECT college, region, seed FROM tournament
->ORDER BY region, seed;
mysql>SELECT college, region AS r, seed AS s FROM tournament
->ORDER BY r, s;
mysql>SELECT college, region, seed FROM tournament
->ORDER BY 2, 3;
Pour trier dans l'ordre inverse, ajoutez le mot-clé
DESC
(descendant) au nom du champ dans la
clause ORDER BY
qui vous permet de trier.
Par défaut, l'ordre ascendant est utilisé; ceci peut être
indiqué de fa¸on explicite en utilisant le mot-clé
ASC
.
L'utilisation des positions de colonnes est obsolète, car la syntaxe a été supprimée du SQL standard.
Si vous utilisez GROUP BY
, les lignes
sont triées en fonction des colonnes GROUP
BY
comme si on avait ajouté la clause
ORDER BY
pour ces colonnes. MySQL a
amélioré la clause GROUP BY
depuis la
version 3.23.34 pour que vous puissiez aussi spécifier
ASC
et DESC
après le
nom de la colonne :
SELECT a, COUNT(b) FROM test_table GROUP BY a DESC
MySQL améliore l'utilisation de GROUP BY
en vous autorisant à l'utiliser avec des champs qui ne sont
pas mentionnés dans la clause GROUP BY
.
Si vous n'obtenez pas les résultats que vous attendiez,
lisez la description de GROUP BY
. See
Section 12.9, « Fonctions et options à utiliser dans les clauses GROUP
BY
».
Depuis MySQL 4.1.1, GROUP BY
dispose de
l'option WITH ROLLUP
. See
Section 12.9.2, « Options de GROUP BY
».
La clause HAVING
peut faire référence
à n'importe quel champs ou alias défini dans
select_expr
. C'est évalué en dernier
lieu, juste avant que les éléments ne soient envoyés au
client, sans aucune optimisation.
N'utilisez pas HAVING
pour des éléments
qui devraient être dans la clause WHERE
.
Par exemple, n'écrivez pas ceci :
mysql> SELECT nom_de_colonne FROM nom_de_table HAVING nom_de_colonne > 0;
Ecrivez plutôt cela :
mysql> SELECT nom_de_colonne FROM nom_de_table WHERE nom_de_colonne > 0;
Dans les versions 3.22.5 et supérieures de MySQL, vous pouvez aussi écrire des requêtes ainsi :
mysql>SELECT user,MAX(salary) FROM users
->GROUP BY user HAVING MAX(salary)>10;
Dans des versions plus anciennes de MySQL, vous pouvez écrire à la place :
mysql>SELECT user,MAX(salary) AS sum FROM users
->group by user HAVING sum>10;
La clause HAVING
peut utiliser des
fonctions d'agrégation, alors que la clause
WHERE
ne le peut pas :
mysql>SELECT user, MAX(salary) FROM users
->GROUP BY user HAVING MAX(salary)>10;
Cependant, cela ne fonctionne pas dans les anciennes
versions du serveur MySQL, : avant la version 3.22.5. Au
lieu de cela, ajoutez un alias de colonne dans la liste de
colonnes, et faites référence à cet alias dans la colonne
HAVING
:
mysql>SELECT user, MAX(salary) AS max_salary FROM users
->GROUP BY user HAVING max_salary>10;
La clause LIMIT
peut être utilisée pour
limiter le nombre d'enregistrements retournés par la
commande SELECT
. LIMIT
accepte un ou deux arguments numériques. Ces arguments
doivent être des entiers constants.
Avec un argument, la valeur spécifie le nombre de lignes à retourner depuis le début du jeu de résultat. Si deux arguments sont donnés, le premier indique le décalage du premier enregistrement à retourner, le second donne le nombre maximum d'enregistrement à retourner. Le décalage du premier enregistrement est 0 (pas 1) :
Pour être compatible avec PostgreSQL, MySQL supporte aussi
la syntaxe : LIMIT row_count OFFSET
offset
.
mysql> SELECT * FROM table LIMIT 5,10; # Retourne les enregistrements 6 à 15
Pour obtenir tous les enregistrement d'un certain décalage jusqu'à la fin du résultat, vous pouvez utiliser de grands entier en tant que second paramètre :
mysql> SELECT * FROM table LIMIT 95,18446744073709551615; # Retourne les enregistrements de 96 jusqu'au dernier.
Si un seul argument est donné, il indique le nombre maximum d'enregistrements à retourner :
mysql> SELECT * FROM table LIMIT 5; # Retourne les 5 premiers enregistrements
Autrement dit, LIMIT n
est équivalent à
LIMIT 0,n
.
La forme SELECT ... INTO OUTFILE
'nom_fichier'
de SELECT
écrit
les lignes sélectionnées dans un fichier. Le fichier est
crée sur le serveur et ne peut y être déjà présent
(cela permet entre autre d'éviter la destruction des tables
et de fichiers tel que /etc/passwd
).
Vous devez avoir le droit FILE
sur le
serveur pour utiliser cette forme de
SELECT
.
SELECT ... INTO OUTFILE
à pour but
principal de vous permettre de réaliser des dumps rapides
des tables sur la machine serveur. Si vous voulez créer le
fichier sur une autre machine, vous ne pouvez utiliser
SELECT ... INTO OUTFILE
. Dans ce cas là,
vous pouvez utiliser à la place un programme client comme
mysqldump --tab
ou mysql -e
"SELECT ..." > fichier
pour générer le
fichier.
SELECT ... INTO OUTFILE
est le
complément de LOAD DATA INFILE
; La
syntaxe pour la partie export_options
de
la requête se compose des mêmes clauses
FIELDS
et LINES
que
celles utilisées avec la commande LOAD DATA
INFILE
. See Section 13.1.5, « Syntaxe de LOAD DATA INFILE
».
Dans le fichier résultant, seul les caractères suivants
sont protégés par le caractère ESCAPED
BY
:
Le caractère ESCAPED BY
Les premier caractère de FIELDS TERMINATED
BY
Les premier caractère de LINES TERMINATED
BY
ASCII 0
est convertit en
ESCAPED BY
suivi de 0 (ASCII
48
).
Si le caractère FIELDS ESCAPED BY
est
vide, aucun caractère n'est protégé, et
NULL
vaut NULL
, et non
\N
. Il est probable que ce ne soit pas
une bonne idée de spécifier un caractère de protection
vide, en particulier sir les valeurs de vos champs peuvent
être n'importe quoi.
La raison de ce qui précède est que vous devez
impérativement protéger chaque
caractère FIELDS TERMINATED BY
,
ESCAPED BY
, ou LINES TERMINATED
BY
pour assurer une relecture fiable du fichier.
Le caractère ASCII 0
est échappé pour
assurer la lisibilité sur certains clients.
Comme le fichier résultant ne se doit pas d'être syntaxiquement conforme à SQL, vous n'avez besoin d'échapper rien d'autre.
Voila un exemple de relecture de fichier au format utilisé par plusieurs anciens programmes.
SELECT a,b,a+b INTO OUTFILE '/tmp/result.text' FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' LINES TERMINATED BY '\n' FROM test_table;
Si vous utilisez INTO DUMPFILE
au lieu de
INTO OUTFILE
, MySQL n'écrira qu'une
seule ligne dans le fichier, sans aucun caractère de fin de
ligne ou de colonne, ni d'échappement. Cela est utile
lorsque vous voulez enregistrer un BLOB
dans un fichier.
Note : notez que les
fichiers crées par INTO OUTFILE
et
INTO DUMPFILE
sera lisible par tout les
utilisateurs ! La raison est que le serveur MySQL ne peut
créer de fichier appartenant à autre que l'utilisateur qui
l'a mis en route. (vous devez éviter d'exécuter
mysqld
en tant que root), le fichier doit
se composer de mot lisible pour que les données puissent
être récupérées.
Une clause PROCEDURE
indique une
procédure qui doit traiter les lignes du jeu de résultat.
Pour un exemple, voyez Section 27.3.1, « La procédure Analyse ».
Si vous utilisez la clause FOR UPDATE
avec un gestionnaire de tables qui gère les verrous de
lignes ou de pages, les lignes seront verrouillées.
Après le mot SELECT
, vous pouvez ajouter
certaines options qui affectent le comportement de la commande.
Les options DISTINCT
,
DISTINCTROW
et ALL
indiquent quels enregistrements avec doublons doivent être
retournés. Par défaut, c'est (ALL
),
retournant ainsi tous les enregistrements.
DISTINCT
et DISTINCTROW
sont synonymes et indique que les doublons doivent être
éliminés du résultat.
HIGH_PRIORITY
,
STRAIGHT_JOIN
, et les options commen¸ants
par SQL_
sont des extensions MySQL au
standard SQL.
HIGH_PRIORITY
donne à une commande
SELECT
une plus grande priorité qu'une
commande qui modifie une table. Vous devez l'utiliser
seulement pour les requêtes qui sont très rapides et qui
doivent être effectuées en premier lieu. Une requête
SELECT HIGH_PRIORITY
s'exécutera sur une
table verrouillée en lecture même si une commande de mise
à jour attend que la table soit libérée.
HIGH_PRIORITY
ne peut être utilisée
avec les commandes SELECT
qui font partie
d'une UNION
.
STRAIGHT_JOIN
force l'optimiseur à
joindre les tables dans l'ordre dans lequel elles sont
listées dans la clause FROM
. Vous pouvez
utiliser cela pour accélérer la requête, si les tables
sont réordonnées sub-optimalement par l'optimiseur. See
Section 7.2.1, « Syntaxe de EXPLAIN
(Obtenir des informations sur les
SELECT
) ». STRAIGHT_JOIN
peut aussi être utilisée dans la liste
table_references
. See
Section 13.1.7.1, « Syntaxe de JOIN
».
SQL_BIG_RESULT
peut être utilisé avec
GROUP BY
ou DISTINCT
pour indiquer à l'optimiseur que le résultat comportera
beaucoup d'enregistrements. Dans ce cas, MySQL utilisera si
besoin directement les bases temporaires stockées sur le
disque. MySQL préférera, dans ce cas, trier que d'obtenir
une table temporaire avec une clé sur les éléments du
GROUP BY
.
SQL_BUFFER_RESULT
forcera le résultat à
être stocké dans une table temporaire. Ceci va aider MySQL
à libérer plus tôt les verrous des tables et aidera aussi
dans les cas ou l'envoi du résultat au client prend un
temps assez conséquent.
SQL_SMALL_RESULT
, une option spécifique
à MySQL, peut être utilisée avec GROUP
BY
ou DISTINCT
pour indiquer à
l'optimiseur que le résultat sera petit. Dans ce cas, MySQL
utilise des tables temporaires rapides pour stocker la table
résultante plutôt que d'utiliser le tri. Dans MySQL 3.23,
ceci n'est normalement pas nécessaire.
SQL_CALC_FOUND_ROWS
(version 4.0.0 et
supérieure) indique à MySQL de calculer combien
d'enregistrements seront dans le jeu de résultats,
indépendamment de n'importe quelle clause
LIMIT
. Le nombre d'enregistrements peut
alors être obtenu avec SELECT
FOUND_ROWS()
. See
Section 12.8.4, « Fonctions diverses ».
Avant MySQL 4.1.0, cette option ne fonctionne pas avec
LIMIT 0
, qui est optimisée pour se
terminer instantanément (le résultat ne contiendra pas de
lignes). See Section 7.2.12, « Comment MySQL optimise LIMIT
».
SQL_CACHE
demande à MySQL de ne pas
stocker le résultat de la requête si vous utilisez
query_cache_type
avec la valeur
2
ou DEMAND
. Pour une
requête qui utilise UNION
ou une
sous-requête, cette option prend effet si elle est
utilisée dans n'importe quelle partie de la requête
SELECT
. See
Section 5.11, « Cache de requêtes MySQL ».
SQL_CACHE
indique à MySQL de stocker le
résultat de la requête dans le cache de requêtes si vous
utilisez QUERY_CACHE_TYPE=2
(DEMAND
). See
Section 5.11, « Cache de requêtes MySQL ». Pour les requêtes qui
utilisent UNION
ou les sous-requêtes,
cette option aura un effet sur toutes les parties de la
requête SELECT
.
MySQL supporte les syntaxes suivantes de
JOIN
pour une utilisation dans les
SELECT
:
reference_table, reference_table reference_table [CROSS] JOIN reference_table reference_table INNER JOIN reference_table condition_jointure reference_table STRAIGHT_JOIN reference_table reference_table LEFT [OUTER] JOIN reference_table condition_jointure reference_table LEFT [OUTER] JOIN reference_table reference_table NATURAL [LEFT [OUTER]] JOIN reference_table { OJ reference_table LEFT OUTER JOIN reference_table ON expr_conditionnelle } reference_table RIGHT [OUTER] JOIN reference_table condition_jointure reference_table RIGHT [OUTER] JOIN reference_table reference_table NATURAL [RIGHT [OUTER]] JOIN reference_table
où reference_table
est définie de la
manière suivante :
nom_de_table [[AS] alias] [USE INDEX (liste_de_clefs)] [IGNORE INDEX (liste_de_clefs)]
et condition_jointure
est définie comme
suit :
ON expr_conditionnelle | USING (column_list)
Généralement, vous ne devez avoir aucune condition, dans la
partie ON
, qui soit utilisée pour
spécifier les lignes que vous voulez obtenir en résultat.
(il y a des exceptions à cette règle). Si vous voulez
restreindre les lignes résultantes, vous devez le faire dans
la clause WHERE
.
Notez que dans les versions antérieures à la 3.23.17,
INNER JOIN
ne prenait pas en compte
condition_jointure
!
La dernière syntaxe de LEFT OUTER JOIN
vue
plus haut, n'existe que pour assurer la compatibilité avec
ODBC :
On peut créer un alias sur une référence de table en
utilisant nom_de_table AS alias_name
ou
nom_de_table alias_name
:
mysql>SELECT t1.name, t2.salary FROM employee AS t1, info AS t2
->WHERE t1.name = t2.name;
La condition ON
est de la même forme
qu'une condition pouvant être utilisée dans la clause
WHERE
.
Si aucune ligne ne correspond dans la table de droite dans
la partie ON
ou
USING
du LEFT JOIN
,
une ligne avec toutes les colonnes mises à
NULL
est utilisé en remplacement. Vous
pouvez utiliser ce fait pour trouver les enregistrements
dans une table qui n'ont pas de correspondances dans une
autre :
mysql>SELECT table1.* FROM table1
->LEFT JOIN table2 ON table1.id=table2.id
->WHERE table2.id IS NULL;
Cet exemple retourne toutes les lignes trouvées dans
table1
avec une valeur de
id
qui n'est pas présente dans
table2
(autrement dit, toutes les
lignes de table1
sans correspondances
dans la table table2
). Cela demande que
table2.id
soit déclaré NOT
NULL
, bien sur. See
Section 7.2.9, « Comment MySQL optimise les clauses LEFT JOIN
et
RIGHT JOIN
».
La clause USING
(column_list)
recense la liste des
colonnes qui doivent exister dans les deux tables. Les
clauses USING
suivantes sont
identiques :
a LEFT JOIN b USING (c1,c2,c3) a LEFT JOIN b ON a.c1=b.c1 AND a.c2=b.c2 AND a.c3=b.c3
La jointure de deux tables avec NATURAL [LEFT]
JOIN
est définie pour être sémantiquement
équivalent à un INNER JOIN
ou un
LEFT JOIN
avec une clause
USING
qui nomme toutes les colonnes qui
existent dans les deux tables.
INNER JOIN
et ,
(virgule) sont sémantiquement équivalents. Les deux
opèrent une jointure totale sur les tables utilisées.
Normalement, vous spécifiez les conditions de jointure
dans la clause WHERE
.
RIGHT JOIN
fonctionne de fa¸on
analogue à LEFT JOIN
. Pour garder un
code facilement portable, il est recommandé d'utiliser
les LEFT JOIN
à la place des
RIGHT JOIN
.
STRAIGHT_JOIN
est identique à
JOIN
, sauf que la table de gauche est
toujours lues avant celle de droite. Cela peut être
utilisé dans les cas (rares) où l'optimiseur des
jointures place les tables dans le mauvais ordre.
A partir de la version 3.23.12 de MySQL, vous pouvez donner
des indications à propos de l'index à utiliser lors de la
lecture d'informations d'une table. C'est utile si
EXPLAIN
montre que MySQL utilise un mauvais
index de la liste de ceux disponibles. En spécifiant
USE INDEX (liste_de_clefs)
, vous pouvez
forcer MySQL à utiliser un index spécifique pour trouver les
enregistrements dans la table. Une alternative réside dans
l'utilisation de IGNORE INDEX
(liste_de_clefs)
pour dire à MySQL de ne pas
utiliser certains index.
En MySQL 4.0.9, vous pouvez aussi utiliser la clause
FORCE INDEX
. Elle se comporte comme
USE INDEX (key_list)
mais en supposant que
les scan de tables seront très coûteux.
En d'autres termes, les scans de tables seront utilisés que
s'il n'y a pas d'autres méthodes pour trouver les lignes.
USE/IGNORE KEY
sont des synonymes de
USE/IGNORE INDEX
.
Note : USE
INDEX
, IGNORE INDEX
et
FORCE INDEX
affectent uniquement les index
qui sont utilisés lors du choix de la méthode de sélection
des lignes dans la table, et comment faire une jointure. Elles
n'affectent pas l'utilisation finale de l'index dans les
clauses ORDER BY
ou GROUP
BY
.
Quelques exemples :
mysql>SELECT * FROM table1,table2 WHERE table1.id=table2.id;
mysql>SELECT * FROM table1 LEFT JOIN table2 ON table1.id=table2.id;
mysql>SELECT * FROM table1 LEFT JOIN table2 USING (id);
mysql>SELECT * FROM table1 LEFT JOIN table2 ON table1.id=table2.id
->LEFT JOIN table3 ON table2.id=table3.id;
mysql>SELECT * FROM table1 USE INDEX (key1,key2)
->WHERE key1=1 AND key2=2 AND key3=3;
mysql>SELECT * FROM table1 IGNORE INDEX (key3)
->WHERE key1=1 AND key2=2 AND key3=3;
See Section 7.2.9, « Comment MySQL optimise les clauses LEFT JOIN
et
RIGHT JOIN
».
SELECT ... UNION [ALL | DISTINCT] SELECT ... [UNION [ALL | DISTINCT] SELECT ...]
UNION
est implémentée en MySQL 4.0.0.
UNION
est utilisé pour combiner le
résultat de plusieurs requêtes SELECT
en
un seul résultat.
Les colonnes listées dans la partie
select_expression
du
SELECT
doivent être du même type. Les
noms de colonnes utilisés dans le premier
SELECT
seront utilisé comme nom de champs
pour les résultats retournés.
Les commandes SELECT
sont des sélections
normales, mais avec les restrictions suivantes :
Seule la dernière commande SELECT
peut
avoir une clause INTO OUTFILE
.
HIGH_PRIORITY
ne peut être utilisée
avec les commandes SELECT
qui ne font
pas partie de l'UNION
. Si vous la
spécifiez pour la première commande
SELECT
, elle n'aura pas d'effet. Si
vous la spécifiez pour toute autre commandes
SELECT
suivante, une erreur de syntaxe
sera signalée.
Si vous n'utilisez pas le mot clef ALL
pour
l'UNION
, toutes les lignes retournées
seront uniques, comme si vous aviez fait un
DISTINCT
pour l'ensemble du résultat. Si
vous spécifiez ALL
, vous aurez alors tout
les résultats retournés par toutes les commandes
SELECT
.
Si vous voulez utiliser un ORDER BY
pour le
résultat final de UNION
, vous devez
utiliser des parenthèses :
(SELECT a FROM nom_de_table WHERE a=10 AND B=1 ORDER BY a LIMIT 10) UNION (SELECT a FROM nom_de_table WHERE a=11 AND B=2 ORDER BY a LIMIT 10) ORDER BY a;
Note : vous ne pouvez pas
mélanger les clauses UNION ALL
et
UNION DISTINCT
dans la même requête. Si
vous utilisez ALL
dans une des
UNION
, alors elle devra être utilisée
partout.
Les types et longueurs des colonnes du jeu de résultat de
UNION
prend en compte les valeurs lues dans
tous les SELECT
. Avant MySQL 4.1.1, une
limitation de UNION
est que seules les
valeurs du premier SELECT
étaient
utilisée pour déterminer le type de résultats, et leur
taille. Cela peut conduire à un raccourcissement de la valeur
si, par exemple, le second SELECT
trouvait
des valeurs plus grandes que le premier
SELECT
:
mysql> SELECT REPEAT('a',1) UNION SELECT REPEAT('b',10);
+---------------+
| REPEAT('a',1) |
+---------------+
| a |
| b |
+---------------+
Cette limitation a été supprimée en MySQL version 4.1.1 :
mysql> SELECT REPEAT('a',1) UNION SELECT REPEAT('b',10);
+---------------+
| REPEAT('a',1) |
+---------------+
| a |
| bbbbbbbbbb |
+---------------+
ANY
,
IN
et SOME
ALL
EXISTS
et NOT EXISTS
FROM
Une sous-requête est une commande SELECT
dans une autre commande. Par exemple :
SELECT * FROM table1 WHERE id IN (SELECT id FROM table2);
La requête externe (ou commande
externe), et (SELECT column1 FROM
t2)
est la sous-requête. Nous
disons que la sous-requête est imbriquée
dans la requête externe, et en fait, il est possible
d'imbriquer des requêtes dans des sous-requêtes, avec d'autres
commandes. Une sous-requête doit toujours être entre
parenthèses.
Depuis la version 4.1, MySQL supporte toutes les formes de sous-requêtes et opérations que le standard SQL requiert, ainsi que quelques fonctionnalités spécifiques. Les avantages des sous-requêtes sont :
Elles permettent aux requêtes d'être structuré pour que chaque partie puisse être isolée.
Elles fournissent une méthode pour réaliser des opérations qui seraient complexes, et impliqueraient des unions et jointures.
Elles sont, au dire de nombreuses personnes, lisibles. En
fait, c'est les sous-requêtes qui ont donné aux inventeurs
le nom original de SQL
``Structured Query Language''
.
Dans les versions plus anciennes de MySQL, il fallait trouver des palliatifs, et contourner les sous-requêtes. Il est bien plus facile de se mettre aux sous-requêtes.
Voici un exemple de commande qui montre les principaux avantages des sous-requêtes et de leur syntaxe, aussi bien pour celle qui est proposée par le standard, que celle de MySQL.
DELETE FROM t1 WHERE s11 > ANY (SELECT COUNT(*) /* no hint */ FROM t2 WHERE NOT EXISTS (SELECT * FROM t3 WHERE ROW(5*t2.s1,77)= (SELECT 50,11*s1 FROM t4 UNION SELECT 50,77 FROM (SELECT * FROM t5) AS t5)));
Pour les versions de MySQL antérieure à la version 4.1, la plupart des sous requêtes peuvent être réécrites avec des jointures et d'autres méthodes. See Section 13.1.8.11, « Se passer des sous-requêtes avec les premières versions de MySQL ».
Dans dans forme la plus simple, une sous-requête scalaire, par opposition à une sous-requête de ligne ou de table qui seront présentées plus loin, est un simple opérande. Vous pouvez l'utilisez à chaque fois qu'une valeur de colonne ou qu'une valeur littérale est valide, et vous pouvez en attendre les mêmes caractéristiques : type de données, taille et indication de nullité, etc. Par exemple :
CREATE TABLE t1 (s1 INT, s2 CHAR(5) NOT NULL); SELECT (SELECT s2 FROM t1);
La sous-requête de la commande SELECT
ci-dessus est de type CHAR
, de longueur 5.
Son jeu de caractères et sa collation sont ceux fournis par
défaut, et elle porte une marque de nullité. En fait, toutes
les sous-requêtes peuvent prendre la valeur
NULL
, car si la table est vide, la valeur
de la sous-requête sera alors NULL
. Il y a
quelques restrictions :
Une sous-requête peut être utilisée avec les commandes
suivantes : SELECT
,
INSERT
, UPDATE
,
DELETE
, SET
et
DO
.
Une sous-requête peut contenir les mots-clé et les
clauses qu'une commande SELECT
peut
contenir : DISTINCT
, GROUP
BY
, ORDER BY
,
LIMIT
, jointures,
UNION
, commentaires, fonctions, etc.
Ainsi, lorsque vous lirez les exemples des sections suivantes
qui utilisent la commande spartiate (SELECT column1
FROM t1)
, imaginez que votre code pourra contenir
des commandes bien plus diverses et complexes.
Par exemple, supposons que nous avons ces deux tables :
CREATE TABLE t1 (s1 INT); INSERT INTO t1 VALUES (1); CREATE TABLE t2 (s1 INT); INSERT INTO t2 VALUES (2);
Puis, que vous envoyons la commande suivante
SELECT
:
SELECT (SELECT s1 FROM t2) FROM t1;
Le résultat sera 2
car il y a une ligne
dans t2
, dont la colonne
s1
a une valeur de 2.
La sous-requête peut faire partie d'une expression. Si c'est un opérande d'une fonction, n'oubliez pas les parenthèses.
Par exemple :
SELECT UPPER((SELECT s1 FROM t1)) FROM t2;
L'utilisation la plus répandue des sous-requêtes est celle-ci :
<non-subquery operand> <comparison operator> (<subquery>)
où <comparison operator>
est l'un
des opérateurs suivants :
= > < >= <= <>
Par exemple :
... 'a' = (SELECT column1 FROM t1)
Il fut un temps où la seule place possible pour une sous-requête était à la droite de l'opérateur de comparaison, mais vous pourrez rencontrer de vieilles bases qui insisteront sur ce point.
Voici un exemple de comparaison classiques, pour lequel vous
ne pouvez pas utiliser de jointure : trouvez toutes les
valeurs de la table t1
qui sont égales au
maximum de la valeur dans la table t2
.
SELECT column1 FROM t1 WHERE column1 = (SELECT MAX(column2) FROM t2);
Voici un autre exemple, qui est aussi impossible à réaliser
avec une jointure, car elle impose l'agrégation de plusieurs
tables : trouver toutes les lignes de la table
t1
qui contiennent une valeur qui apparaît
deux fois.
SELECT * FROM t1 WHERE 2 = (SELECT COUNT(column1) FROM t1);
Syntaxe :
<operand> <comparison operator> ANY (<subquery>) <operand> IN (<subquery>) <operand> <comparison operator> SOME (<subquery>)
Le mot ANY
, qui doit suivre immédiatement
un opérateur de comparaison, signifie : ``retourne
TRUE
si la comparaison est
TRUE
pour UNE
des lignes
que la sous-requête retourne.'' Par exemple :
SELECT s1 FROM t1 WHERE s1 > ANY (SELECT s1 FROM t2);
Supposons qu'il y ait une ligne dans la table
t1
qui contienne {10}. L'expression est
TRUE
si la table t2
contient {21,14,7} car il y a une valeur de
t2
, 7, qui est inférieure à 10. Cette
expression est FALSE
si la table
t2
contient {20,10}, ou si la table
t2
est vide. L'expression est
UNKNOWN
si la table t2
contient
{NULL
,NULL
,NULL
}.
Le mot IN
est un alias de =
ANY
. Les deux commandes suivantes sont identiques :
SELECT s1 FROM t1 WHERE s1 = ANY (SELECT s1 FROM t2); SELECT s1 FROM t1 WHERE s1 IN (SELECT s1 FROM t2);
Le mot SOME
est un alias de
ANY
. Les deux commandes suivantes sont
identiques :
SELECT s1 FROM t1 WHERE s1 <> ANY (SELECT s1 FROM t2); SELECT s1 FROM t1 WHERE s1 <> SOME (SELECT s1 FROM t2);
L'utilisation du mot SOME
est rare, mais
les exemples ci-dessus montrent pourquoi il peut être utile.
En langage parlé, ``a n'est pas égal à aucun b'' signifie
pour la majorité des gens, ``il n'y a pas de b qui est égal
à a'' : ce n'est pas la signification de la syntaxe SQL. En
utilisant <> SOME
, vous pouvez vous
assurer que tout le monde comprend le véritable sens de la
commande.
Syntaxe :
<operand> <comparison operator> ALL (<subquery>)
Le mot ALL
, qui doit suivre immédiatement
l'opérateur de comparaison, signifie ``retourne
TRUE
si la comparaison est
TRUE
pour TOUTES
les
lignes que la sous-requête retourne''.
Par exemple :
SELECT s1 FROM t1 WHERE s1 > ALL (SELECT s1 FROM t2);
Supposons qu'il y ait une ligne dans la table
t1
contenant {10}. L'expression est
TRUE
si la table t2
contient {-5,0,+5} car les trois valeurs de
t2
sont inférieures à 10. L'expression
est FALSE
si la table t2
contient {12,6,NULL
,-100} car il y a une
des valeurs de la table t2
, ici 12, qui est
plus grande que 10. L'expression est
UNKNOWN
si la table t2
contient {0,NULL
,1}.
Finalement, si la table t2
est vide, le
résultat est TRUE
. Vous pouvez pensez que
le résultat doit être indéterminé
(UNKNOWN
), mais c'est bien
TRUE
. Ce qui fait que, bizarrement,
SELECT * FROM t1 WHERE 1 > ALL (SELECT s1 FROM t2);
est TRUE
si la table t2
est vide, mais
SELECT * FROM t1 WHERE 1 > (SELECT s1 FROM t2);
est UNKNOWN
si la table
t2
est vide. De plus,
SELECT * FROM t1 WHERE 1 > ALL (SELECT MAX(s1) FROM t2);
est UNKNOWN
si la table
t2
est vide. En général, les
tables avec des NULL
et les
tables vides sont des cas
particuliers : lorsque vous écrivez vos
sous-requêtes, pensez bien à les prendre en compte.
Jusqu'ici, nous avons étudié les sous-requêtes scalaires, ou de colonnes : des sous-requêtes qui retournent une seule valeur dans une ligne. Une sous-requête de ligne est une variante qui retourne une seule ligne : elle peut donc retourner plusieurs colonnes. Voici deux exemples :
SELECT * FROM t1 WHERE (1,2) = (SELECT column1, column2 FROM t2); SELECT * FROM t1 WHERE ROW(1,2) = (SELECT column1, column2 FROM t2);
Les requêtes ci-dessus sont toutes les deux
TRUE
si la table t2
a
une ligne où column1 = 1
et
column2 = 2
.
L'expression (1,2)
est parfois appelée un
constructeur de ligne et est valide dans
d'autres contextes. Par exemple, les deux commandes suivantes
sont sémantiquement équivalentes, même si la précédente
peut être optimisée :
SELECT * FROM t1 WHERE (column1,column2) = (1,1); SELECT * FROM t1 WHERE column1 = 1 AND column2 = 1;
L'utilisation traditionnelle des constructeurs de ligne est lors des comparaisons avec des sous-requêtes qui retournent plusieurs colonnes. Par exemple, cette requête répond à la question : ``trouve toutes les lignes de la table t1 qui sont dupliquées dans la table t2'':
SELECT column1,column2,column3 FROM t1 WHERE (column1,column2,column3) IN (SELECT column1,column2,column3 FROM t2);
Si une sous-requête retourne absolument aucune valeur, alors
la clause EXISTS <subquery>
est
TRUE
, et la clause NOT EXISTS
<subquery>
est FALSE
. Par
exemple :
SELECT column1 FROM t1 WHERE EXISTS (SELECT * FROM t2);
Traditionnellement, une sous-requête qui
EXISTS
commence avec SELECT
*
mais elle peut commencer aussi bien avec
SELECT 5
ou SELECT
column1
ou n'importe quoi d'autre encore : MySQL
ignore la liste de colonnes du SELECT
de
cette requête, ce qui fait que cela n'a pas d'importance.
Dans l'exemple ci-dessus, si la table t2
ne
contient aucune ligne, même pas de ligne avec uniquement des
valeurs NULL
, alors la condition
EXISTS
est TRUE
. C'est
un exemple plutôt exceptionnel, car il y a presque toujours
une sous-requête [NOT] EXISTS
qui
contiendra des corrélations. Voici des exemples plus
concrets :
Quel type de magasin est le plus fréquent dans une ou plusieurs villes?
SELECT DISTINCT store_type FROM Stores WHERE EXISTS (SELECT * FROM Cities_Stores WHERE Cities_Stores.store_type = Stores.store_type);
Quel type de magasin n'est présent dans aucune villes?
SELECT DISTINCT store_type FROM Stores WHERE NOT EXISTS (SELECT * FROM Cities_Stores WHERE Cities_Stores.store_type = Stores.store_type);
Quel type de magasin est présent dans toutes les villes?
SELECT DISTINCT store_type FROM Stores S1 WHERE NOT EXISTS ( SELECT * FROM Cities WHERE NOT EXISTS ( SELECT * FROM Cities_Stores WHERE Cities_Stores.city = Cities.city AND Cities_Stores.store_type = Stores.store_type));
Le dernier exemple est une double imbrication de requête
NOT EXISTS
: elle possède une clause
NOT EXISTS
à l'intérieur de la clause
NOT EXISTS
. Formellement, elle répond à
la question : ``Existe-t-il une ville avec un magasin qui
n'est pas dans Stores?''. Mais il est plus facile de dire
qu'une clause NOT EXISTS
imbriquée répond
à la question ``est-ce que x est vrai pour tous les y?''.
Une sous-requête corrélée est une sous-requête qui contient une référence à une colonne qui est aussi dans une requête différente.
Par exemple :
SELECT * FROM t1 WHERE column1 = ANY (SELECT column1 FROM t2 WHERE t2.column2 = t1.column2);
Notez que dans notre exemple, la sous-requête contient une
référence à une colonne de la table t1
,
même si la sous-requête de la clause FROM
ne mentionne pas la table t1
. MySQL
recherche hors de la requête et trouve t1
dans la requête externe.
Supposez que la table t1
contienne une
ligne où column1 = 5
et column2 =
6
; alors que la table t2
continue
une ligne où column1 = 5
et
column2 = 7
. l'expression ...
WHERE column1 = ANY (SELECT column1 FROM t2)
sera
alors TRUE
, mais dans cet exemple, la
clause WHERE
de la sous-requête est
FALSE
(car 7 <> 5), et donc, toute la
sous-requête est FALSE
.
Règles de contexte : MySQL fait les évaluations de l'intérieur vers l'extérieur. Par exemple :
SELECT column1 FROM t1 AS x WHERE x.column1 = (SELECT column1 FROM t2 AS x WHERE x.column1 = (SELECT column1 FROM t3 WHERE x.column2 = t3.column1));
Dans l'exemple ci-dessus, x.column2
doit
être une colonne de la table t2
car
SELECT column1 FROM t2 AS x ...
prend le
nom de t2
. ce n'est pas une colonne de la
table t1
car SELECT column1 FROM
t1 ...
est une requête externe, qui est
à venir.
Pour les sous-requêtes placées dans des clauses
HAVING
ou ORDER BY
,
MySQL recherche aussi les noms de colonnes dans la liste des
sélections externes.
Dans certains cas, les sous-requêtes corrélées sont optimisées. Par exemple :
val IN (SELECT key_val FROM tbl_name WHERE correlated_condition)
Sinon, elles sont inefficaces et plutôt lentes. Réécrire une requête sous forme de jointure peut améliorer les performances.
Les sous-requêtes sont valides dans la clause
FROM
d'une commande
SELECT
. Voici une syntaxe que vous allez
rencontrer :
SELECT ... FROM (<subquery>) AS <name> ...
La clause AS <name>
est obligatoire,
car les tables de la clause FROM
doivent
avoir un nom. Toutes les colonnes de la sous-requête
<subquery>
doivent avoir des noms
distincts. Vous pourrez trouver cette syntaxe décrite
ailleurs dans ce manuel, sous le nom de ``tables dérivées''.
Par exemple, supposons que vous avons cette table :
CREATE TABLE t1 (s1 INT, s2 CHAR(5), s3 FLOAT);
Comment utiliser la fonctionnalité de sous-requêtes dans la
clause FROM
, avec cette table d'exemple :
INSERT INTO t1 VALUES (1,'1',1.0); INSERT INTO t1 VALUES (2,'2',2.0); SELECT sb1,sb2,sb3 FROM (SELECT s1 AS sb1, s2 AS sb2, s3*2 AS sb3 FROM t1) AS sb WHERE sb1 > 1;
Résultat : 2, '2', 4.0.
Voici un autre exemple : supposons que vous voulez connaître la moyenne de la somme pour un groupe de table. Ceci ne fonctionnera pas :
SELECT AVG(SUM(column1)) FROM t1 GROUP BY column1;
Mais cette requête-ci vous donnera les informations nécessaires :
SELECT AVG(sum_column1) FROM (SELECT SUM(column1) AS sum_column1 FROM t1 GROUP BY column1) AS t1;
Notez que les colonnes sont nommées à partir de la
sous-requête : (sum_column1)
est reconnue
dans la requête externe.
Actuellement, les sous-requêtes en clause
FROM
ne peuvent pas être corrélées.
Il y a de nouvelles erreurs qui ne s'appliquent qu'aux sous-requêtes. Cette section les rassemble, car elles vous aideront à garder en tête certains points importants.
ERROR 1235 (ER_NOT_SUPPORTED_YET) SQLSTATE = 42000 Message = "This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'"
Cela signifie que
SELECT * FROM t1 WHERE s1 IN (SELECT s2 FROM t2 ORDER BY s1 LIMIT 1)
ne fonctionnera pas, mais uniquement dans certaines versions d'origines, comme MySQL 4.1.1.
ERROR 1240 (ER_CARDINALITY_COL) SQLSTATE = 21000 Message = "Operand should contain 1 column(s)"
Cette erreur va survient dans des cas comme celui-ci :
SELECT (SELECT column1, column2 FROM t2) FROM t1;
Il est valide d'utiliser une sous-requête qui utilise plusieurs colonnes, dans le cadre d'une comparaison. See Section 13.1.8.5, « Sous-requêtes de ligne ». Mais dans d'autres contextes, la sous-requête doit être un opérande scalaire.
ERROR 1241 (ER_SUBSELECT_NO_1_ROW) SQLSTATE = 21000 Message = "Subquery returns more than 1 row"
Cette erreur survient dans des cas comme celui-ci :
SELECT * FROM t1 WHERE column1 = (SELECT column1 FROM t2);
mais uniquement lorsque plus d'une ligne sont extraites de
t2
. Cela signifie que cette erreur peut
survenir dans du code qui fonctionne depuis longtemps :
quelqu'un vient de modifier le nombre de ligne que la
requête retourne. N'oubliez pas que si votre but est de
trouver un nombre arbitraire de lignes, et non pas juste
une seule, la commande correcte aurait été :
SELECT * FROM t1 WHERE column1 = ANY (SELECT column1 FROM t2);
Error 1093 (ER_UPDATE_TABLE_USED) SQLSTATE = HY000 Message = "You can't specify target table 'x' for update in FROM clause"
Cette erreur survient dans des cas comme celui-ci :
UPDATE t1 SET column2 = (SELECT MAX(column1) FROM t1);
Il est valide d'utiliser une sous-requête lors d'une
affectation dans une commande UPDATE
, car
les sous-requêtes sont valides avec les commandes
UPDATE
et DELETE
, tout
comme dans les commandes SELECT
. Cependant,
vous ne pouvez pas les utiliser sur la même table, qui est
ici t1
, car cette table est alors la cible
de la clause FROM
et de la commande
UPDATE
.
Généralement, l'échec d'un sous-requête entraîne l'échec de toute la commande.
Le développement des sous-requêtes se poursuit, et aucun des conseils d'optimisation ne sera valable longtemps. Voici quelques astuces que vous voulez prendre en compte :
Utiliser une clause de sous-requête pour affecter le nombre ou l'ordre des lignes dans une sous-requête, par exemple :
SELECT * FROM t1 WHERE t1.column1 IN (SELECT column1 FROM t2 ORDER BY column1); SELECT * FROM t1 WHERE t1.column1 IN (SELECT DISTINCT column1 FROM t2); SELECT * FROM t1 WHERE EXISTS (SELECT * FROM t2 LIMIT 1);
Remplacer une jointure par une sous-requête. Par exemple :
SELECT DISTINCT column1 FROM t1 WHERE t1.column1 IN ( SELECT column1 FROM t2);
au lieu de
SELECT DISTINCT t1.column1 FROM t1, t2 WHERE t1.column1 = t2.column1;
Déplacer une clause FROM
externe dans
une sous-requête, comme ceci :
SELECT * FROM t1 WHERE s1 IN (SELECT s1 FROM t1 UNION ALL SELECT s1 FROM t2);
au lieu de
SELECT * FROM t1 WHERE s1 IN (SELECT s1 FROM t1) OR s1 IN (SELECT s1 FROM t2);
Un autre exemple :
SELECT (SELECT column1 + 5 FROM t1) FROM t2;
au lieu de
SELECT (SELECT column1 FROM t1) + 5 FROM t2;
Utiliser une sous-requête de ligne plutôt qu'une corrélation. Par exemple :
SELECT * FROM t1 WHERE (column1,column2) IN (SELECT column1,column2 FROM t2);
au lieu de
SELECT * FROM t1 WHERE EXISTS (SELECT * FROM t2 WHERE t2.column1=t1.column1 AND t2.column2=t1.column2);
Utiliser NOT (a = ANY (...))
au lieu de
a <> ALL (...)
.
Utiliser x = ANY (table containing
{1,2})
plutôt que x=1 OR
x=2
.
Utiliser = ANY
de préférence à
EXISTS
Le truc ci-dessus peut accélérer certains programmes, et en
ralentir d'autres. En utilisant la fonction utilitaire
BENCHMARK()
, vous pouvez obtenir une idée
de votre cas. Ne vous attardez pas trop à transformer vos
jointures, sauf si la compatibilité avec les anciennes
versions est importante pour vous.
Quelques optimisation que MySQL va prendre en charge lui-même :
MySQL va exécuter les sous-requêtes non corrélées une
seule fois (utilisez la commande
EXPLAIN
pour vous assurer que les
requêtes ne sont pas correllées).
MySQL va transformer les sous-requêtes
IN
/ALL
/ANY
/SOME
pour essayer de profiter de la possibilité que les
colonnes sélectionnées dans la sous-requêtes sont
indexées.
MySQL remplacera les sous-requêtes de la forme
... IN (SELECT indexed_column FROM single_table ...)
par une recherche dans un index, que
EXPLAIN
décrira comme une jointure de
type spécial.
MySQL va améliorer les expressions de la forme
valeur {ALL|ANY|SOME} {> | < | >= | <=} (sous-requête non-correllée)
avec une expression impliquant MIN
ou
MAX
(à moins d'une valeur
NULL
ou d'ensembles
SET
vides). Par exemple,
WHERE 5 > ALL (SELECT x FROM t)
revient à
WHERE 5 > (SELECT MAX(x) FROM t)
Il y a un chapitre intitulé ``Comment MySQL adapte les
sous-requêtes'' dans les manuels internes de MySQL, que vous
pouvez trouver en téléchargeant les sources de MySQL : il
est dans un fichier appelé
internals.texi
, dans le dossier
Docs
.
Jusqu'à la version 4.1, seules les requêtes imbriquées de
la forme INSERT ... SELECT ...
et
REPLACE ... SELECT ...
étaient
supportées.
La clause IN()
peut être utilisée dans
certains contextes, pour tester la présence de valeur dans un
ensemble de données.
Il est souvent possible de réécrire une requête sans sous-requête :
SELECT * FROM t1 WHERE id IN (SELECT id FROM t2);
Cela peut se réécrire :
SELECT t1.* FROM t1,t2 WHERE t1.id=t2.id;
Les requêtes :
SELECT * FROM t1 WHERE id NOT IN (SELECT id FROM t2); SELECT * FROM t1 WHERE NOT EXISTS (SELECT id FROM t2 WHERE t1.id=t2.id);
peuvent être réécrites :
SELECT table1.* FROM table1 LEFT JOIN table2 ON table1.id=table2.id WHERE table2.id IS NULL;
Une clause LEFT [OUTER] JOIN
peut être
plus rapide qu'une sous-requête équivalent, car le serveur
va pouvoir l'optimiser bien mieux : c'est un fait qui n'est
pas spécifique à MySQL. Avant SQL-92, les jointures externes
n'existaient pas, et les sous-requêtes étaient la seule
méthode pour résoudre certains problèmes. Aujourd'hui, le
serveur MySQL et d'autres bases de données modernes offrent
toute une gamme de jointures externes.
Pour les sous-requêtes plus complexes, vous pouvez simplement
créer des tables temporaires pour contenir les résultats
intermédiaires. Dans certains cas, cela ne sera pas possible.
C'est notamment le cas des commandes de type
DELETE
, pour lesquelles le standard SQL ne
supporte pas les jointures, sauf pour les sous-requêtes. Dans
ces situations, trois solutions s'offrent à vous :
Passez en MySQL version 4.1.
Utilisez un langage de programmation procédural, comme
Perl
ou PHP
, pour
envoyer la requête SELECT
, lire les
clés primaires à effacer, et utiliser ces valeurs pour
soumettre des requêtes de type DELETE
(DELETE FROM ... WHERE ... IN (key1, key2,
...)
).
La troisième option est d'utiliser le client interactif
de mysql
pour construire et exécuter
une liste de commande DELETE
automatiquement, avec la fonction
CONCAT()
au lieu de l'opérateur
||
. Par exemple :
SELECT CONCAT('DELETE FROM tab1 WHERE pkid = ', "'", tab1.pkid, "'", ';') FROM tab1, tab2 WHERE tab1.col1 = tab2.col2;
Vous pouvez placer cette requête dans un fichier de
script, et rediriger son résultat vers le client en ligne
de commande mysql
, pour que ce dernier
lance une seconde instance de l'interprêteur :
shell> mysql --skip-column-names mydb < myscript.sql | mysql mydb
MySQL 4.0 supporte les commandes DELETE
multi-tables qui peuvent être utilisées pour effacer des
lignes dans une table en fonction d'informations qui sont dans
une autre table, ou même effacer des lignes simultanément
dans plusieurs tables. Les commandes UPDATE
multi-tables sont aussi supportés depuis la version 4.0.
TRUNCATE TABLE nom_de_table
Dans la version 3.23, TRUNCATE TABLE
est
équivalent à COMMIT ; DELETE FROM
nom_de_table
. See Section 13.1.1, « Syntaxe de DELETE
».
TRUNCATE TABLE
diffère de DELETE
FROM ...
des fa¸ons suivantes :
Implémentée comme une destruction/création de table, ce qui accélère la suppression des enregistrements.
Ne respecte pas les transactions. Vous aurez des erreurs si vous avez une transaction active ou une table protégée en écriture.
Ne retourne pas le nombre de lignes effacées.
Tant que le fichier de définition
nom_de_table.frm
est valide, la table
peut être recréée, me si les données ou un index a été
corrompu.
Le gestionnaire de table ne se souvient pas de la dernière
valeur AUTO_INCREMENT
utilisée, mais
peut commencer à compter depuis le début. C'est vrai pour
les tables MyISAM
,
ISAM
et BDB
.
TRUNCATE
est une extension Oracle SQL. Cette
commande a été ajoutée en MySQL 3.23.28, même si dans les
versions 3.23.28 à 3.23.32, le mot clé
TABLE
devait être omis.
UPDATE [LOW_PRIORITY] [IGNORE]tbl_name
SETcol_name1
=expr1
[,col_name2
=expr2
...] [WHEREwhere_definition
] [ORDER BY ...] [LIMITrow_count
]
Syntaxe multi-tables :
UPDATE [LOW_PRIORITY] [IGNORE]tbl_name
[,tbl_name
...] SETcol_name1
=expr1
[,col_name2
=expr2
...] [WHEREwhere_definition
]
UPDATE
met à jour des enregistrements dans
une tables avec de nouvelles valeurs. La clause
SET
indique les colonnes à modifier et les
valeurs à leur donner. La clause WHERE
, si
fournie, spécifie les enregistrements à mettre à jour. Sinon,
tous les enregistrements sont mis à jour. Si la clause
ORDER BY
est fournie, les enregistrements
seront mis à jour dans l'ordre spécifié.
La commande UPDATE
accepte les options
suivantes :
Si vous spécifiez le mot clef
LOW_PRIORITY
, l'exécution de
l'UPDATE
sera repoussé jusqu'à ce que
aucun client ne lise plus de la table.
Si vous spécifiez le mot clef IGNORE
, la
mise à jour ne s'interrompra pas même si on rencontre des
problèmes d'unicité de clefs durant l'opération. Les
enregistrements posant problèmes ne seront pas mis à jour.
Si vous accédez à une colonne d'une table
tbl_name
dans une expression,
UPDATE
utilisera la valeur courante de la
colonne. Par exemple, la requête suivante ajoute une année à
l'âge actuel de tout le monde :
mysql> UPDATE persondata SET age=age+1;
Les requêtes UPDATE
sont évaluées de
gauche à droite. Par exemple, la requête suivante double la
valeur de la colonnes âge, puis l'incrémente :
mysql> UPDATE persondata SET age=age*2, age=age+1;
Si vous changez la valeur d'une colonne en lui spécifiant sa valeur actuelle, MySQL s'en aper¸oit et ne fait pas la mise à jour.
UPDATE
retourne le nombre d'enregistrements
ayant changé. Depuis la version 3.22 de MySQL, la fonction
mysql_info()
de l'API C retourne le nombre de
colonnes qui correspondaient, le nombre de colonnes mises à
jour et le nombre d'erreurs générées pendant
l'UPDATE
.
Dans la version 3.23 de MySQL, vous pouvez utilisez le code
LIMIT #
pour vous assurer que seul un nombre
d'enregistrements bien précis est changé.
Avant MySQL 4.0.13, LIMIT
est une
restrictions sur le nombre de lignes affectées. Cette
clause stoppe dès que row_count
ont
été trouvées par la clause WHERE
.
Depuis la version 4.0.13, LIMIT
est une
restriction sur le nombre de lignes trouvées. La commande
s'arrête une fois que row_count
lignes
ont été trouvées par la clause WHERE
,
qu'elles ait été changées ou pas.
Ai une clause ORDER BY
est utilisée
(disponible depuis MySQL version 4.0.0), les lignes seront
modifiées selon cet ordre. Ce n'est vraiment utile qu'en
conjonction avec LIMIT
.
Depuis MySQL version 4.0.4, vous pouvez aussi faire des
opérations de UPDATE
qui couvrent plusieurs
tables :
UPDATE items,month SET items.price=month.price WHERE items.id=month.id;
L'exemple ci-dessus montre une jointure interne, en utilisant la
virgule comme séparateur, mais une commande
UPDATE
multi-table peut utiliser n'importe
quel type de jointure autorisée dans une commande
SELECT
, tel qu'un LEFT
JOIN
.
Note : vous ne pouvez pas utiliser ORDER BY
ou LIMIT
avec les UPDATE
multi-table.
ALTER DATABASE db_name alter_specification [, alter_specification] ... alter_specification: [DEFAULT] CHARACTER SET charset_name | [DEFAULT] COLLATE collation_name
ALTER DATABASE
vous permet de modifier les
caractéristiques générales d'une base de données. Ces
caractéristiques sont stockées dans le fichier
db.opt
du dossier de base. Pour utiliser
ALTER DATABASE
, vous avez besoin des droits
de ALTER
sur la base.
La clause CHARACTER SET
modifie le jeu de
caractères par défaut de la base. La clause
COLLATE
modifie la collation par défaut de
la base. Les noms de jeu de caractères et de collation sont
présentés dans la section Chapitre 10, Jeux de caractères et Unicode.
ALTER DATABASE
a été ajoutée MySQL 4.1.1.
ALTER [IGNORE] TABLE tbl_name alter_specification [, alter_specification] ... alter_specification: ADD [COLUMN] column_definition [FIRST | AFTER col_name ] | ADD [COLUMN] (column_definition,...) | ADD INDEX [index_name] [index_type] (index_col_name,...) | ADD [CONSTRAINT [symbol]] PRIMARY KEY [index_type] (index_col_name,...) | ADD [CONSTRAINT [symbol]] UNIQUE [index_name] [index_type] (index_col_name,...) | ADD [FULLTEXT|SPATIAL] [index_name] (index_col_name,...) | ADD [CONSTRAINT [symbol]] FOREIGN KEY [index_name] (index_col_name,...) [reference_definition] | ALTER [COLUMN] col_name {SET DEFAULT literal | DROP DEFAULT} | CHANGE [COLUMN] old_col_name column_definition [FIRST|AFTER col_name] | MODIFY [COLUMN] column_definition [FIRST | AFTER col_name] | DROP [COLUMN] col_name | DROP PRIMARY KEY | DROP INDEX index_name | DROP FOREIGN KEY fk_symbol | DISABLE KEYS | ENABLE KEYS | RENAME [TO] new_tbl_name | ORDER BY col_name | CONVERT TO CHARACTER SET charset_name [COLLATE collation_name] | [DEFAULT] CHARACTER SET charset_name [COLLATE collation_name] | DISCARD TABLESPACE | IMPORT TABLESPACE | table_options
ALTER TABLE
vous permet de changer la
structure d'une table existante. Par exemple, vous pouvez
ajouter ou supprimer des colonnes, des index, changer le type
des colonnes existantes, renommer ces colonnes, ou la table
elle-même. Vous pouvez de même changer le commentaire sur la
table, ou le type de celle-ci.
La syntaxe de nombreuses altérations est similaires aux clauses
de la commande CREATE TABLE
. See
Section 13.2.5, « Syntaxe de CREATE TABLE
».
Si vous utilisez ALTER TABLE
pour modifier
les spécifications d'une colonne mais que DESCRIBE
nom_de_table
vous indique que cette colonne n'a pas
été modifiée, il est possible que MySQL ait ignoré vos
modifications pour une des raisons décrite dans
Section 13.2.5.1, « Modification automatique du type de colonnes ». Par exemple, si vous
essayez de changer une colonne de type
VARCHAR
en CHAR
, MySQL
continuera d'utiliser VARCHAR
si la table
contient d'autres colonnes de taille variable.
ALTER TABLE
effectue une copie temporaire de
la table originale. Les modifications sont faites sur cette
copie, puis l'original est effacée, et enfin la copie est
renommée pour remplacer l'originale. Cette méthode permet de
rediriger toutes les commandes automatiquement vers la nouvelle
table sans pertes. Durant l'exécution de ALTER
TABLE
, la table originale est lisible par d'autres
clients. Les modifications et insertions sont reportées
jusqu'à ce que la nouvelle table soit prête.
Notez que si vous utilisez une autre option que
RENAME
avec ALTER TABLE
,
MySQL créera toujours une table temporaire, même si les
données n'ont pas besoin d'être copiées (comme quand vous
changez le nom d'une colonne). Nous avons prévu de corriger
cela dans les versions suivantes, mais comme la commande
ALTER TABLE
n'est pas utilisée très
souvent, cette correction ne fait pas partie de nos priorités.
Pour les tables MyISAM
, vous pouvez
accélérer la réindexation (qui est la partie la plus lente de
la modification d'une table) en donnant à la variable système
myisam_sort_buffer_size
une valeur plus
grande.
Pour utiliser ALTER TABLE
, vous devez
avoir les droits ALTER
,
INSERT
, et CREATE
sur
la table.
IGNORE
est une extension MySQL pour ANSI
SQL92. Cette option contrôle la fa¸on dont ALTER
TABLE
fonctionne s'il y a des duplications sur une
clef unique de la nouvelle table. Si
IGNORE
n'est pas spécifiée, la copie
est annulée et la table originale est restaurée. Si
IGNORE
est spécifiée, les lignes
contenant les éléments doublons de la table seront
effacées, hormis la première, qui sera conservée.
Vous pouvez effectuer plusieurs opérations de
ADD
, ALTER
,
DROP
, et CHANGE
dans
une même commande ALTER TABLE
. C'est une
extension de MySQL à la norme ANSI SQL92, qui n'autorise
qu'une seule modification par commande ALTER
TABLE
.
CHANGE nom_colonne
, DROP
nom_colonne
, et DROP INDEX
sont
des extensions de MySQL à la norme ANSI SQL92.
MODIFY
est une extension Oracle à
ALTER TABLE
.
Le mot optionnel COLUMN
est purement de
la fioriture et peut être ignoré.
Si vous utilisez ALTER TABLE nom_de_table RENAME TO
nouveau_nom
sans autre option, MySQL va simplement
renommer les fichiers qui correspondent à la table
nom_de_table
. Il n'y a pas de création
de fichier temporaire. See Section 13.2.9, « Syntaxe de RENAME TABLE
».
La définition create_definition
utilise
la même syntaxe pour les clauses ADD
et
CHANGE
que dans CREATE
TABLE
. Notez que cette syntaxe inclut le nom de la
colonne, et pas seulement son type See
Section 13.2.5, « Syntaxe de CREATE TABLE
».
Vous pouvez renommer une colonne avec la syntaxe
CHANGE ancien_nom_de_colonne
create_definition
. Pour cela, indiquez l'ancien
nom de la colonne, puis le nouveau nom et son type courant.
Par exemple, pour renommer une colonne de type
INTEGER
, de a
en
b
, vous pouvez faire ceci :
mysql> ALTER TABLE t1 CHANGE a b INTEGER;
Si vous ne voulez changer que le type de la colonne, avec la
clause CHANGE
vous devrez redonner le nom
de la colonne. Par exemple :
mysql> ALTER TABLE t1 CHANGE b b BIGINT NOT NULL;
Cependant, à partir de la version 3.22.16a de MySQL, vous
pouvez aussi utiliser la clause MODIFY
pour changer le type d'une colonne sans la renommer :
mysql> ALTER TABLE t1 MODIFY b BIGINT NOT NULL;
Si vous utilisez les clauses CHANGE
ou
MODIFY
pour réduire la taille d'une
colonne qui comportait un index sur une partie de la colonne
(par exemple, si vous aviez un index sur 10 caractères
d'une colonne de type VARCHAR
), vous ne
pouvez pas rendre la colonne plus petite que le nombre de
caractères indexés.
Quand vous changez le type d'une colonne avec
CHANGE
ou MODIFY
,
MySQL essaye de convertir les données au niveau type dans
la mesure du possible.
A partir de la version 3.22 de MySQL, vous pouvez utiliser
FIRST
ou ADD ... AFTER
nom_colonne
pour ajouter la colonne à un endroit
spécifique dans la table. Par défaut, la colonne est
ajoutée à la fin. A partir de la version 4.0.1, vous
pouvez aussi utiliser les mots clés
FIRST
et AFTER
avec
CHANGE
ou MODIFY
.
ALTER COLUMN
spécifie une nouvelle
valeur par défaut pour une colonne ou enlève l'ancienne.
si l'ancienne valeur est effacée et que la colonne peut
être NULL
, la nouvelle valeur par
défaut sera NULL
. Si la colonne ne peut
être NULL
, MySQL assigne une valeur par
défaut, comme défini dans Section 13.2.5, « Syntaxe de CREATE TABLE
».
DROP INDEX
supprime un index. C'est une
extension MySQL à la norme ANSI SQL92. See
Section 13.2.7, « Syntaxe de DROP INDEX
».
Si des colonnes sont effacées d'une table, ces colonnes sont aussi supprimés des index dont elles font partie. Si toutes les colonnes qui forment un index sont effacées, l'index lui même est supprimé.
Si une table ne comporte qu'une seule colonne, La colonne ne
peut être supprimée. Si vous voulez effacer la table,
utilisez la commande DROP TABLE
.
DROP PRIMARY KEY
supprime la clef
primaire. Si cette clef n'existe pas, cette commande
effacera le premier index UNIQUE
de la
table. (MySQL marque la première clef
UNIQUE
en tant que PRIMARY
KEY
si aucune PRIMARY KEY
n'a
été spécifiée explicitement.)
Si vous ajoutez un UNIQUE INDEX
ou
PRIMARY KEY
à une table, c'est
enregistré avant les index non-UNIQUE
pour que MySQL puisse détecter les valeurs dupliquées
aussi vite que possible.
ORDER BY
vous permet de créer une
nouvelle table tout en ordonnant les lignes par défaut.
Notez que cet ordre ne sera pas conservé après les
prochaines insertions et modifications. Dans certains cas,
cela aide MySQL si les colonnes sont dans l'ordre dans
lequel vous allez trier les valeurs. Cette option n'est
vraiment utile que si vous savez à l'avance dans quel ordre
vous effectuerez les tris : vous y gagnerez alors en
performances.
Si vous utilisez ALTER TABLE
sur une
table MyISAM
, tous les index non-uniques
sont créés par des opérations séparées. (comme dans
REPAIR
). Cela devrait rendre
ALTER TABLE
plus rapide quand vous avez
beaucoup d'index.
Depuis la version 4.0, la fonctionnalité ci-dessus peut
être activée explicitement. ALTER TABLE ...
DISABLE KEYS
force MySQL à ne plus mettre à jour
les index non-uniques pour les tables au format
MyISAM
. ALTER TABLE ... ENABLE
KEYS
doit alors être utilisé pour recréer les
index manquants. Comme MySQL le fait avec un algorithme
spécial qui est plus rapide que le fait d'insérer les
clefs une par une, désactiver les clefs peut vous faire
gagner en performances.
Les clauses FOREIGN KEY
et
REFERENCES
sont supportées par le moteur
de tables InnoDB
, qui implémente les
clauses ADD [CONSTRAINT [symbol]] FOREIGN KEY (...)
REFERENCES ... (...)
. See
Section 15.7.4, « Contraintes de clés étrangères FOREIGN KEY
». Pour les
autres moteurs de stockages, ces clauses sont lues mais
ignorées. La clause CHECK
est analysée
mais ignorée par tous les moteurs de stockage. See
Section 13.2.5, « Syntaxe de CREATE TABLE
». La raison pour accepter mais
ignorer ces clauses est que cela renforce la compatibilité
avec le code des autres serveurs SQL, et qu'il est possible
de créer des tables avec des références. See
Section 1.5.5, « Différences entre MySQL et le standard SQL-92 ».
Depuis MySQL 4.0.13, InnoDB
supporte
l'utilisation de ALTER TABLE
pour effacer
des clés étrangères :
ALTER TABLE yourtablename DROP FOREIGN KEY fk_symbol
Pour plus d'informations, voyez
Section 15.7.4, « Contraintes de clés étrangères FOREIGN KEY
».
ALTER TABLE
ignore les options de tables
DATA DIRECTORY
et INDEX
DIRECTORY
.
Depuis MySQL 4.1.2, si vous voulez changer dans toutes les
colonnes de texte (CHAR
,
VARCHAR
, TEXT
) le jeu
de caractères, vous pouvez utiliser la commande suivante :
ALTER TABLE tbl_name CONVERT TO CHARACTER SET charset_name;
C'est pratique lorsque vous passez de MySQL 4.0.x en 4.1.x. See Section 10.10, « Préparer le passage de version 4.0 en 4.1 ».
Attention : l'opération
précédente va convertir les valeurs des colonnes entre les
deux jeux de caractères. Ce n'est pas
ce que vous souhaitez faire si une colonne est de type
latin1
mais que les valeurs sont en fait
dans un autre jeu de caractères (comme
utf8
). Dans ce cas, vous devez faire ceci
avec une telle colonne :
ALTER TABLE t1 CHANGE c1 c1 BLOB; ALTER TABLE t1 CHANGE c1 c1 TEXT CHARACTER SET utf8;
La raison est que dans ce cas, il n'y aura pas de conversion
lorsque vous passer en type BLOB
.
Pour ne changer que le type de caractères par défaut, utilisez cette commande :
ALTER TABLE tbl_name DEFAULT CHARACTER SET charset_name;
Le mot DEFAULT
est optionnel. Le jeu de
caractères par défaut est utilisé si vous ne spécifiez
pas le jeu de caractères de la colonne explicitement,
lorsque vous ajoutez une nouvelle colonne : par exemple,
avec ALTER TABLE ... ADD column
.
Attention : depuis MySQL
4.1.2 et plus récent, ALTER TABLE ... DEFAULT
CHARACTER SET
et ALTER TABLE ...
CHARACTER SET
sont équivalent et ne changent que
le jeu de caractères par défaut. Dans les versions
antérieures à MySQL 4.1.2, ALTER TABLE ...
DEFAULT CHARACTER SET
changeait le jeu de
caractères par défaut, mais ALTER TABLE ...
CHARACTER SET
(sans DEFAULT
)
changeait le jeu de caractères par défaut, et
convertissaient les colonnes dans le nouveau jeu.
Pour une table InnoDB
qui a été créée
avec son propre espace de tables dans un fichier
.ibd
, ce fichier peut être supprimé
et importé. Pour supprimer le fichier
.ibd
, utilisez la commande suivante :
ALTER TABLE tbl_name DISCARD TABLESPACE;
Elle efface le fichier .ibd
courant,
alors assurez vous que vous avez une copie de sauvegarde. Si
vous tentez d'accéder à un espace de table sans ce
fichier, vous obtiendrez une erreur.
Pour importer un fichier de sauvegarde
.ibd
dans la table, copiez le nouveau
fichier dans le dossier de la base, et utilisez cette
commande :
ALTER TABLE tbl_name IMPORT TABLESPACE;
See Section 15.7.6, « Espaces de tables multiples : chaque table InnoDB
a
son fichier .ibd
».
Avec la fonction mysql_info()
de l'API C,
vous pouvez savoir combien d'enregistrements ont été
copiés, et (quand IGNORE
est spécifié)
combien d'enregistrements ont été effacés à cause de la
clef unique. See Section 24.2.3.31, « mysql_info()
».
Voilà un exemple qui montre quelques utilisations de
ALTER TABLE
. On commence par une table
t1
créée comme suit :
mysql> CREATE TABLE t1 (a INTEGER,b CHAR(10));
Pour renommer la table de t1
à
t2
:
mysql> ALTER TABLE t1 RENAME t2;
Pour changer une colonne a
de
INTEGER
en TINYINT NOT
NULL
(en laissant le même nom), et pour changer une
colonne b
de CHAR(10)
à
CHAR(20)
et la renommant de
b
en c
:
mysql> ALTER TABLE t2 MODIFY a TINYINT NOT NULL, CHANGE b c CHAR(20);
Pour ajouter une nouvelle colonne TIMESTAMP
nommée d
:
mysql> ALTER TABLE t2 ADD d TIMESTAMP;
Pour ajouter un index sur une colonne d
, et
rendre la colonne a
la clef primaire :
mysql> ALTER TABLE t2 ADD INDEX (d), ADD PRIMARY KEY (a);
Pour effacer la colonne c
:
mysql> ALTER TABLE t2 DROP COLUMN c;
Pour ajouter une nouvelle colonne
AUTO_INCREMENT
nommée
c
:
mysql> ALTER TABLE t2 ADD c INT UNSIGNED NOT NULL AUTO_INCREMENT,
ADD INDEX (c);
Notez que nous avons indexé c
, car les
colonnes AUTO_INCREMENT
doivent être
indexées, et que nous définissons aussi c
en tant que NOT NULL
, car les colonnes
indexées ne peuvent être NULL
.
Quand vous ajoutez une colonne
AUTO_INCREMENT
, les valeurs de la colonne
sont remplies automatiquement pour vous. Vous pouvez choisir la
valeur de départ pour l'indexation en utilisant SET
INSERT_ID=#
avant ALTER TABLE
ou en
utilisant l'option AUTO_INCREMENT = #
de la
table. See Section 13.5.2.8, « Syntaxe de SET
».
Avec les tables de type MyISAM
, si vous ne
changez pas la colonne AUTO_INCREMENT
,
l'indice d'auto-incrémentation ne sera pas affecté. Si vous
effacez une colonne AUTO_INCREMENT
puis en
ajoutez une autre, l'indexation recommencera à partir de 1.
CREATE DATABASE [IF NOT EXISTS] db_name [create_specification [, create_specification] ...] create_specification: [DEFAULT] CHARACTER SET charset_name | [DEFAULT] COLLATE collation_name
CREATE DATABASE
crée une base de données
avec le nom donné.
Les règles de nommage des bases de donnée sont présentées
dans la section Section 9.2, « Noms de bases, tables, index, colonnes et alias ». Une erreur
survient si une base de données de même nom existe déjà, si
vous ne spécifiez pas l'option IF NOT
EXISTS
.
Depuis MySQL 4.1.1, les options
create_specification
peuvent être données
pour spécifier des caractéristiques de la base. Les
caractéristiques de la base sont stockées dans le fichier
db.opt
dans le dossier de la base. La
clause CHARACTER SET
spécifie le jeu de
caractères par défaut pour les tables de cette base. La clause
COLLATE
spécifie la collation par défaut de
la base de données. Les jeux de caractères et les collations
sont présentées dans la section Chapitre 10, Jeux de caractères et Unicode.
Les bases de données MySQL sont implémentées comme des
répertoires contenant des fichiers qui correspondent aux tables
dans les bases de données. Puisqu'il n'y a pas de tables dans
une base de données lors de sa création, la requête
CREATE DATABASE
créera seulement le dossier
dans le répertoire de données de MySQL (et le fichier
db.opt
, depuis MySQL 4.1.1).
Vous pouvez aussi créer des bases de données avec
mysqladmin
. See Section 8.4, « mysqladmin
, administration d'un serveur MySQL ».
CREATE [UNIQUE|FULLTEXT|SPATIAL] INDEX index_name [index_type] ON tbl_name (index_col_name,...) index_col_name: col_name [(length)] [ASC | DESC]
La requête CREATE INDEX
n'effectue aucune
action sur les versions de MySQL antérieures à la version
3.22. Dans les versions 3.22 et supérieures, CREATE
INDEX
est équivalent à une requête ALTER
TABLE
pour créer des index. See
Section 13.2.2, « Syntaxe de ALTER TABLE
».
Normalement, tous les index sont créés en même temps que la
table elle même avec CREATE TABLE
. See
Section 13.2.5, « Syntaxe de CREATE TABLE
». CREATE INDEX
permet d'ajouter des index à une table existante.
Une liste de colonnes de la forme
(col1,col2,...)
crée un index
multi-colonnes. Les valeurs de l'index sont créées en
concaténant la valeur deux colonnes données.
Pour les colonnes CHAR
et
VARCHAR
, les index peut être créés sur
uniquement une partie de la colonne, avec la syntaxe
col_name(length)
. Pour les colonnes
BLOB
et TEXT
la longueur
d'index est obligatoire. La requête
suivante crée un index en utilisant les 10 premiers caractères
de la colonne name
:
mysql> CREATE INDEX part_of_name ON customer (name(10));
Comme la plupart des noms ont en général des différences dans
les 10 premiers caractères, l'index ne devrait pas être plus
lent qu'un index créé à partir de la colonne
name
en entier. Ainsi, en n'utilisant qu'une
partie de la colonne pour les index, on peut réduire la taille
du fichier d'index, ce qui peut permettre d'économiser beaucoup
d'espace disque, et peut aussi accélérer les opérations
INSERT
!
Il est important de savoir qu'on peut indexer une colonne qui
peut avoir la valeur NULL
ou une colonne
BLOB
/TEXT
que si on
utilise une version 3.23.2 ou supérieure de MySQL et en
utilisant le type MyISAM
.
Pour plus d'informations à propos de l'utilisation des index dans MySQL, voir Section 7.4.5, « Comment MySQL utilise les index ».
Les index FULLTEXT
ne peuvent indexer que des
colonnes VARCHAR
ou TEXT
,
et seulement dans les tables MyISAM
. Les
index FULLTEXT
sont disponibles dans les
versions 3.23.23 et supérieures de MySQL.
Section 12.6, « Recherche en texte intégral (Full-text
) dans MySQL ».
Les index SPATIAL
peuvent indexer les
colonnes spatiales, et uniquement avec les tables
MyISAM
. Les index SPATIAL
sont disponibles en MySQL 4.1 et plus récent. Les colonnes
spatiales sont présentées dans section
Chapitre 18, Données spatiales avec MySQL.
CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name [(create_definition,...)] [table_options] [select_statement]
ou :
CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name [(] LIKE old_tbl_name [)]; create_definition: column_definition | [CONSTRAINT [symbol]] PRIMARY KEY [index_type] (index_col_name,...) | KEY [index_name] [index_type] (index_col_name,...) | INDEX [index_name] [index_type] (index_col_name,...) | [CONSTRAINT [symbol]] UNIQUE [INDEX] [index_name] [index_type] (index_col_name,...) | [FULLTEXT|SPATIAL] [INDEX] [index_name] (index_col_name,...) | [CONSTRAINT [symbol]] FOREIGN KEY [index_name] (index_col_name,...) [reference_definition] | CHECK (expr) column_definition: col_name type [NOT NULL | NULL] [DEFAULT default_value] [AUTO_INCREMENT] [[PRIMARY] KEY] [COMMENT 'string'] [reference_definition] type: TINYINT[(length)] [UNSIGNED] [ZEROFILL] | SMALLINT[(length)] [UNSIGNED] [ZEROFILL] | MEDIUMINT[(length)] [UNSIGNED] [ZEROFILL] | INT[(length)] [UNSIGNED] [ZEROFILL] | INTEGER[(length)] [UNSIGNED] [ZEROFILL] | BIGINT[(length)] [UNSIGNED] [ZEROFILL] | REAL[(length,decimals)] [UNSIGNED] [ZEROFILL] | DOUBLE[(length,decimals)] [UNSIGNED] [ZEROFILL] | FLOAT[(length,decimals)] [UNSIGNED] [ZEROFILL] | DECIMAL(length,decimals) [UNSIGNED] [ZEROFILL] | NUMERIC(length,decimals) [UNSIGNED] [ZEROFILL] | DATE | TIME | TIMESTAMP | DATETIME | CHAR(length) [BINARY | ASCII | UNICODE] | VARCHAR(length) [BINARY] | TINYBLOB | BLOB | MEDIUMBLOB | LONGBLOB | TINYTEXT | TEXT | MEDIUMTEXT | LONGTEXT | ENUM(value1,value2,value3,...) | SET(value1,value2,value3,...) | spatial_type index_col_name: col_name [(length)] [ASC | DESC] reference_definition: REFERENCES tbl_name [(index_col_name,...)] [MATCH FULL | MATCH PARTIAL] [ON DELETE reference_option] [ON UPDATE reference_option] reference_option: RESTRICT | CASCADE | SET NULL | NO ACTION | SET DEFAULT table_options: table_option [table_option] ... table_option: {ENGINE|TYPE} = {BDB|HEAP|ISAM|InnoDB|MERGE|MRG_MYISAM|MYISAM} | AUTO_INCREMENT = value | AVG_ROW_LENGTH = value | CHECKSUM = {0 | 1} | COMMENT = 'string' | MAX_ROWS = value | MIN_ROWS = value | PACK_KEYS = {0 | 1 | DEFAULT} | PASSWORD = 'string' | DELAY_KEY_WRITE = {0 | 1} | ROW_FORMAT = { DEFAULT | DYNAMIC | FIXED | COMPRESSED } | RAID_TYPE = { 1 | STRIPED | RAID0 } RAID_CHUNKS = value RAID_CHUNKSIZE = value | UNION = (tbl_name[,tbl_name]...) | INSERT_METHOD = { NO | FIRST | LAST } | DATA DIRECTORY = 'absolute path to directory' | INDEX DIRECTORY = 'absolute path to directory' | [DEFAULT] CHARACTER SET charset_name [COLLATE collation_name] select_statement: [IGNORE | REPLACE] [AS] SELECT ... (Some legal select statement)
CREATE TABLE
Crée une table avec le nom
donné, dans la base de données courante. Vous avez besoin des
droits de CREATE
pour créer une table.
Les règles de nommage des tables sont disponibles dans Section 9.2, « Noms de bases, tables, index, colonnes et alias ». Par défaut, une table est créée dans la base de données courante. Une erreur est affichée s'il n'y a pas de base courante, si la base de données n'existe pas ou si la table existe déjà.
En MySQL 3.22 et plus récent, le nom de la table peut être
spécifié avec la syntaxe db_name.tbl_name
,
pour créer une table dans une base spécifique. Cela fonctionne
même s'il n'y a pas de base courante. Si vous utilisez les
identifiants protégez, et mettez le nom de la base et de lui de
la table entre guillemets, séparément. Par exemple,
`madb`.`matbl`
est valide, mais
`madb.matbl`
ne l'est pas.
Depuis la version 3.22 de MySQL, vous pouvez utiliser le mot
réservé TEMPORARY
lorsque vous créez une
table. Une table temporaire sera immédiatement effacée dès
que la connexion se termine. Cela signifie que vous pouvez
utiliser le même nom de table temporaire depuis deux connexions
différentes sans risque de conflit entre les connexions. Vous
pouvez aussi utiliser une table temporaire qui a le même nom
qu'une table existante (la table existante est alors cachée
tant que dure la table temporaire). En MySQL version 4.0.2 ou
plus récent, vous avez juste à avoir le privilège
CREATE TEMPORARY TABLES
pour créer des
tables temporaires.
Depuis la version 3.23 de MySQL, vous pouvez utiliser le mot
réservé IF NOT EXISTS
, de fa¸on à ce
qu'aucune erreur ne soit affiché si la table que vous essayez
de créer existe déjà. Notez qu'il n'y a pas de comparaisons
entre les structures de table lors du test d'existence.
MySQL représente chaque table par un fichier de définition de
table .frm
, placé dans le dossier de la
base de données. Le moteur de la table peut créer d'autres
fichiers complémentaires. Dans le cas des tables
MyISAM
, le moteur de stockage utilise trois
fichiers, avec le nom nom_de_table
:
Fichier | Rôle |
nom_de_table.frm | Fichier de définition de la table |
nom_de_table.MYD | Fichier de données |
nom_de_table.MYI | Fichier d'index |
Les fichiers créés par les moteurs de stockages pour représenter les tables sont décrits dans la section Chapitre 14, Moteurs de tables MySQL et types de table.
Pour des informations générales sur les propriétés des différentes colonnes, voyez Chapitre 11, Types de colonnes. Pour des informations sur les types de données spatiaux, voyez Chapitre 18, Données spatiales avec MySQL.
Si ni NULL
, ni NOT
NULL
n'est spécifié, une colonne utilisera par
défaut l'attribut NULL
(elle acceptera
les valeurs NULL
).
Une colonne de nombre entier peut se voir attribuer
l'attribut AUTO_INCREMENT
. Lorsque vous
insérez la valeur NULL
(recommandée) ou
0
dans une colonne
AUTO_INCREMENT
, la colonne prendra
automatiquement la valeur de value+1
, où
value est la plus grande valeur positive courante dans cette
colonne. La série des valeurs
AUTO_INCREMENT
commence à
1
. See Section 24.2.3.33, « mysql_insert_id()
».
Depuis MySQL 4.1.1, en spécifiant l'option
NO_AUTO_VALUE_ON_ZERO
pour le mode
--sql-mode
ou la variable serveur
sql_mode
permet de stocker la valeur
0
dans les colonnes de type
AUTO_INCREMENT
, au lieu de voir
0
prendre le prochain numéro de
séquence. See Section 5.2.1, « Options de ligne de commande de mysqld
».
Note : Il ne peut y avoir
qu'une seule colonne de type
AUTO_INCREMENT
dans une table, et elle
doit être indexée. MySQL version 3.23 ne fonctionnera
correctement que si cette colonne n'accueille que des
valeurs positives. Insérer un nombre négatif sera
considéré comme insérer un nombre de très grande taille,
mais positif. Ceci est fait pour éviter les problèmes de
précision lorsque les nombres passe de positif à négatif
lorsqu'ils atteignent leur valeur maximale positive. C'est
aussi pour éviter qu'une colonne de type
AUTO_INCREMENT
ne contienne de valeur 0.
Si vous effacez la ligne contenant la valeur maximale dans
la colonne AUTO_INCREMENT
, cette valeur
sera réutilisée dans les tables de type
ISAM
mais pas dans les tables de type
MyISAM
. Si vous effacez toutes les lignes
dans la table avec la commande DELETE FROM
nom_de_table
(sans la clause
WHERE)
en mode
AUTOCOMMIT
, la série des valeurs
AUTO_INCREMENT
recommencera à
0
.
Avec les tables MyISAM
et
BDB
, vous pouvez spécifier une colonne
secondaire d'AUTO_INCREMENT
dans une clef
multi-colonnes. See
Section 3.6.9, « Utiliser AUTO_INCREMENT
».
Pour rendre MySQL avec certaines applications
ODBC
, vous pouvez retrouver la valeur de
la dernière valeur automatiquement générée avec la
requête suivante :
SELECT * FROM nom_de_table WHERE auto_col IS NULL
Depuis MySQL 4.1, la définition des colonnes peut inclure
un attribut CHARACTER SET
pour spécifier
le jeu de caractères, et éventuellement la collation de la
colonne. Pour des détails, voyez Chapitre 10, Jeux de caractères et Unicode.
CREATE TABLE t (c CHAR(20) CHARACTER SET utf8 COLLATE utf8_bin);
Depuis la version 4.1 aussi, MySQL interprète les spécifications de longueur de colonne en caractères. Les anciennes versions l'interprète comme des octets.
La valeur NULL
est traitée différemment
dans les colonnes de type TIMESTAMP
. Vous
ne pouvez pas stocker de valeur NULL
littérale dans une colonne TIMESTAMP
;
insérer une valeur NULL
dans une telle
colonne revient à insérer la date et l'heure courante. Car
les colonnes TIMESTAMP
ignorent les
attributs NULL et NOT NULL
.
Cela facilite grandement l'utilisation des colonnes
TIMESTAMP
pour les clients MySQL : le
serveur indique que ces colonnes peuvent se voir assigner
une valeur NULL
(ce qui est vrai), même
si les colonnes TIMESTAMP
ne contiendront
jamais de valeur NULL
. Vous pouvez le
constater lorsque vous utiliser la commande
DESCRIBE
nom_de_table
pour avoir une description de votre table.
Notez qu'affecter la valeur 0
à une
colonne TIMESTAMP
n'est pas la même
chose que lui affecter la valeur NULL
,
car 0
est une valeur
TIMESTAMP
valide.
Une valeur DEFAULT
doit être une
constante, ¸a ne peut être une fonction ou une expression.
Cela signifie notamment que vous ne pouvez pas donner une
valeur par défaut à une colonne de date, le résultat de
la fonction NOW()
ou
CURRENT_DATE
.
Si aucune valeur par défaut (attribut
DEFAULT
) n'est spécifiée, MySQL en
assigne une automatiquement
Si la colonne accepte les valeur NULL
, la
valeur par défaut sera la valeur NULL
.
Si la colonne est déclarée comme NOT
NULL
(non-nulle), la valeur par défaut dépendra
du type de colonne :
Pour les types numériques sans l'attribut
AUTO_INCREMENT
, la valeur sera
0
. Pour une colonne
AUTO_INCREMENT
, la valeur par défaut
sera la prochaine valeur de la série.
Pour les types dates et heures autres que
TIMESTAMP
, la valeur par défaut est
la date zéro appropriée. Pour les colonnes
TIMESTAMP
, la valeur par défaut est
la date et l'heure courante. See
Section 11.3, « Les types date et heure ».
Pour les types de chaînes autres que
ENUM
, la valeur par défaut est la
chaîne vide. Pour ENUM
, la valeur
par défaut est la première valeur de l'énumération.
Les colonnes BLOB
et
TEXT
ne peuvent pas recevoir de valeur
par défaut.
Un commentaire pour une colonne peut être spécifiée avec
COMMENT
. Le commentaire est affiché par
la commande SHOW CREATE TABLE
, et par
SHOW FULL COLUMNS
. Cette option est
disponible depuis MySQL 4.1. Il était autorisé, mais
ignoré dans les anciennes versions.
Depuis MySQL version 4.1.0, l'attribut
SERIAL
peut être utilisé comme alias
pour les colonnes BIGINT UNSIGNED NOT NULL
AUTO_INCREMENT UNIQUE
. C'est une fonctionnalité
de compatibilité.
KEY
est un synonyme de
INDEX
. Depuis la version 4.1, l'attribut
de clé PRIMARY KEY
peut aussi être
spécifié avec la clause KEY
. Il a été
implémenté pour assurer la compatibilité avec les autres
bases.
Avec MySQL, une clé UNIQUE
peut avoir
uniquement avoir deux valeurs distinctes. Une erreur
surviendra si vous essayez d'ajouter une ligne dont la clé
correspond à une ligne existante.
Une clé primaire (PRIMARY KEY
) est un
index UNIQUE
avec la contrainte
supplémentaire que les toutes les colonnes utilisées doit
avoir l'attribut NOT NULL
. En MySQL,
cette clé est dite PRIMARY
. Une table ne
peut avoir qu'une seule clé primaire. Si vous n'avez pas de
PRIMARY KEY
et que des applications
demandent la PRIMARY KEY
dans vos tables,
MySQL retournera la première clé
UNIQUE
, qui n'a aucune valeur
NULL
.
Dans une table créée, la clé primaire PRIMARY
KEY
est placée en première, suivie de tous les
index UNIQUE
, et enfin, les index
non-unique. Cela permet à l'optimiseur MySQL d'utiliser en
priorité les index, et de détecter rapidement les doublons
pour les clés UNIQUE
.
Une PRIMARY KEY
peut être
multi-colonnes. Cependant, vous ne pouvez pas créer d'index
multi-colonnes avec l'attribut PRIMARY
KEY
dans une spécification de colonne. En faisant
cela, le seul résultat sera que cette seule colonne sera
marquée comme clé primaire. Vous devez absolument utiliser
la syntaxe PRIMARY KEY
(index_nom_de_colonne
, ...).
Si une clé primaire (PRIMARY
) ou unique
(UNIQUE
) est établit sur une seule
colonne, et que cette colonne est de type entier, vous
pouvez aussi faire référence à cette colonne sous le nom
_rowid
(nouveau en version 3.23.11).
Avec MySQL, le nom de la clé primaire PRIMARY
KEY
est PRIMARY
. Si vous ne
donnez pas de nom à un index, l'index prendra le nom de la
première colonne qui le compose, avec éventuellement un
suffixe (_2
, _3
, ...)
pour le rendre unique. Vous pouvez voir les noms des index
avec la commande SHOW INDEX FROM
tbl_name
. See Section 13.5.3.6, « Syntaxe de SHOW DATABASES
».
Depuis MySQL 4.1.0, certains moteurs de stockage vous
permettent de spécifier un type d'index lors de la
création d'un index. La syntaxe de
index_type
est USING
type_name
. Les valeurs possibles de
type_name
qui sont supportées par les
différents moteurs de stockages sont listés ci-dessous.
Lorsque des index multiples sont listés, le premier
rencontré est celui par défaut, si aucun
index_type
n'est spécifié.
Moteur de table | Types d'index |
MyISAM | BTREE |
InnoDB | BTREE |
MEMORY/HEAP | HASH , BTREE |
Exemple :
CREATE TABLE lookup (id INT, INDEX USING BTREE (id)) ENGINE = MEMORY;
TYPE type_name
peut être utilisé comme
synonyme de USING type_name
, pour
spécifier un type d'index. Cependant,
USING
est la forme recommandée. De plus,
le nom d'index qui précède le type d'index dans la syntaxe
de spécification n'est pas optionnelle avec
TYPE
. Ceci est dû au fait que
contrairement à USING
,
TYPE
n'est pas un mot réservé, et donc,
il pourrait être interprété comme un nom d'index.
Si vous spécifiez un type d'index qui n'est pas légal pour le moteur de stockage, mais qu'il y a un autre type d'index que le moteur peut utiliser sans affecter les résultats de la requête, le moteur utilisera ce type en remplacement.
Seuls, les formats de table MyISAM
,
InnoDB
, et BDB
supportent des index sur des colonnes qui peuvent contenir
des valeurs NULL
. Dans les autres
situations, vous devez déclarer ces colonnes NOT
NULL
ou une erreur sera générée.
Avec la syntaxe nom_de_colonne(longueur)
,
vous pouvez spécifier un index qui n'utilise qu'une partie
de la colonne CHAR
ou
VARCHAR
. Cela peut réduire la taille des
fichiers d'index. See Section 7.4.3, « Index de colonnes ».
Le format de table MyISAM
, et depuis la
version MySQL 4.0.14, InnoDB
, supportent
l'indexation des colonnes BLOB
et
TEXT
. Lorsque vous ajoutez un index à
une colonne BLOB
ou
TEXT
, vous devez
absolument spécifier une longueur
d'index :
CREATE TABLE test (blob_col BLOB, INDEX(blob_col(10)));
Le préfixe peut valoir jusqu'à 255 octets de long (où
1000 octets pour les tables MyISAM
et
InnoDB
depuis MySQL 4.1.2). Notez que le
préfixe est mesuré en octets, alors que la longueur du
préfixe de CREATE TABLE
est interprété
comme un nombre de caractères. Prenez cela en compte
lorsque vous spécifiez une longueur de préfixe pour une
colonne dont le jeu de caractères est multi-octets.
Une spécification index_col_name
peut se
terminer avec ASC
ou
DESC
. Ces mots clés sont prévus pour
des extensions futures qui permettront un stockage dans un
ordre donné. Actuellement, ils sont reconnus mais
ignorés : les index sont stockés en ordre ascendant.
Lorsque vous utilisez une clause ORDER BY
ou GROUP BY
sur une colonne de type
TEXT
ou BLOB
, seuls,
les max_sort_longueur
premiers octets
seront lus. See Section 11.4.3, « Les types BLOB
et TEXT
».
En MySQL version 3.23.23 ou plus récent, vous pouvez aussi
créer des index spécial FULLTEXT
. Ils
sont utilisés pour faire des recherches en texte plein.
Seul, le format de table MyISAM
supporte
les index FULLTEXT
. Ils peuvent être
créés uniquement pour les colonnes de type
VARCHAR
et TEXT
.
L'indexation est alors exécutée sur toute la colonne, et
les indexations partielles ne sont pas supportées. Voir
Section 12.6, « Recherche en texte intégral (Full-text
) dans MySQL » pour les détails.
En MySQL version 4.1 ou plus récent, vous pouvez créer les
index spéciaux SPATIAL
pour les colonnes
géographiques. Les types spatiaux sont supportés par les
tables MyISAM
, et les colonnes indexées
doivent être déclarées comme NOT NULL
.
Voyez Chapitre 18, Données spatiales avec MySQL.
En MySQL version 3.23.44 et plus récent, les tables
InnoDB
supportent la vérification de
clé étrangères. See Chapitre 15, Le moteur de tables InnoDB
. Notez que
la syntaxe des clés étrangères FOREIGN
KEY
de InnoDB
est plus
restrictive que la syntaxe présentée ci-dessus.
InnoDB
ne permet pas la spécification
d'un index_name
, et les colonnes de la
table référencée doivent être explicitement nommées.
Depuis la version 4.0.8, InnoDB
supporte
les clauses ON DELETE
et ON
UPDATE
avec les clés étrangères. Voyez le
manuel InnoDB
pour la syntaxe précise.
Section 15.7.4, « Contraintes de clés étrangères FOREIGN KEY
».
Pour les autres types de tables, le serveur MySQL n'analyse
pas les clauses FOREIGN KEY
,
CHECK
et REFERENCES
dans les commandes CREATE TABLE
, et
aucune action n'est réalisée. See
Section 1.5.5.5, « Les clés étrangères ».
Pour les tables MyISAM
et
ISAM
, chaque colonne
NULL
requiert un bit supplémentaire,
arrondi à l'octet supérieur le plus proche.
La taille maximale d'enregistrement peut être calculée comme ceci :
row longueur = 1 + (somme des longueurs de colonnes) + (nombre de colonnes NULL + 7)/8 + (nombre de colonnes à taille variable)
delete_flag
vaut 1 pour les tables avec
un format fixe. Les tables à format fixe utilisent un bit
dans les lignes pour un marqueur, qui indique si la ligne a
été effacée. delete_flag
vaut 0 pour
les tables à ligne dynamique, car le marquer est stocké
dans l'entête de la ligne.
Ces calculs ne s'appliquent pas aux tables
InnoDB
, qui ne font pas la différente
entre les colonnes NULL
et les colonnes
NOT NULL
.
Les options options_de_table
et
SELECT
ne sont implémentées que dans MySQL
version 3.23 et plus récent.
Les options ENGINE
et TYPE
spécifie le type de moteur de table. ENGINE
a été ajouté en MySQL 4.0.18, pour la série des 4.0 et
4.1.2, pour la série des 4.1. C'est le nom d'attribut
recommandé pour ces versions et TYPE
est
maintenant abandonné. TYPE
sera supporté
dans les séries 4.x, mais abandonnée probablement en MySQL
5.1.
Les différents types de tables sont :
Table type | Description |
ARCHIVE | Le moteur d'archivage. See Section 14.7, « Le moteur de table ARCHIVE ». |
BDB | Tables avec transactions. See Section 14.4, « Tables BDB ou BerkeleyDB ». |
BerkeleyDB | Un alias de BDB . |
CSV | Tables qui stockent les lignes au format valeurs séparées par des
virgules. See Section 14.8, « Le moteur CSV ». |
EXAMPLE | Un moteur d'exemple. See Section 14.5, « Le moteur de table EXAMPLE ». |
FEDERATED | Un moteur qui accède à des tables distantes. See
Section 14.6, « Le moteur de table FEDERATED ». |
HEAP | Les données de ces tables ne sont stockées qu'en mémoire. See
Section 14.3, « Le moteur de table MEMORY (HEAP ) ». |
ISAM | Le gestionnaire originel de tables. See
Section 14.9, « Tables ISAM ». |
InnoDB | Tables transactionnelles avec verrou de lignes. See
Chapitre 15, Le moteur de tables InnoDB . |
MEMORY | Un alias de HEAP . (En fait, depuis MySQL 4.1,
MEMORY est le terme recommandé.) |
MERGE | Un ensemble de tables MyISAM utilisées comme une
seule et même table. See
Section 14.2, « Tables assemblées MERGE ». |
MRG_MyISAM | Un synonyme pour les tables MERGE. |
MyISAM | Le nouveau gestionnaire de table binaire et portable. See
Section 14.1, « Le moteur de tables MyISAM ». |
NDB | Alias de NDBCLUSTER . |
NDBCLUSTER | Tables en grappe et en mémoire, tolérantes aux pannes. See Chapitre 16, Introduction à MySQL Cluster. |
See Chapitre 14, Moteurs de tables MySQL et types de table.
Si un type de table est demandé, mais que ce type particulier
n'est pas disponible, MySQL va choisir le type de table le plus
proche de celui qui est spécifié. Par exemple, si
TYPE=BDB
est spécifié, et que la
distribution de MySQL ne supporte pas les tables
BDB
, la table qui sera créée sera du type
MyISAM
.
Les autres options de tables sont utilisées pour optimiser le comportement de la table. Dans la plupart des cas, vous n'avez pas à les spécifier. Les options fonctionnent pour tous les types de tables (sauf contre-indication) :
AUTO_INCREMENT
La prochaine valeur AUTO_INCREMENT
de
votre table (MyISAM
). Ne fonctionne que
pour les tables MyISAM
. Pour donner la
première valeur à une colonne
AUTO_INCREMENT
InnoDB
,
insérez une ligne bidon, avec la valeur désirée moins un,
puis supprimez la ligne.
AVG_ROW_LENGTH
La taille moyenne approchée des lignes de votre table. Vous ne devez fournir cette valeur que pour les tables à taille de ligne variable, de très grande taille.
Lorsque vous créer une table MyISAM
,
MySQL utilise le produit des options
MAX_ROWS
et
AVG_ROW_LENGTH
pour décider de la taille
du résultat. Si vous ne spécifiez aucune option, la taille
maximale de la table sera de 4 Go (ou 2 Go si votre système
d'exploitation ne supporte que les tables de 2 Go). Ceci
sert à conserver la taille des pointeurs d'index petite, et
rapide, si nous n'avez pas besoin de gros fichiers. Si vous
voulez que vos tables dépassent 4 Go de taille, et que vous
voulez garder les tables petites taille un peu plus lentes
et grosses que nécessaire, vous pouvez augmenter la taille
du pointeur d'index en modifiant la variable système
globale myisam_data_pointer_size
, qui a
été ajoutée en MySQL 4.1.2. See
Section 5.2.3, « Variables serveur système ».
CHECKSUM
Passez 1 si vous voulez que MySQL génère une somme de
vérification (ce qui facilite la recherche des lignes
corrompues, mais ralentit les mises à jour). La commande
CHECKSUM TABLE
rapporte cette somme.
MyISAM
uniquement.
COMMENT
Un commentaire pour votre table (60 caractères).
MAX_ROWS
Nombre de lignes maximum que vous pensez stocker dans la table.
MIN_ROWS
Nombre de minimum lignes que vous pensez stocker dans la table.
PACK_KEYS
Spécifiez 1 si vous voulez un index plus compact. Généralement cela rend les mises à jour plus lentes, mais les lectures plus rapides.
Spécifier la valeur de 0 désactive tout le compactage de
clé. Spécifier la valeur DEFAULT
(MySQL
4.0) indique au moteur de stockage de ne stocker que les
colonnes CHAR
/VARCHAR
.
(MyISAM
et ISAM
uniquement)
Si vous n'utilisez pas PACK_KEYS
, le
comportement par défaut est de ne stocker que les chaînes,
et non pas les nombres. Si vous utilisez
PACK_KEYS=1
, les nombres seront aussi
compactés.
Lors du compactage, MySQL utilise une compression de préfixe :
Chaque clé requiert un octet de plus pour indiquer combien d'octets sont identiques dans la clé précédente.
Le pointeur de ligne est stocké au format grand-octet-en-premier, directement après la clé, pour améliorer la compression.
Cela signifie que si vous avez de nombreuses clés proches
sur des lignes consécutives, les clés successives
``identiques'' ne prendront généralement que deux octets
(incluant le pointeur de ligne). Comparez cela à la
situation ordinaire, où les clés successives occupent
taille_de_cle + taille_de_pointeur
(où
la taille du pointeur est généralement de 4). En
conséquence, vous tirerez le meilleur parti de cette
compression si vous avez plusieurs nombres identiques. Si
toutes les clés sont totalement différentes, vous
utiliserez un octet de plus par clé, si la clé n'accepte
pas les valeurs NULL
. Dans ce cas, la
taille de la clé sera stockée dans le même octet que
celui qui indique que la clé est NULL
.)
PASSWORD
Chiffre le fichier .frm
avec un mot de
passe. Cette option ne fait rien du tout pour la version
standard de MySQL.
DELAY_KEY_WRITE
Spécifiez 1 si vous voulez attendre la fermeture de la
table pour mettre à jour les index.
MyISAM
uniquement.
ROW_FORMAT
Définit la méthode de stockage des lignes (réservé pour
le futur). Actuellement, cette option fonctionne uniquement
avec des tables MyISAM
qui supportent le
DYNAMIC
et FIXED
en
format de ligne. See Section 14.1.3, « Formats de table MyISAM
».
L'option RAID_TYPE
vous permet de
dépasser la limite de 2 Go/4 Go de votre fichier de
données MyISAM
(mais pas le fichier
d'index), pour les systèmes d'exploitation qui ne
supportent pas les grands fichiers. Cette option n'est pas
recommandée pour les systèmes d'exploitation qui
supportent les grands fichiers.
Vous pouvez réduire les ralentissements d'E/S en pla¸ant
les dossiers RAID
sur différents disques
physiques. Actuellement, le seul type
RAID_TYPE
est STRIPED
.
1
et RAID0
sont des
alias de STRIPED
.
Si vous spécifiez l'option RAID_TYPE
pour une table MyISAM
, spécifiez les
options RAID_CHUNKS
et
RAID_CHUNKSIZE
en même temps. La valeur
maximale de RAID_CHUNKS
est 255.
MyISAM
va créer
RAID_CHUNKS
sous-dossiers appelés
00
, 01
,
02
, ... 09
,
0a
, 0b
, ... dans
le dossier de données. Dans chaque dossier,
MyISAM
va créer un fichier
tbl_name.MYD
. Lors de l'écriture dans
le fichier de données, le gestionnaire
RAID
place les
RAID_CHUNKSIZE*1024
premiers octets dans
le premier fichier, les seconds
RAID_CHUNKSIZE*1024
octets dans le
fichier suivant, etc.
RAID_TYPE
fonctionne sur tous les
systèmes d'exploitation, tant que vous avez compilé MySQL
avec --with-raid
, avec le script
configure
. Pour déterminer si votre
serveur a le support des tables RAID
,
utilisez SHOW VARIABLES LIKE 'have_raid'
pour voir si sa valeur vaut YES
.
UNION
UNION
sert lorsque vous voulez que
plusieurs tables identiques se comporte comme une seule
table. Cela fonctionne avec les tables
MERGE
. See
Section 14.2, « Tables assemblées MERGE
».
Pour le moment, vous devez avoir les droits de
SELECT
, UPDATE
et
DELETE
pour les tables intégrées dans
la table MERGE
. Originalement, toutes les
tables utilisées devaient être dans la même base de
données, que la table MERGE
. Cette
restriction a été levée depuis MySQL 4.1.1.
INSERT_METHOD
Si vous voulez insérer des données dans une table
MERGE
, vous devez spécifier la table
d'insertion avec l'attribut
INSERT_METHOD
. L'option
INSERT_METHOD
est utilisée uniquement
avec les tables MERGE
. Cette option a
été introduite en MySQL 4.0.0. See
Section 14.2, « Tables assemblées MERGE
».
DATA DIRECTORY
, INDEX
DIRECTORY
En utilisant DATA DIRECTORY='directory'
ou INDEX DIRECTORY='directory'
, vous
pouvez spécifier où le moteur de stockage
MyISAM
doit placer les données de la
table et le fichier d'index. Notez que vous devez donner un
chemin absolu, et non un chemin relatif.
Ces options ne fonctionnent que pour les tables
MyISAM
depuis MySQL 4.0, lorsque vous
n'utilisez pas l'option --skip-symlink
.
Votre système d'exploitation doit aussi disposer d'une
fonction realpath()
compatible avec les
threads. See Section 7.6.1.2, « Utiliser les liens symboliques avec les tables sous Unix ».
Depuis MySQL 3.23, vous pouvez créer une table à partir d'une
autre, en ajoutant une commande SELECT
après
la commande CREATE TABLE
:
CREATE TABLE new_tbl SELECT * FROM orig_tbl;
MySQL va créer une nouvelle colonne pour chaque colonne de
résultat de la commande SELECT
. Par
exemple :
mysql>CREATE TABLE test (a INT NOT NULL AUTO_INCREMENT,
->PRIMARY KEY (a), KEY(b))
->TYPE=MyISAM SELECT b,c FROM test2;
Cela créer une table MyISAM
avec trois
colonnes a
, b
, et
c
. Notez que les colonnes de la commande
SELECT
sont ajoutées à droite de la table,
et non dans la liste des colonnes. Par exemple :
mysql>SELECT * FROM foo;
+---+ | n | +---+ | 1 | +---+ mysql>CREATE TABLE bar (m INT) SELECT n FROM foo;
Query OK, 1 row affected (0.02 sec) Records: 1 Duplicates: 0 Warnings: 0 mysql>SELECT * FROM bar;
+------+---+ | m | n | +------+---+ | NULL | 1 | +------+---+ 1 row in set (0.00 sec)
Pour chaque ligne de la table foo
, une ligne
est insérée dans la colonne bar
avec la
valeur issue de foo
et la valeur par défaut
pour les nouvelles colonnes.
Si une erreur survient durant la copie de la table, la table est automatiquement effacée.
CREATE TABLE ... SELECT
ne va pas créer
automatiquement les index pour vous. Ceci est fait
intentionnellement pour rendre la commande aussi souple que
possible. Si vous voulez avoir les mêmes index, vous devez les
spécifier dans la commande avant le
SELECT
:
mysql> CREATE TABLE bar (UNIQUE (n)) SELECT n FROM foo;
Certaines conversions de type pourraient avoir lieu. Par
exemple, l'attribut AUTO_INCREMENT
n'est pas
préservé, et les colonnes VARCHAR
peuvent
devenir des colonnes CHAR
.
Lors de la création de la table avec CREATE ...
SELECT
, assurez vous de mettre un nom d'alias à
toutes les fonctions ou expression de la requête. Si vous ne le
faîtes pas, la commande CREATE
peut échouer
ou donner des noms de colonnes inattendus.
CREATE TABLE artists_and_works SELECT artist.name, COUNT(work.artist_id) AS number_of_works FROM artist LEFT JOIN work ON artist.id = work.artist_id GROUP BY artist.id;
Depuis MySQL 4.1, vous pouvez spécifier explicitement le type de colonne généré :
CREATE TABLE foo (a TINYINT NOT NULL) SELECT b+1 AS a FROM bar;
En MySQL 4.1, vous pouvez aussi utiliser la clause
LIKE
pour créer une table basée sur la
définition d'une autre table, y compris les attributs de
colonnes et les index originaux :
CREATE TABLE new_tbl LIKE orig_tbl;
CREATE TABLE ... LIKE
ne copie pas les
options de tables DATA DIRECTORY
et
INDEX DIRECTORY
qui étaient spécifiées
dans la table originale.
Vous pouvez faire précéder SELECT
par
IGNORE
ou REPLACE
pour
indiquer comment gérer les clés doublons. Avec
IGNORE
, les nouvelles lignes qui sont en
double seront ignorés. Avec REPLACE
, les
nouvelles lignes remplaceront les lignes précédentes, qui
avaient la même valeur d'index. Si ni
IGNORE
, ni REPLACE
ne sont
spécifié, les doublons génèreront une erreur.
Pour s'assurer que le log binaire peut être réutilisé pour
recréer la table originale, MySQL ne permettra pas les
insertions concurrentes durant une commande CREATE
TABLE ... SELECT
.
Dans certains cas, MySQL change automatiquement la
spécification d'une colonne fournie dans la commande
CREATE TABLE
. (Cela peut aussi arriver avec
ALTER TABLE
) :
Les colonnes VARCHAR
avec une taille
inférieure à quatre (4) sont changées en
CHAR
.
Si l'une des colonnes d'une table est de taille variable,
toute la ligne est, par conséquent, de taille variable.
Ainsi, si une ligne contient une colonne de taille
variable (VARCHAR
,
TEXT
ou BLOB
) toutes
les colonnes CHAR
de plus de trois
caractères sont transformées en
VARCHAR
. Cela ne change en rien la
fa¸on dont vous utilisez les colonnes. Pour MySQL,
VARCHAR
est simplement une autre fa¸on
de stocker les caractères. MySQL effectue cette
conversion car cela économise de la place, et rend les
calculs sur les tables plus rapides. See
Chapitre 14, Moteurs de tables MySQL et types de table.
Depuis la version 4.1.0, si un champ
CHAR
ou VARCHAR
est
spécifié avec une taille supérieure à 255, il est
converti en TEXT
. C'est une
fonctionnalité de compatibilité.
La taille d'affichage de TIMESTAMP
doit
être un nombre pair et être compris entre 2 et 14. (2,
4, 6, 8, 10, 12 ou 14). Si vous spécifiez une taille plus
grande que 14, ou inférieure à 2, celle-ci sera
transformée en 14. Les valeurs impaires sont ramenées à
la valeur pair supérieure la plus proche.
Vous ne pouvez pas stocker de valeur littérale
NULL
dans une colonne de type
TIMESTAMP
. Cette valeur sera remplacée
par la date et l'heure courante. De ce fait, les attributs
NULL
et NOT NULL
n'ont pas de sens pour ces colonnes et sont ignorés.
DESCRIBE nom_de_table
indiquera
toujours que la colonne TIMESTAMP
accepte les valeurs NULL
.
Les colonnes qui font partie d'une PRIMARY
KEY
ont l'attribut NOT NULL
même si elles ne sont pas déclarées comme tel.
Depuis MySQL 3.23.51, les espaces terminaux sont
automatiquement supprimés des valeurs
ENUM
et SET
lors de
la création de la table.
MySQL change certains type de colonnes utilisés par d'autres serveurs SQL en types MySQL. See Section 11.7, « Utilisation des types de données issues d'autres SGBDR ».
Si vous utilisez une clause USING
pour
spécifier un type d'index qui n'est pas légal pour un
moteur de stockage, mais qu'un autre type d'index est
disponible pour ce moteur sans affecter les résultats, le
moteur utilisera le type disponible.
Si vous voulez voir si MySQL a utilisé un autre type que
celui que vous avez spécifié, utilisez la commande
DESCRIBE nom_de_table
, après votre
création ou modification de structure de table.
Certain types de colonnes peuvent être modifiés si vous
compressez une table en utilisant l'utilitaire
myisampack
. See
Section 14.1.3.3, « Caractéristiques des tables compressées ».
DROP DATABASE [IF EXISTS] db_name
DROP DATABASE
détruit toutes les tables dans
la base de données et l'efface elle même. Soyez
très prudent avec cette commande! Pour
utiliser la commande DROP DATABASE
, vous avez
besoin du droit de DROP
sur cette base.
Depuis la version 3.22 de MySQL, vous pouvez utiliser le mot
clef IF EXISTS
pour éviter l'affichage
d'erreur si la base n'existe pas.
Si vous utilisez la commande DROP DATABASE
sur un lien symbolique pointant sur la base de données, le lien
et la base seront effacés.
Depuis MySQL 4.1.2, DROP DATABASE
retourne le
nombre de tables qui ont été supprimées. Cela revient à
compter le nombre de fichiers .frm
qui ont
été supprimées.
La commande DROP DATABASE
efface tous les
fichiers du dossier de la base de données, qui ont été
créés par MySQL lui-même, durant ses opérations normales :
Tous les fichiers avec les extensions suivantes :
.BAK | .DAT | .HSH | .ISD |
.ISM | .ISM | .MRG | .MYD |
.MYI | .db | .frm |
Tous les sous-dossiers qui consistent de 2 chiffres
hexadécimaux 00
-ff
.
Ce sont des dossiers RAID
) qui sont aussi
supprimés.
Le fichier db.opt
, s'il existe.
Si d'autres fichiers ou dossiers restent dans le dossier de base
après que MySQL ait supprimés ceux listés ci-dessus, le
dossier de base ne pourra pas être supprimé. Dans ce cas, vous
devez supprimer manuellement les fichiers restant, et lancer à
nouveau la commande DROP DATABASE
.
Vous pouvez aussi supprimer des bases de données avec
mysqladmin
. See Section 8.4, « mysqladmin
, administration d'un serveur MySQL ».
DROP INDEX nom_de_l_index ON nom_de_table
DROP INDEX
supprime l'index nommé
nom_de_l_index
de la table
nom_de_table
. DROP INDEX
ne fait rien avec la version 3.22 et les précédentes. Depuis
cette version, DROP INDEX
est un alias
d'ALTER TABLE
supprimant l'index.
DROP [TEMPORARY] TABLE [IF EXISTS] tbl_name [, tbl_name] ... [RESTRICT | CASCADE]
DROP TABLE
supprime une ou plusieurs tables.
Toutes les données et la structure de la tables sont
perdues, alors soyez
prudents avec cette commande !
Depuis la version 3.22 de MySQL, vous pouvez utiliser le mot
réservé IF EXISTS
pour éviter l'affichage
des erreurs pour les tables qui n'existent pas. See
Section 13.5.3.19, « SHOW WARNINGS | ERRORS
».
RESTRICT
et CASCADE
sont
autorisés pour faciliter le port. Pour le moment, elles ne font
rien.
Note : DROP
TABLE
va automatiquement valider les transactions
actives (hormis si vous utilisez la version 4.1 et le mot clé
TEMPORARY
).
L'option TEMPORARY
est ignorée en 4.0. En
4.1, cette option fonctionne comme suit :
Détruit uniquement les tables temporaires.
Ne termine pas les transactions en cours.
Aucun droits d'accès n'est vérifié.
TEMPORARY
est pour le moment ignoré; Dans un
futur proche, il servira à s'assurer qu'on efface vraiment une
table temporaire.
RENAME TABLE nom_de_table TO nouveau_nom_de_table[, nom_de_table2 TO nouveau_nom_de_table2,...]
Le changement de nom se fait atomiquement ce qui signifie qu'aucun autre processus ne peut accéder la table tant que l'opération est en cours. Cela rend possible de remplacer une vielle table avec une table vide :
CREATE TABLE nouvelle_table (...); RENAME TABLE ancienne_table TO backup_table, nouvelle_table TO ancienne_table;
L'opération s'effectue de gauche à droite ce qui signifie que si vous voulez échanger deux noms de tables, vous devez :
RENAME TABLE ancienne_table TO backup_table, nouvelle_table TO ancienne_table, backup_table TO nouvelle_table;
Si les deux bases de données sont sur le même disque, vous pouvez renommer à travers les bases :
RENAME TABLE bdd_courante.nom_de_table TO autre_bdd.nom_de_table;
Quand vous exécutez RENAME
, vous ne pouvez
avoir aucune transaction active ou une table protégée en mode
écriture. Vous devez avoir les privilèges
ALTER
et DROP
sur
l'ancienne table, et les privilèges CREATE
et INSERT
sur la nouvelle.
Si MySQL rencontre des erreurs dans un renommage multiple, il remettra les noms changés à leurs valeurs d'origine pour revenir à l'état d'origine.
RENAME TABLE
a été ajouté à la version
3.23.23 de MySQL.
{DESCRIBE | DESC} nom_de_table [nom_de_colonne | wild]
DESCRIBE
fournit des informations à propos
des colonnes de la table. DESCRIBE
est un
raccourci de SHOW COLUMNS FROM
.
See Section 13.5.3.3, « Syntaxe de SHOW COLUMNS
».
nom_de_colonne
peut être le nom d'une
colonne ou une chaîne contenant les caractères spéciaux SQL
‘%
’ et
‘_
’. Il n'est pas nécessaire de
placer la chaîne entre guillemets, hormis s'il y a des espaces
ou d'autres caractères spéciaux.
mysql> DESCRIBE city;
+------------+----------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+----------+------+-----+---------+----------------+
| Id | int(11) | | PRI | NULL | auto_increment |
| Name | char(35) | | | | |
| Country | char(3) | | UNI | | |
| District | char(20) | YES | MUL | | |
| Population | int(11) | | | 0 | |
+------------+----------+------+-----+---------+----------------+
5 rows in set (0.00 sec)
La colonne Null
indique si la valeur NULL
peut être stockée dans la colonne. YES indique que c'est le
cas.
La colonne Key
indique si un champ est
indexé. La valeur PRI
indique que le champ
fait partie de la clé primaire de la table.
UNI
indique que le champ fait partie d'un
index UNIQUE
. La valeur
MUL
indique que plusieurs occurrences d'une
valeur sont autorisées dans le champ.
Un champ peut être désigné comme MUL
même
si l'index UNIQUE
est utilisé, si les
valeurs NULL
sont autorisées, car une
colonne UNIQUE
peut contenir plusieurs
valeurs NULL
si la colonne est déclarée
comme NOT NULL
. Une autre cause pour
MUL
sur une colonne UNIQUE
est lorsque deux colonnes forment un couple
UNIQUE
: même si la combinaison des deux
colonnes est toujours unique, chaque colonne peut contenir des
valeurs multiples. Notez que dans un index composé, seul le
champ de gauche aura une entrée dans la colonne
Key
.
La colonne Default
indique la valeur par
défaut assignée à ce champ.
La colonne Extra
indique des informations
supplémentaires, disponibles sur le champ. Dans notre exemple,
la colonne Extra
indique que la colonne
Id
porte l'attribut
AUTO_INCREMENT
.
Si le type de colonne est différent de celui que vous pensiez
avoir définit lors du CREATE TABLE
, notez
que MySQL change le type des colonnes de temps en temps. See
Section 13.2.5.1, « Modification automatique du type de colonnes ».
Cette instruction est fournie pour une meilleure compatibilité avec Oracle.
L'instruction SHOW
renvoie les mêmes
informations. See Section 13.5.3, « Syntaxe de SHOW
».
USE db_name
La commande USE db_name
spécifie à MySQL
d'utiliser la base db_name
comme base par
défaut pour les requêtes ne les mentionnant pas. La base
choisie reste la même jusqu'à la fermeture de la session ou un
nouvel appel à USE
:
mysql>USE db1;
mysql>SELECT COUNT(*) FROM ma_table; # sélectionne à partir de db1.ma_table
mysql>USE db2;
mysql>SELECT COUNT(*) FROM ma_table; # sélectionne à partir de db2.ma_table
Rendre une base de données la base courante (en utilisant
USE
) ne vous interdit pas l'accès à
d'autres tables dans d'autres bases. L'exemple suivant accède
à la table author
de la base
db1
et à la table editor
de la base db2
:
mysql>USE db1;
mysql>SELECT author_name,editor_name FROM author,db2.editor
->WHERE author.editor_id = db2.editor.editor_id;
La commande USE
est fournie pour assurer la
compatibilité Sybase.
Par défaut, MySQL est lancé en mode
autocommit
. Cela signifie que chaque
modification effectué est enregistré immédiatement sur le
disque par MySQL.
Si vous utilisez des tables supportant les transactions (comme
InnoDB
, BDB
), vous pouvez
configurer MySQL en mode non-autocommit
grâce à la commande:
SET AUTOCOMMIT=0
A partir de là, vous devez utiliser COMMIT
pour enregistrer les modifications sur le disque ou
ROLLBACK
pour ignorer les modifications
apportées depuis le début de la transaction.
Si vous souhaitez sortir du mode AUTOCOMMIT
pour une série d'opérations, vous pouvez utiliser les
commandes BEGIN
ou BEGIN
WORK
:
START TRANSACTION; SELECT @A:=SUM(salary) FROM table1 WHERE type=1; UPDATE table2 SET summmary=@A WHERE type=1; COMMIT;
BEGIN
et BEGIN WORK
peuvent être utilisé à la place de START
TRANSACTION
pour initialiser une transaction.
START TRANSACTION
a été ajouté en MySQL
4.0.11; C'est une syntaxe SQL-99, et il est recommandé de
l'utiliser pour lancer une transaction. BEGIN
et BEGIN WORK
sont disponibles pour MySQL
3.23.17 et 3.23.19, respectivement.
Notez que si vous n'utilisez pas de table transactionnelles, les modifications seront validées automatiquement, indépendamment du mode de validation.
Si vous faites un ROLLBACK
après avoir
modifié une table non transactionnelle, vous obtiendrez
(ER_WARNING_NOT_COMPLETE_ROLLBACK
) comme
message d'alerte. Toutes les tables supportant les transactions
seront restaurées, mais aucune des autres tables ne changera.
Si vous utilisez START TRANSACTION
ou
SET AUTOCOMMIT=0
, il est recommandé
d'utiliser les "binary log
" de MySQL à la
place des anciens logs de modifications pour les sauvegardes.
Les transactions sont stockées dans les logs binaires en un
seul bloc, après COMMIT
, pour être sûr que
les transactions qui ont été annulées ne soient pas
enregistrées. See Section 5.9.4, « Le log binaire ».
Vous pouvez changer le niveau d'isolation des transactions avec
SET TRANSACTION ISOLATION LEVEL ...
. See
Section 13.4.6, « Syntaxe de SET TRANSACTION
».
Certaines commandes ne peuvent pas être annulées. En général, elles incluent le langage de définition des données (DDL), comme les commandes qui créent ou effacent des bases de données, ou celles qui créent, modifient ou effacent des tables de données.
Il est recommandé de concevoir vos transactions pour éviter
ces commandes. Si vous soumettez une commande qui ne peut pas
être annulée, dès le début de votre transaction, et qu'une
commande ultérieure échoue, vous pourrez pas annuler
l'ensemble de la transaction avec ROLLBACK
.
Les commandes suivantes valident implicitement une transaction,
comme si vous aviez émis une commande COMMIT
après :
ALTER TABLE | BEGIN | CREATE INDEX |
DROP DATABASE | DROP INDEX | DROP TABLE |
LOAD MASTER DATA | LOCK TABLES | RENAME TABLE |
SET AUTOCOMMIT=1 | START TRANSACTION | TRUNCATE |
UNLOCK TABLES
termine aussi une transaction
si toutes les tables courantes sont verrouillées. Avant MySQL
version 4.0.13, CREATE TABLE
terminait une
transaction si le log binaire était activé.
Les transactions ne peuvent pas être imbriquées. C'est la
conséquence de cette validation COMMIT
implicite pour toutes les transactions en cours, lorsque vous
émettez une commande START TRANSACTION
ou
équivalent.
Depuis MySQL 4.0.14 et 4.1.1, InnoDB
supporte
les commandes SQL SAVEPOINT
et
ROLLBACK TO SAVEPOINT
.
SAVEPOINT identifier
Cette commande pose un jalon de transaction dont le nom est
identifier
. Si la transaction courante a
déjà un jalon de ce nom, l'ancien jalon est effacé, et le
nouveau est créé à la place.
Cette commande annule la transaction jusqu'au jalon. Les
modifications que cette transaction a fait aux lignes depuis le
jalon sont annulées, mais InnoDB
ne libère pas les verrous posés en
mémoire après le jalon. Notez que pour une nouvelle ligne
insérée, l'information de verrou est conservée par
l'identifiant de transaction de la ligne : le verrou n'est pas
stocké en mémoire. Dansa ce cas, le verrou sera levé par
l'annulation. Les jalons qui ont été posé après celui-ci
sont aussi annulés.
Si la commande retourne l'erreur suivante, c'est qu'aucun jalon de ce nom n'a pu être trouvé.
ERROR 1181: Got error 153 during ROLLBACK
Tous les jalons de la transaction courante sont annulés si vous
exécutez les commandes COMMIT
ou
ROLLBACK
, sans préciser de nom de jalon.
LOCK TABLES tbl_name [AS alias] {READ [LOCAL] | [LOW_PRIORITY] WRITE} [, tbl_name [AS alias] {READ [LOCAL] | [LOW_PRIORITY] WRITE}] ... UNLOCK TABLES
LOCK TABLES
verrouille une table pour le
thread courant. UNLOCK TABLES
déverrouillera
automatiquement tous les verrous posés par le thread courant.
Toutes les tables verrouillées par le thread courant sont
automatiquement déverrouillées quand ce thread utilise à
nouveau LOCK TABLES
, ou quand la connexion au
serveur est perdue.
Note : LOCK
TABLES
n'est pas compatible avec les transactions, et
valide automatiquement toute transaction active avant de
verrouiller une table.
L'utilisation de LOCK TABLES
dans MySQL 4.0.2
nécessite le privilège LOCK TABLES
global
et un privilège de SELECT
sur les tables
impliquées. Dans MySQL 3.23, il faut les privilèges
SELECT
, INSERT
,
DELETE
et UPDATE
sur les
tables.
Les principales raisons d'utiliser LOCK
TABLES
sont l'émulation de transactions ou
l'accélération des processus de modification de tables. Cela
sera détaillé plus loin.
Si un thread obtient un verrouillage READ
sur
une table, ce thread (et tous les autres threads) peuvent
uniquement accéder a cette table en lecture. Si un thread
obtient un verrouillage WRITE
sur une table,
alors seul le thread qui a posé le verrou peut lire ou écrire
sur cette table. Tous les autres threads sont bloqués.
La différence entre READ LOCAL
et
READ
est que READ LOCAL
autorise des requêtes INSERT
non-conflictuelles à être exécutées alors que le verrou est
posé. Ceci ne peut cependant pas être utilisé si vous
souhaitez modifier les fichiers de la base de données en dehors
de MySQL pendant que le verrou est posé.
Quand vous utilisez LOCK TABLES
, vous devez
verrouiller toutes les tables que vous allez utiliser, et vous
devez utiliser les mêmes alias sur ce que vous utiliserez dans
vos requêtes ! Si vous utilisez une table a plusieurs reprises
dans une requête (avec des alias), vous devez verrouiller
chacun des alias !
Si vos requêtes utilisent un alias pour une table, alors vous devez verrouiller la table avec l'alias. Le verrouillage ne fonctionnera pas si vous verrouillez la table sans spécifier l'alias :
mysql>LOCK TABLE t READ;
mysql>SELECT * FROM t AS myalias;
ERROR 1100: Table 'myalias' was not locked with LOCK TABLES
De même, lorsque vous verrouillez une table avec un alias, vous devez utiliser le nom de l'alias dans vos requêtes :
mysql>LOCK TABLE t AS myalias READ;
mysql>SELECT * FROM t;
ERROR 1100: Table 't' was not locked with LOCK TABLES mysql>SELECT * FROM t AS myalias;
Les verrous WRITE
ont normalement des
priorités supérieures aux verrous READ
,
afin de s'assurer que les modifications sont exécutées au plus
vite. Cela signifie que si un thread demande un verrou
READ
et qu'un autre thread demande un verrou
WRITE
, la demande de verrou
READ
attendra que le thread
WRITE
ait abouti pour libérer le verrou.
Vous pouvez utiliser le verrou LOW_PRIORITY
WRITE
pour permettre à d'autres threads d'obtenir des
verrous READ
pendant que le thread attend le
verrou WRITE
. Vous ne devriez utiliser les
verrous LOW_PRIORITY WRITE
que si vous êtes
sûr qu'il y aura effectivement un moment où aucun thread ne
posera de verrou READ
.
LOCK TABLES
fonctionne de la manière
suivante :
Trie toutes les tables à verrouiller dans un ordre défini par MySQL (l'utilisateur ne définit pas d'ordre).
Si une table est verrouillée avec un verrou de lecture et un verrou d'écriture, il pose le verrou de lecture avant celui d'écriture.
Verrouille une table à la fois jusqu'à ce que le thread ait tous ses verrous.
Cette politique garantit le bon verrouillage des tables. Il faut cependant connaître certaines choses sur ce schéma :
Si vous utilisez un verrou LOW_PRIORITY WRITE
pour une table, cela signifie seulement que MySQL attendra, pour
poser ce verrou, qu'aucun autre thread ne réclame de verrou
READ
. Quand le thread aura le verrou
WRITE
et qu'il attendra que les verrous
soient posés sur les autres tables de la liste, tous les autres
threads attendront que le verrou WRITE
soit
libéré. Si cela devient un problème grave pour votre
application, il est conseillé de convertir des tables en tables
supportant les transactions.
Vous pouvez terminer un thread attendant un verrouillage de
table en toute sécurité avec KILL
. See
Section 13.5.4.3, « Syntaxe de KILL
».
Il est déconseillé de verrouiller des
tables utilisées avec INSERT DELAYED
, car,
dans ce cas, la requête INSERT
est
exécutée dans un autre thread.
Normalement, vous n'avez pas besoin de verrouiller les tables
puisque chaque requête UPDATE
est
atomique : aucun autre thread ne peut interférer avec une
autre requête active. Il existe cependant quelques cas où vous
aurez besoin de verrouiller les tables :
Si vous allez exécuter plusieurs requêtes sur plusieurs
tables, il est préférable, d'un point de vue rapidité, de
verrouiller les tables dont vous aurez besoin.
L'inconvénient, bien sur, est que les autres threads ne
pourront pas intervenir sur ces tables durant vos
opérations, ni en extraire des informations si la table est
verrouillée en WRITE
.
La raison pour laquelle les requêtes sont plus rapides avec
LOCK TABLES
est que MySQL ne rafraîchît
pas l'index des clés des tables verrouillées tant que
UNLOCK TABLES
n'est pas invoqué
(normalement, le cache des clés est rafraîchi après
chaque requête SQL). Cela accélère les insertions, les
modifications et les suppressions de données dans les
tables MyISAM
.
Si vous utilisez un type de table dans MySQL qui ne supporte
pas les transactions, vous devez utiliser LOCK
TABLES
pour vous assurez qu'aucun autre thread ne
s'intercale entre un SELECT
et un
UPDATE
. L'exemple suivant nécessite
LOCK TABLES
pour s'exécuter en toute
sécurité :
mysql>LOCK TABLES trans READ, customer WRITE;
mysql>SELECT SUM(value) FROM trans WHERE customer_id=some_id;
mysql>UPDATE customer SET total_value=sum_from_previous_statement
->WHERE customer_id=some_id;
mysql>UNLOCK TABLES;
Sans LOCK TABLES
, Il est possible qu'un
autre thread ait inséré une nouvelle ligne dans la table
trans
entre l'exécution du
SELECT
et l'exécution de la requête
UPDATE
.
L'utilisation de modifications incrémentales (UPDATE
customer SET value=value+nouvelle_valeur
) ou de la
fonction LAST_INSERT_ID()
permet de se passer
de LOCK TABLES
dans de nombreuses situations.
See Section 1.5.5.3, « Transactions et opérations atomiques ».
Il est aussi possible de résoudre de nombreux cas en utilisant
un verrou utilisateur, avec les fonctions
GET_LOCK()
et
RELEASE_LOCK()
. Ces verrous sont stockés
dans une table de hashage dans le serveur et utilisent les
fonctions pthread_mutex_lock()
et
pthread_mutex_unlock()
pour plus de vitesse.
See Section 12.8.4, « Fonctions diverses ».
Voir Section 7.3.1, « Méthodes de verrouillage » pour plus de détails.
Il est possible de verrouiller tous les tables de toutes les
bases avec la commande FLUSH TABLES WITH READ
LOCK
.
See Section 13.5.4.2, « Syntaxe de FLUSH
». C'est une méthode très pratique
pour effectuer des sauvegardes si vous utilisez un système de
fichiers qui, comme Veritas, permet de créer des instantanés.
Note : LOCK
TABLES
ne fonctionne pas avec les transactions et
validera automatiquement toutes les transactions actives avant
de poser verrouiller la table. See
Section A.7.1, « Problèmes avec ALTER TABLE
. ».
SET [GLOBAL | SESSION] TRANSACTION ISOLATION LEVEL { READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE }
Configuration du niveau d'isolation des transactions en général, pour la totalité de la session, ou pour la prochaine transaction.
Le comportement par défaut est de configurer le niveau
d'isolation pour la transaction suivante (qui n'a pas encore
été commencée) En utilisant le paramètre
GLOBAL
, on configure le niveau par défaut
global pour toutes les nouvelles connections. Cette commande
requiert les privilèges SUPER
. En utilisant
le paramètre SESSION
, on configure le niveau
par défaut pour toutes les prochaines transactions effectuées
durant la session actuelle.
Pour une description de chaque niveau d'isolation de transaction
InnoDB
, voyez
Section 15.11.2, « InnoDB et SET ... TRANSACTION ISOLATION LEVEL ...
».
InnoDB
supporte chacun des niveaux depuis
MySQL 4.0.5. Le niveau par défaut est REPEATABLE
READ
.
On peut configurer le niveau d'isolation global des transactions
pour mysqld
avec
--transaction-isolation=...
. See
Section 4.3.1, « Options de ligne de commande de mysqld
».
CREATE USERuser
[IDENTIFIED BY [PASSWORD] 'password
'] [,user
[IDENTIFIED BY [PASSWORD] 'password
']] ...
La commande CREATE USER
crée un nouveau
compte MySQL. Pour l'utiliser, vous devez avoir les droits de
CREATE USER
ou les droits
d'INSERT
dans la table de droits de la base
mysql
. Pour chaque compte, CREATE
USER
crée un nouvel enregistrement dans la table
mysql.user
, sans aucun droit. Une erreur
survient si le compte existe déjà. Le compte peut recevoir
un mot de passe avec la clause optionnelle IDENTIFIED
BY
. La valeur user
et le
mot de passe sont données de la même manière que dans la
commande GRANT
.
La commande CREATE USER
a été ajoutée en
MySQL 5.0.2.
DROP USER user_name
Cette commande a été ajoutée en MySQL 4.1.1.
Elle efface un utilisateur qui n'a aucun droits.
Pour effacer un utilisateur dans MySQL, vous devriez utiliser l'une des procédures suivantes, dans cet ordre :
Vérifiez les droits de l'utilisateur avec la commande
SHOW PRIVILEGES
. See
Section 13.5.3.13, « SHOW PRIVILEGES
».
Effacez tous les droits de l'utilisateur avec la commande
REVOKE
. See Section 13.5.1.3, « Syntaxe de GRANT
et REVOKE
».
Effacez l'utilisateur avec DROP USER
.
Si vous utilisez une vieille version de MySQL, vous devriez commencer par effacer les droits, puis l'utilisateur avec :
DELETE FROM mysql.user WHERE user='username' and host='hostname'; FLUSH PRIVILEGES;
GRANT priv_type [(column_list)] [, priv_type [(column_list)]] ... ON {tbl_name | * | *.* | db_name.*} TO user [IDENTIFIED BY [PASSWORD] 'password'] [, user [IDENTIFIED BY [PASSWORD] 'password']] ... [REQUIRE NONE | [{SSL| X509}] [CIPHER cipher [AND]] [ISSUER issuer [AND]] [SUBJECT subject]] [WITH [GRANT OPTION | MAX_QUERIES_PER_HOUR count | MAX_UPDATES_PER_HOUR count | MAX_CONNECTIONS_PER_HOUR count]]
REVOKE priv_type [(column_list)] [, priv_type [(column_list)]] ... ON {tbl_name | * | *.* | db_name.*} FROM user [, user] ... REVOKE ALL PRIVILEGES, GRANT OPTION FROM user [, user] ...
Les commandes GRANT
et
REVOKE
permettent à l'administrateur
système de créer et supprimer des comptes utilisateur et de
leur donner ou retirer des droits. GRANT
et
REVOKE
sont implémentées en MySQL 3.22.11
ou plus récent. Pour les anciennes versions de MySQL, ces
commandes ne font rien.
Les informations sur les comptes MySQL sont stockés dans la
base mysql
. Cette base et son accès sont
présentés en détails dans la section
Chapitre 5, Administration du serveur.
Les droits sont donnés à 4 niveaux :
Niveau global
Les droits globaux s'appliquent à toutes les bases de
données d'un serveur. Ces droits sont stockés dans la
table mysql.user
. REVOKE ALL
ON *.*
retirera seulement les privilèges
globaux.
Niveau base de données
Les droits de niveau de base de données s'appliquent à
toutes les tables d'une base de données. Ces droits sont
stockés dans les tables mysql.db
et
mysql.host
. REVOKE ALL ON
db.*
retirera seulement les privilèges de base
de données.
Niveau table
Les droits de table s'appliquent à toutes les colonnes
d'une table. Ces droits sont stockés dans la table
mysql.tables_priv
. REVOKE ALL
ON db.table
retirera seulement les privilèges
de table.
Niveau colonne
Les droits de niveau de colonnes s'appliquent à des
colonnes dans une table. Ces droits sont stockés dans la
table mysql.columns_priv
. Quand vous
utilisez REVOKE
vous devez spécifier
les mêmes colonnes qui s'étaient vues accorder des
privilèges.
Pour faciliter la suppression de tous les droits d'un utilisateur, MySQL 4.1.2 a ajouté la syntaxe suivante, qui efface tous les droits de base, table et colonne pour un utilisateur donné :
REVOKE ALL PRIVILEGES,GRANT FROM user_name [, user_name ...]
Avant MySQL 4.1.2, tous les droits ne peuvent pas être effacés d'un coup. Il faut deux commandes pour cela :
REVOKE ALL PRIVILEGES FROM user [, user] ... REVOKE GRANT OPTION FROM user [, user] ...
Pour les commandes GRANT
et
REVOKE
, la clause
priv_type
peut être spécifiée par les
constantes suivantes :
Droit | Signification |
ALL [PRIVILEGES] | Tous les droits sauf WITH GRANT OPTION . |
ALTER | Autorise l'utilisation de ALTER TABLE . |
CREATE | Autorise l'utilisation de CREATE TABLE . |
CREATE TEMPORARY TABLES | Autorise l'utilisation de CREATE TEMPORARY TABLE . |
DELETE | Autorise l'utilisation de DELETE . |
DROP | Autorise l'utilisation de DROP TABLE . |
EXECUTE | Autorise l'utilisateur à exécuter des procédures stockées (pour MySQL 5.0). |
FILE | Autorise l'utilisation de SELECT ... INTO OUTFILE et
LOAD DATA INFILE . |
INDEX | Autorise l'utilisation de CREATE INDEX et
DROP INDEX . |
INSERT | Autorise l'utilisation de INSERT . |
LOCK TABLES | Autorise l'utilisation de LOCK TABLES sur les tables
pour lesquelles l'utilisateur a les droits de
SELECT . |
PROCESS | Autorise l'utilisation de SHOW FULL PROCESSLIST . |
REFERENCES | Réservé pour le futur. |
RELOAD | Autorise l'utilisation de FLUSH . |
REPLICATION CLIENT | Donne le droit à l'utilisateur de savoir où sont les maîtres et esclaves. |
REPLICATION SLAVE | Nécessaire pour les esclaves de réplication (pour lire les historiques binaires du maître). |
SELECT | Autorise l'utilisation de SELECT . |
SHOW DATABASES | SHOW DATABASES affiche toutes les bases de données. |
SHUTDOWN | Autorise l'utilisation de mysqladmin shutdown . |
SUPER | Autorise une connexion unique même si
max_connections est atteint, et
l'exécution des commandes CHANGE
MASTER , KILL thread ,
mysqladmin debug , PURGE
MASTER LOGS et SET
GLOBAL . |
UPDATE | Autorise l'utilisation de UPDATE . |
USAGE | Synonyme de ``pas de droits''. |
GRANT OPTION | Synonyme pour WITH GRANT OPTION |
USAGE
peut être utilisé lorsque vous
voulez créer un utilisateur sans aucun droit.
Les droits de CREATE TEMPORARY TABLES
,
EXECUTE
, LOCK TABLES
,
REPLICATION ...
, SHOW
DATABASES
et SUPER
sont nouveaux
en version 4.0.2. Pour utiliser ces droits après mise à jour
en 4.0.2, vous devez exécuter le script
mysql_fix_privilege_tables
. See
Section 2.6.7, « Mise à jour des tables de droits ».
Dans les anciennes versions de MySQL, le droit de
PROCESS
donnait les mêmes droits que le
nouveau droit SUPER
.
Vous pouvez donner des droits globaux en utilisant la syntaxe
ON *.*
. Vous pouvez donner des droits de
base en utilisant la syntaxe ON nom_base.*
.
Si vous spécifiez ON *
et que vous avez
une base de données qui est déjà sélectionnée, vous allez
donner des droits pour la base de données courante.
Attention : si vous
spécifiez ON *
et que vous
n'avez pas de base courante, vous allez
affecter les droits au niveau du serveur !
Les droits EXECUTION
,
FILE
, PROCESS
,
RELOAD
, REPLICATION
CLIENT
, REPLICATION SLAVE
,
SHOW DATABASES
, SHUTDOWN
et SUPER
sont des droits d'administration,
qui ne peuvent être donnés que globalement (avec la syntaxe
ON *.*
).
Les autres droits peuvent être donnés globalement ou à des niveaux plus spécifiques.
Les seuls droits priv_type
que vous pouvez
donner au niveau d'une table sont SELECT
,
INSERT
, UPDATE
,
DELETE
, CREATE
,
DROP
, GRANT OPTION
,
INDEX
et ALTER
.
Les seuls droits priv_type
que vous pouvez
donner au niveau d'une colonne (avec la clause
column_list
) sont
SELECT
, INSERT
et
UPDATE
.
GRANT ALL
assigne des droits que vous
possédez au niveau où vous le possédez. Par exemple, si
vous utilisez GRANT ALL ON db_name.*
, qui
est un droit de niveau de base de données, aucun des droits
globaux, comme FILE
ne sera donné.
MySQL vous permet de donner des droits au niveau d'une base de données, même si la base de données n'existe pas, pour vous aider à préparer l'utilisation de la base de données. Actuellement, MySQL ne vous permet pas de créer des droits pour une table si la table n'existe pas.
MySQL ne supprime pas les droits lorsqu'un utilisateur efface une table ou une base.
Notez bien : les caractères
joker ‘_
’ et
‘%
’ sont autorisés lors de la
spécification de noms dans la commande
GRANT
. Cela signifie que si vous voulez
utiliser par exemple le caractère littéral
‘_
’ comme nom de base, vous
devez le spécifier sous la forme
‘\_
’ dans la commande
GRANT
, pour éviter à l'utilisateur
d'accéder à d'autres bases, dont le nom pourrait
correspondre au masque d'expression régulière ainsi créé.
Utilisez plutôt GRANT ... ON `foo\_bar`.* TO
...
.
Afin de permettre l'identification des utilisateurs depuis des
hôtes arbitraires, MySQL supporte la spécification du nom
d'utilisateur nom_utilisateur
sous la forme
user@host
. Si vous voulez spécifier un nom
d'utilisateur user
qui contient des
caractères spéciaux tels que
‘-
’, ou une chaîne d'hôte
host
qui contient des caractères joker
(comme ‘%
’), vous pouvez placer
le nom de l'utilisateur ou de l'hôte entre guillemets (par
exemple,
'test-utilisateur'@'test-nomdhote'
).
Vous pouvez spécifier des caractères jokers dans le nom
d'hôte. Par exemple, user@'%.loc.gov'
fait
correspondre l'utilisateur user
de
n'importe quel hôte du domaine loc.gov
, et
user@'144.155.166.%'
fait correspondre
l'utilisateur user
à n'importe quelle
adresse de la classe C 144.155.166
.
La forme simple de user
est synonyme de
user@"%"
.
MySQL ne supporte pas de caractères joker dans les noms
d'utilisateur. Les utilisateurs anonymes sont définis par
l'insertion de ligne avec User=''
dans la
table mysql.user
, ou en créant un
utilisateur avec un nom vide, grâce à la commande
GRANT
.
mysql> GRANT ALL ON test.* TO ''@'localhost' ...
Attention : si vous
autorisez des utilisateurs anonymes à se connecter à votre
serveur, vous devriez aussi donner ces droits à tous les
utilisateurs locaux user@localhost
car
sinon, la ligne dans la table mysql.user
sera utilisée lorsque l'utilisateur se connectera au serveur
MySQL depuis la machine locale ! (Ce compte est créé durant
l'installation de MySQL.)
Vous pouvez vérifier si cela s'applique à vous en exécutant la requête suivante :
mysql> SELECT Host,User FROM mysql.user WHERE User='';
Si vous voulez effacer les utilisateurs anonymes d'un serveur, utilisez ces commandes :
mysql>DELETE FROM mysql.user WHERE Host='localhost' AND User='';
mysql>FLUSH PRIVILEGES;
Actuellement, la commande GRANT
supporte
uniquement les noms d'hôte, colonne, table et bases de
données d'au plus 60 caractères. Un nom d'utilisateur peut
être d'au plus 16 caractères.
Les droits pour les tables et colonnes sont combinés par OU
logique, avec les quatre niveaux de droits. Par exemple, si la
table mysql.user
spécifie qu'un
utilisateur a un droit global de SELECT
, ce
droit ne pourra pas être annulé au niveau base, table ou
colonne.
Les droits d'une colonne sont calculés comme ceci :
droit global OR (droit de base de données ET droit d'hôte) OR droit de table OR droit de colonne
Dans la plupart des cas, vous donnez des droits à un utilisateur en utilisant un seul des niveaux de droits ci-dessus, ce qui fait que la vie n'est pas aussi compliquée. Le détails de la procédure de vérification des droits et disponible dans Section 5.5, « Règles de sécurité et droits d'accès au serveur MySQL ».
Si vous donnez des droits à une paire utilisateur/hôte qui
n'existe pas dans la table mysql.user
, une
ligne sera créée et restera disponible jusqu'à son
effacement avec la commande DELETE
. En
d'autre termes, GRANT
crée une ligne dans
la table user
, mais
REVOKE
ne la supprime pas. Vous devez le
faire explicitement avec la commande
DELETE
.
Avec MySQL version 3.22.12 ou plus récent, si un nouvel
utilisateur est créé, ou si vous avez les droits de
GRANT
globaux, le mot de passe sera
configuré avec le mot de passe spécifié avec la clause
IDENTIFIED BY
, si elle est fournie. Si
l'utilisateur a déjà un mot de passe, il sera remplacé par
ce nouveau.
Attention : si vous créez
un nouvel utilisateur, mais ne spécifiez pas de clause
IDENTIFIED BY
, l'utilisateur n'aura pas de
mot de passe. Ce n'est pas sécuritaire.
Les mots de passe peuvent aussi être modifiés avec la
commande SET PASSWORD
. See
Section 13.5.1.5, « Syntaxe de SET PASSWORD
».
Si vous ne voulez pas transmettre le mot de passe en texte
clair, vous pouvez immédiatement utiliser l'option
PASSWORD
suivi du mot de passe déjà
chiffré avec la fonction PASSWORD()
ou
l'API C make_scrambled_password(char *to, const char
*password)
.
Si vous donnez les droits de base, une ligne sera ajoutée
dans la table mysql.db
. Lorsque les droits
sur cette base seront supprimés avec la commande
REVOKE
, cette ligne disparaîtra.
Si un utilisateur n'a pas de droit sur une table, elle ne sera
pas affichée lorsqu'il demandera la liste des tables avec la
commande SHOW TABLES
. Si un utilisateur n'a
pas de droit dans une base, le nom de la base ne sera pas
affiché par SHOW DATABASES
à moins que
l'utilisateur n'ai un droit de SHOW
DATABASES
.
La clause WITH GRANT OPTION
donne à
l'utilisateur le droit de donner les droits qu'il possède à
d'autres utilisateurs. La plus grande prudence est
recommandée pour cette commande, car il permettra à terme à
deux utilisateurs de combiner les droits dont ils disposent.
Vous ne pouvez pas donner un droit que vous ne possédez pas.
le droit de GRANT OPTION
ne vous donne le
droit que de donner les droits que vous possédez.
Sachez que si vous donnez à quelqu'un le droit de
GRANT OPTION
, tous les droits que possède
cet utilisateur seront distribuables. Supposez que vous donnez
à un utilisateur le droit d'INSERT
dans
une base de données. Si vous donnez le droit de
SELECT
sur une base, et spécifiez l'option
WITH GRANT OPTION
, l'utilisateur peut
distribuer non seulement son droit de
SELECT
, mais aussi son droit de
INSERT
. Si vous donnez ensuite le droit de
UPDATE
, il pourra alors distribuer
INSERT
, SELECT
et
UPDATE
.
Il est recommandé de ne pas donner de droits de
ALTER
à un utilisateur normal. Si vous le
faîtes, l'utilisateur pourra essayer de contourner le
système de droits en renommant des tables.
MAX_QUERIES_PER_HOUR #
,
MAX_UPDATES_PER_HOUR #
et
MAX_CONNECTIONS_PER_HOUR #
sont nouveaux en
MySQL 4.0.2. Ces deux options limitent le nombre de requêtes
et de modifications qu'un utilisateur peut réclamer dans une
heure. Si #
vaut 0 (valeur par défaut),
alors cela signifie qu'il n'y a pas de limitations pour cet
utilisateur. See Section 5.6.4, « Limiter les ressources utilisateurs ». Note: pour
spécifier l'une de ces options pour un utilisateur existant
sans ajouter d'autres privilèges additionnels, utilisez
GRANT USAGE ... WITH MAX_...
.
MySQL peut vérifier les attributs X509 en plus des éléments
d'identifications habituels, comme le nom d'utilisateur et le
mot de passe. Pour spécifier des options SSL pour un compte
MySQL, utilisez la clause REQUIRE
de la
commande GRANT
. Pour des informations
générales sur SSL et MySQL, voyez
Section 5.6.7, « Utilisation des connexions sécurisées ».
Il y a différentes possibilités pour limiter le type de connexions d'un compte :
Si un compte ne doit pas utiliser SSL ou X509, les connexions sont autorisées si le mot de passe et le nom d'utilisateur sont valides. Cependant, les connexions non-chiffrées peuvent aussi être utilisées par le client, si le client dispose des bons certificats et clés.
L'option REQUIRE SSL
limite le serveur
aux connexions chiffrées avec SSL. Notez que cette option
peut être omise s'il y a des lignes d'identifications qui
autorisent les connexions non chiffrées.
mysql>GRANT ALL PRIVILEGES ON test.* TO 'root'@'localhost'
->IDENTIFIED BY 'goodsecret' REQUIRE SSL;
REQUIRE X509
signifie que le client
doit avoir un certificat valide, mais que le certificat
exact, l'émetteur et le sujet n'ont pas d'importance. La
seule obligation est qu'il faut pouvoir vérifier la
signature auprès d'une des autorités de certification.
mysql>GRANT ALL PRIVILEGES ON test.* TO 'root'@'localhost'
->IDENTIFIED BY 'goodsecret' REQUIRE X509;
REQUIRE ISSUER 'issuer'
impose aux
connexions l'utilisation d'un certificat X509 émis par
l'autorité de certification 'issuer'
.
Si le client présente un certificat d'une autre
autorité, le serveur rejette la connexion. L'utilisation
des certificats X509 implique toujours un chiffrement, ce
qui fait que l'option SSL
est inutile.
mysql>GRANT ALL PRIVILEGES ON test.* TO 'root'@'localhost'
->IDENTIFIED BY 'goodsecret'
->REQUIRE ISSUER '/C=FI/ST=Some-State/L=Helsinki/
O=MySQL Finland AB/CN=Tonu Samuel/Email=tonu@example.com';
Notez que la valeur de ISSUER
doit
être saisie comme une seule chaîne.
REQUIRE SUBJECT 'subject'
impose à la
connexion à la présentation d'un certificat X509 avec le
sujet 'subject'
. Si le client présente
un certificat qui est valide, mais avec un autre sujet, le
serveur rejette la connexion.
mysql>GRANT ALL PRIVILEGES ON test.* TO 'root'@'localhost'
->IDENTIFIED BY 'goodsecret'
->REQUIRE SUBJECT '/C=EE/ST=Some-State/L=Tallinn/
O=MySQL demo client certificate/ CN=Tonu Samuel/Email=tonu@example.com';
Notez que la valeur de SUBJECT
doit
être saisie comme une seule chaîne.
REQUIRE CIPHER 'cipher'
est nécessaire
pour s'assurer que des tailles de clé et chiffrements
suffisantes sont utilisées. SSL peut être faible si de
vieux algorithmes avec des clés courtes sont utilisées.
En utilisant cette option, vous pouvez spécifier un
chiffrement spécifique.
mysql>GRANT ALL PRIVILEGES ON test.* TO 'root'@'localhost'
->IDENTIFIED BY 'goodsecret'
->REQUIRE CIPHER 'EDH-RSA-DES-CBC3-SHA';
Les clauses SUBJECT
,
ISSUER
et CIPHER
peuvent
être combinées avec la clause REQUIRE
comme ceci :
mysql>GRANT ALL PRIVILEGES ON test.* TO 'root'@'localhost'
->IDENTIFIED BY 'goodsecret'
->REQUIRE SUBJECT '/C=EE/ST=Some-State/L=Tallinn/
O=MySQL demo client certificate/ CN=Tonu Samuel/Email=tonu@example.com' ->AND ISSUER '/C=FI/ST=Some-State/L=Helsinki/
O=MySQL Finland AB/CN=Tonu Samuel/Email=tonu@example.com' ->AND CIPHER 'EDH-RSA-DES-CBC3-SHA';
Notez que les valeurs de SUBJECT
et
ISSUER
doivent être saisies comme une
seule chaîne.
Depuis MySQL 4.0.4, le mot clé AND
est
optionnel entre les clauses de REQUIRE
.
L'ordre des options est libre, mais les options doivent être spécifiées une seule fois.
Notez que si vous utilisez des droits de niveau table ou colonne même pour un utilisateur, le serveur vérifiera alors ces droits pour tous les utilisateurs, et cela ralentira MySQL un peu.
Lorsque mysqld
démarre, tous les droits
sont stockés en mémoire. Les droits de bases, tables et
colonnes prennent aussitôt effet, et les droits des
utilisateurs prendront effet dès leur prochaine
configuration. Les modifications sur les tables de droits que
vous effectuez avec les commandes GRANT
et
REVOKE
sont prises en compte immédiatement
par le serveur. Si vous modifiez manuellement les tables (avec
INSERT
, UPDATE
, etc...),
vous devez exécuter la commande FLUSH
PRIVILEGES
, ou la commande en ligne
mysqladmin flush-privileges
pour indiquer
au serveur qu'il doit recharger les droits. See
Section 5.5.7, « Quand les modifications de privilèges prennent-ils effets ? ».
Les différences notables entre l'ANSI SQL et MySQL pour la
commande GRANT
sont :
Les droits MySQL sont donnés pour une combinaison nom d'utilisateur + nom d'hôte, et non pas pour un nom d'hôte seulement.
L'ANSI SQL n'a pas de droits globaux ou de niveau base de
données, et l'ANSI SQL ne supporte pas tous les types de
droits que MySQL supporte. MySQL ne supporte pas le droit
ANSI SQL de TRIGGER
ou
UNDER
.
MySQL ne supporte pas les droits standard SQL
TRIGGER
et UNDER
.
Les droits ANSI SQL sont structurés de manière hiérarchique. Si vous supprimez un utilisateur, tous les droits donnés à cet utilisateur seront supprimés. Avec MySQL, les droits ne sont pas automatiquement supprimés, et vous devez les supprimer manuellement, si besoin.
Avec MySQL, si vous avez le droit de
INSERT
sur uniquement quelques colonnes
de la table, vous pourrez exécuter des insertions. Les
colonnes pour lesquelles vous n'avez pas de droit
prendront alors leur valeur par défaut. L'ANSI SQL vous
impose d'avoir les droits d'INSERT
sur
toutes les colonnes.
Lorsque vous détruisez une table avec ANSI SQL, tous les
droits liés à la table sont supprimés. Si vous
supprimez un droit en ANSI SQL, tous les droits qui
étaient basés sur ce droit sont supprimés. Avec MySQL,
les droits peuvent être abandonnés explicitement avec la
commande REVOKE
, ou en manipulant les
tables de droits de MySQL.
RENAME USERold_user
TOnew_user
[,old_user
TOnew_user
] ...
La commande RENAME USER
renomme un compte
MySQL existant. Pour l'utiliser, vous devez avoir les droits
globaux de CREATE USER
ou les droits de
UPDATE
dans la base
mysql
. Une erreur survient si l'ancien
compte n'existe pas, ou que le nouveau compte existe déjà.
Les valeurs old_user
et
new_user
sont données de la même
fa¸on que dans la commande GRANT
.
La commande RENAME USER
a été ajoutée en
MySQL 5.0.2.
SET PASSWORD = PASSWORD('some password') SET PASSWORD FOR user = PASSWORD('some password')
La commande SET PASSWORD
assigne un mot de
passe à un compte utilisateur existant.
La première syntaxe modifie le mot de passe de l'utilisateur courant. Tout client qui s'est connecté avec un compte non-anonyme peut changer le mot de passe pour ce compte.
La seconde syntaxe modifie le mot de passe pour un compte
tiers, sur le serveur. Seuls les clients qui ont accès aux
bases mysql
peuvent faire cela. La valeur
de user
doit être donnée au format
user_name@host_name
, où
user_name
et host_name
sont tels que listés dans les colonnes
User
et Host
de la table
mysql.user
. Par exemple, si vous avez une
ligne avec les champs User
et
Host
qui valent 'bob'
et
'%.loc.gov'
, vous pouvez écrire la
commande suivante :
mysql> SET PASSWORD FOR 'bob'@'%.loc.gov' = PASSWORD('newpass');
C'est l'équivalent de la commande suivante :
mysql>UPDATE mysql.user SET Password=PASSWORD('newpass')
->WHERE User='bob' AND Host='%.loc.gov';
mysql>FLUSH PRIVILEGES;
ANALYZE TABLE nom_de_table[,nom_de_table...]
Cette commande analyse et stocke la clé de distribution de la
table. Durant l'analyse, la table est verrouillée en lecture.
Cette commande fonctionne avec les tables
MyISAM
et BDB
.
C'est l'équivalent de la commande en ligne myisamchk
-a
.
MySQL utilise les clés de distribution pour décider dans quel ordre les tables doivent être rassemblées lors des jointures qui ne s'effectuent pas sur une constante.
La commande retourne une table avec les colonnes suivantes :
Colonne | Valeur |
Table | Nom de la table |
Op | ``analyze '' (toujours) |
Msg_type | Un des status , error ,
info ou warning . |
Msg_text | Le message. |
Vous pouvez vérifier la clé de distribution stockée avec la
commande SHOW INDEX
. See
Section 13.5.3.6, « Syntaxe de SHOW DATABASES
».
Si la table n'a pas changé depuis la dernière commande
ANALYZE TABLE
, elle ne sera pas analysée
à nouveau.
BACKUP TABLE nom_de_table[,nom_de_table...] TO '/chemin/vers/le/dossier/de/sauvegardes'
Note : cette commande est
obsolète. Nous travaillons à une solution de remplacement
améliorée, qui proposera des sauvegardes à chaud. Durant ce
temps, le script mysqlhotcopy
peut être
utilisé.
Cette commande copie le nombre minimal de fichiers de table
dont en a besoin pour la restaurer vers le dossier de
sauvegardes après avoir rafraîchit les changements dans le
disque. Cela ne fonctionne actuellement que pour les tables au
format MyISAM
. Pour les tables
MyISAM
, elle ne copie que les fichiers
.frm
(définition) et
.MYD
(données), le fichier d'index
.MYD
pouvant, lui, être reconstruit à
partir des deux autres.
Avant d'utiliser cette commande, merci de lire Section 5.7.1, « Sauvegardes de base de données ».
Pendant la sauvegarde, un verrou de lecture est posé sur
chaque table, une par une, lors de leur copie. Si vous voulez
sauvegarder une image instantanée de plusieurs table, vous
devez d'abord exécuter un LOCK TABLES
obtenant un verrou de lecture pour chaque table concernée.
La commande retourne une table avec les colonnes suivantes :
Colonne | Valeur |
Table | Nom de la table |
Op | Toujours ``backup '' |
Msg_type | status , error ,
info ou encore
warning . |
Msg_text | Le message. |
Notez que BACKUP TABLE
n'est disponible en
MySQL que depuis la version 3.23.25.
CHECK TABLE tbl_name[,tbl_name...] [option [option...]] option = QUICK | FAST | MEDIUM | EXTENDED | CHANGED
CHECK TABLE
ne fonctionne qu'avec les
tables MyISAM
et InnoDB
.
Avec les tables MyISAM
, c'est l'équivalent
de la commande myisamchk -m table_name
sur
la table.
Par défaut, l'option MEDIUM
est utilisée.
Cette commande vérifie l'intégrité des tables. Pour les
tables MyISAM
, des statistiques importantes
sont mises à jour. La commande retourne les informations
suivantes sur la table dans les colonnes suivantes :
Colonne | Valeur |
Table | Nom de la table. |
Op | Toujours ``check''. |
Msg_type | Un des statut status , error ,
info ou warning . |
Msg_text | Le message. |
Notez que vous pouvez obtenir de nombreuses lignes
d'informations pour chaque table. La dernière ligne sera du
type Msg_type status
et doit être
normalement OK
. Si vous n'obtenez pas de
statut OK
ou Not
checked
, il vous faudra exécuter une réparation de
la table. See Section 5.7.3, « Utilisation de myisamchk
pour la maintenance des
tables et leur recouvrement ».
Not checked
signifie que la table a
indiqué qu'il n'y a pas de vérification à faire.
Les différents types de vérifications sont les suivants :
Type | Signification |
QUICK | N'analyse pas les lignes pour vérifier les liens erronés. |
FAST | Ne vérifie que les tables qui n'ont pas été correctement fermées. |
CHANGED | Ne vérifie que les tables qui ont changées depuis la dernière vérification, ou bien qui n'ont pas été correctement fermées. |
MEDIUM | Analyse les lignes pour s'assurer que les liens effacés sont corrects. Cette option calcule aussi la somme de contrôle des lignes, et la vérifie avec la somme de contrôle des clés. |
EXTENDED | Fait une vérification complète des liens pour chaque ligne. Cela vérifie que la table est totalement cohérente, mais cela peut prendre beaucoup de temps. |
Pour les tables à format de dynamique de type
MyISAM
, une vérification de table sera
toujours démarrée avec une option de niveau
MEDIUM
. Pour les tables à format de ligne
statique, nous évitons les niveaux de
QUICK
et FAST
car les
lignes sont rarement corrompues.
Vous pouvez combiner les options de vérification comme ceci :
CHECK TABLE test_table FAST QUICK;
L'exemple ci-dessus va simplement faire une vérification de la table, pour s'assurer qu'elle a été correctement fermée.
Note : dans certains cas,
CHECK TABLE
va modifier la table! Cela
arrive si la table a été marquée comme
"corrupted
" et "not closed
properly
" mais CHECK TABLE
n'a
trouvé aucun problème dans la table. Dans ce cas,
CHECK TABLE
va marquer la table comme
correcte.
Si une table est corrompue, il est probable que les problèmes sont dans les fichiers d'index et non pas dans les données. Tous les types de vérifications présentés ci-dessus vérifient les index soigneusement, et ils devraient trouver la plupart des erreurs.
Si vous voulez simplement vérifier une table que vous
supposez correcte, vous pouvez n'utiliser aucune option, ou
l'option QUICK
. Cette dernière peut aussi
être utilisée si vous êtes pressé, et que vous pouvez
prendre le risque minime que QUICK
ne
trouve pas d'erreur dans votre fichier. Dans la plupart des
cas, MySQL doit trouver toutes les erreurs de données, pour
un usage normal. Si cela arrive, alors la table est marquée
comme 'corrupted', auquel cas, la table ne pourra pas être
utilisée tant qu'elle n'a pas été réparée).
FAST
et CHANGED
sont
surtout destinées à être utilisées depuis un script : par
exemple, il peut être exécuté depuis une tâche
cron
, si vous voulez vérifier la table de
temps en temps. Dans la plupart des cas, l'option
FAST
doit être préférée à
CHANGED
: le seul cas ou vous pourriez
préférez CHANGED
est lorsque vous
soup¸onnez avoir trouvé un bogue dans les tables
MyISAM
.
EXTENDED
ne doit être utilisé qu'après
une vérification normale, et que vous obtenez toujours des
erreurs étranges lorsque MySQL essaie de modifier une ligne
ou trouve une ligne avec clé (ce qui est très rare, si une
vérification a réussie).
Certains problèmes rapportés par la commande CHECK
TABLE
, ne peuvent être corrigés automatiquement :
Found row where the auto_increment column has the
value 0
.
Cela signifie que vous avez dans votre table une ligne qui
contient la valeur 0 alors qu'elle est de type
AUTO_INCREMENT
. (Il est possible de
créer une ligne où la colonne
AUTO_INCREMENT
vaut 0 en spécifiant
explicitement la valeur 0 dans la colonne avec la commande
UPDATE
.
Ce n'est pas une erreur en soit, mais cela peut poser des
problèmes si vous décidez de sauver cette table dans un
fichier texte, et de la restaurer, ou encore d'appliquer
la commande ALTER TABLE
sur la table.
Dans ce cas, la colonne AUTO_INCREMENT
va changer automatiquement de valeur, en suivant les
règles des colonnes de type
AUTO_INCREMENT
, qui vont causer un
problème de clé doublon.
Pour se débarasser de cette alerte, vous devez utiliser
une commande UPDATE
sur la table, pour
mettre une valeur différente de 0 dans cette colonne.
CHECKSUM TABLE tbl_name[,tbl_name ...] [ QUICK | EXTENDED ]
Calcule la somme de contrôle de la table.
Si QUICK
est spécifié, la somme de
contrôle instantanée est retournée, ou
NULL
si la table ne supporte pas les sommes
de contrôle instantanées. See
Section 13.2.5, « Syntaxe de CREATE TABLE
».
En mode EXTENDED
, toute la table est lue,
ligne par ligne, et la somme de contrôle est calculée. Cela
peut être très lent pour les tables de grande taille.
Par défaut, sans QUICK
ni
EXTENDED
, MySQL retourne la somme de
contrôle si la table le supporte, et sinon, scanne la table.
Cette commande a été ajoutée en MySQL 4.1.1.
OPTIMIZE [LOCAL | NO_WRITE_TO_BINLOG] TABLE tbl_name [, tbl_name] ...
OPTIMIZE TABLE
doit être utilisée si une
grande partie de la base a été effacée, ou si vous avez
fait de nombreuses modifications dans une table à format de
ligne dynamique (des tables qui ont des colonnes de type
VARCHAR
, BLOB
et
TEXT
). Les lignes effacées sont
conservées dans une liste, et les prochaines opérations
d'INSERT
réutilisent les vieilles
positions de lignes. Vous pouvez vous servir de la commande
OPTIMIZE TABLE
pour récupérer l'espace
utilisé et défragmenter le fichier de données.
Dans la plupart des installations, vous n'avez pas à utiliser
OPTIMIZE TABLE
. Même si vous faites
beaucoup de mises à jour sur des colonnes à taille
dynamique, il n'est pas évident que vous ayez à passer cette
commande plus d'une fois par semaine ou par mois, et
uniquement sur quelques tables.
Pour le moment, OPTIMIZE TABLE
fonctionne
uniquement avec les tables de type MyISAM
et BDB
. Pour les tables
BDB
, OPTIMIZE TABLE
est
actuellement l'équivalent de ANALYZE
TABLE
. See Section 13.5.2.1, « Syntaxe de ANALYZE TABLE
».
Vous pouvez vous arranger pour que OPTIMIZE
TABLE
fonctionne sur d'autres types de tables, en
démarrant mysqld
avec
--skip-new
ou --safe-mode
,
mais dans ce cas, OPTIMIZE TABLE
est
simplement l'équivalent de ALTER TABLE
.
OPTIMIZE TABLE
fonctionne comme ceci :
Si la table contient des lignes effacées ou des lignes fragmentées, la table est compactée.
Si les pages d'index ne sont pas triées,
OPTIMIZE TABLE
les trie.
Si les statistiques ne sont pas à jour (et que la table n'a pas pu effectuer de réparation en triant l'index), elles sont mises à jour.
Notez que la table est verrouillée durant la commande
OPTIMIZE TABLE
.
Avant MySQL 4.1.1, OPTIMIZE
n'était pas
reportée dans le log binaire. Depuis MySQL 4.1.1 elles le
sont, à moins que l'attribut optionnel
NO_WRITE_TO_BINLOG
ou son alias
LOCAL
ne soit utilisé.
REPAIR TABLE tbl_name[,tbl_name...] [QUICK] [EXTENDED] [USE_FRM]
REPAIR TABLE
répare une table possiblement
corrompue. Par défaut, elle a le même effet que
myisamchk --recover tbl_name
sur une table.
REPAIR TABLE
fonctionne uniquement avec les
tables MyISAM
.
Normalement, vous n'avez pas à exécuter cette commande, mais
si une catastrophe vous frappe, vous êtes presque assurés de
retrouver vos données dans les tables MyISAM, avec la
commande REPAIR TABLE
. Si vos tables sont
souvent corrompues, vous devrie toutefois rechercher la cause
de ce problème! See Section A.4.2, « Que faire si MySQL plante constamment ? ». See
Section 14.1.4, « Problèmes avec les tables MyISAM
».
REPAIR TABLE
répare autant que possible
les tables corrompues. La commande retourne la table
suivante :
Colonne | Valeur |
Table | Nom de la table |
Op | Toujours repair |
Msg_type | Un des statut status , error ,
info ou warning . |
Msg_text | Le message |
La commande REPAIR TABLE
pourrait afficher
plusieurs messages pour chaque table. La dernière ligne doit
être du format Msg_type status
et doit
être normalement OK
. Si vous n'obtenez pas
OK
, vous devez essayer de réparer votre
table avec la commande myisamchk -o
, car
REPAIR TABLE
de supporte pas encore toutes
les options de myisamchk
. Dans un futur
proche, nous allons rendre cette commande encore plus souple.
Si l'option QUICK
est fournie, alors MySQL
va essayer de ne réparer que le fichier d'index. Ce type de
réparation est le même que myisamchk --recover
--quick
.
Si vous utilisez l'option EXTENDED
, alors
MySQL va essayer de créer l'index ligne par ligne, au lieu de
créer un index à la fois, par tri. C'est une méthode qui
peut s'avérer plus efficace que de trier sur des clés de
taille fixe, si vous avez des clés CHAR
longues qui se compressent bien. Ce type de réparation est
l'équivalent de myisamchk --safe-recover
.
Depuis MySQL 4.0.2, il existe le mode
USE_FRM
pour REPAIR
.
Utilisez-le si le fichier .MYI
manque, ou
si son entête est corrompu. Avec ce mode, MySQL va recréer
le fichier .MYI
, en utilisant les
informations du fichier .frm
. Ce type de
réparation ne peut pas être fait avec
myisamchk
.
Attention : si le serveur
s'arrête durant l'opération REPAIR TABLE
,
il est important d'exécuter à nouveau la commande
REPAIR TABLE
après le redémarrage (il est
bon de faire une sauvegarde de toutes manières). Dans le pire
scénario, vous pourriez vous retrouver avec un nouvel index
sans relation avec les données, et la prochaine opération
risque d'écraser le fichier de données. C'est peu probable,
mais possible.
Avant MySQL 4.1.1, les commandes REPAIR
TABLE
n'étaient pas écrites dans le log binaire.
Depuis MySQL 4.1.1, elles sont écrites dans le log binaire à
moins que la clause NO_WRITE_TO_BINLOG
ne
soit utilisée (aussi connue sous le nom de
LOCAL
).
RESTORE TABLE nom_de_table[,nom_de_table...] FROM '/chemin/vers/le/dossier/de/sauvegardes'
Restaure la ou les tables à partir d'une sauvegarde
effectuée avec BACKUP TABLE
. Les tables
existantes ne seront pas écrasées et dans ce cas là, vous
obtiendrez une erreur. La restauration prendra plus de temps
que la sauvegarde à cause de la reconstruction du fichier
d'index. Plus vous avez de clefs, plus la restauration sera
longue. Tout comme BACKUP TABLE
,
RESTORE TABLE
fonctionne seulement avec les
tables MyISAM
.
La sauvegarde de chaque table est constituée du fichier de
format .frm
et du fichier de données
.MYD
. L'opération de restauration
restaure ces fichiers, puis les utilise pour reconstruire le
fichier d'index .MYI
. La restauration
prend plus de temps que la sauvegarde, car il faut
reconstituer l'index. Plus la table a d'index, plus cela
prendra de temps.
Cette commande retourne un tableau avec les colonnes suivantes :
Colonne | Valeur |
Table | Nom de la table |
Op | Toujours ``restore '' |
Msg_type | status , error ,
info ou encore
warning . |
Msg_text | Le message. |
SET variable_assignment [, variable_assignment] ... variable_assignment: user_var_name = expr | [GLOBAL | SESSION] system_var_name = expr | @@[global. | session.]system_var_name = expr
SET
permet de configurer plusieurs options
qui affectent le comportement de votre serveur ou de votre
client.
En MySQL 4.0.3, nous avons ajouté les options
GLOBAL
et SESSION
et
permis la modification des variables systèmes les plus
importantes dynamiquement, durant l'exécution du serveur. Le
système de variables que vous pouvez utiliser est décrit
dans Section 5.2.3.1, « Variables système dynamiques ».
Dans les anciennes versions de MySQL, nous avions autorisé
l'utilisation de la syntaxe SET OPTION
,
mais elle est maintenant abandonnée. Omettez simplement le
mot OPTION
.
Les exemples suivants montrent les différentes syntaxes qu'on peut utiliser pour configurer des variables.
Une variable utilisateur s'écrit sous la forme
@var_name
et peut être configurée comme
ceci :
SET @var_name = expr;
Plus d'informations sur les variables utilisateurs sont données dans Section 9.3, « Variables utilisateur ».
Les variables système peuvent être identifiées dans une
commande SET
sous la forme
var_name
. Le nom peut être optionnellement
précédé par GLOBAL
ou
@@global.
pour indiquer que cette variable
est globale, ou par SESSION
,
@@session.
, ou @@
pour
indiquer que cette variable est une variable de session.
LOCAL
et @@local.
son
synonymes de SESSION
et
@@session.
. Si aucune option n'est
présente, SET
spécifie une variable de
session.
La syntaxe @@var_name
pour les variables
système est supportée pour rendre la syntaxe MySQL
compatible avec les autres bases.
Si vous configurez plusieurs variables sur une seule ligne de
commande, le dernier mode GLOBAL | SESSION
utilisé est pris en compte.
SET sort_buffer_size=10000; SET @@local.sort_buffer_size=10000; SET GLOBAL sort_buffer_size=1000000, SESSION sort_buffer_size=1000000; SET @@sort_buffer_size=1000000; SET @@global.sort_buffer_size=1000000, @@local.sort_buffer_size=1000000;
Si vous utilisez SESSION
(par défaut)
l'option que vous configurez garde son effet jusqu'à ce que
la session courante se termine, ou que vous modifiez à
nouveau cette option. Si vous utilisez
GLOBAL
, qui requière le privilège
SUPER
, l'option est gardée en mémoire et
utilisée pour les nouvelles connexion jusqu'au redémarrage
du serveur. Si vous voulez qu'un changement reste permanent,
vous devez l'effectuer dans l'un des fichiers d'options de
MySQL. See Section 4.3.2, « Fichier d'options my.cnf
».
Pour éviter un mauvais usage, MySQL donnera une erreur si
vous utilisez SET GLOBAL
avec une variable
qui ne peut être inutilisée que par SET
SESSION
ou si vous n'utilisez pas SET
GLOBAL
avec une variable globale.
Si vous voulez configurer une variable
SESSION
à une valeur
GLOBAL
ou une valeur
GLOBAL
à la valeur par défaut de MySQL,
vous pouvez la configurer à DEFAULT
.
SET max_join_size=DEFAULT; SET @@session.max_join_size=@@global.max_join_size;
Vous pouvez obtenir une liste de la plupart des variables avec
SHOW VARIABLES
. See
Section 13.5.3.18, « Syntaxe de SHOW VARIABLES
». Vous pouvez obtenir la
valeur d'une variable spécifique avec la syntaxe
@@[global.|local.]nom_variable
:
SHOW VARIABLES LIKE 'max_join_size'; SHOW GLOBAL VARIABLES LIKE 'max_join_size';
Vous pouvez aussi obtenir une valeur spécifique d'une
variable en utilisant la syntaxe
@@[global.|local.]var_name
avec
SELECT
:
SELECT @@max_join_size, @@global.max_join_size;
Lorsque vous lisez la valeur d'une variable avec la syntaxe
SELECT @@var_name
(c'est à dire, sans
spécifier global.
,
session.
ou local.
),
MySQL retourne la valeur de SESSION
si elle
existe, et la valeur GLOBAL
sinon.
Vous trouverez ici une description des variables qui utilisent
une syntaxe non-standard de SET
. Les
définitions des autres variables peuvent être trouvées dans
la section des Section 5.2.3, « Variables serveur système », avec
les options de démarrage ou dans la description de
SHOW VARIABLES
.
Même si ces variables ne sont pas affichées par
SHOW VARIABLES
, vous pouvez obtenir leur
valeur avec la commande SELECT
(à
l'exception de CHARACTER SET
). Par
exemple :
mysql> SELECT @@AUTOCOMMIT;
+--------------+
| @@autocommit |
+--------------+
| 1 |
+--------------+
AUTOCOMMIT= {0 | 1}
Si définie à 1
tous les changements
dans une table se feront en une seule fois. Pour démarrer
une transaction multi-commandes, vous devez utiliser la
commande BEGIN
. See
Section 13.4.1, « Syntaxes de START TRANSACTION
,
COMMIT
et ROLLBACK
». Si définie à
0
vous devez utiliser
COMMIT
/ ROLLBACK
pour accepter/annuler cette transaction. Notez que quand
vous passez du mode non AUTOCOMMIT
vers
le mode AUTOCOMMIT
, MySQL fera un
COMMIT
automatique sur toutes les
transactions en cours.
Si définie à 1
, toutes les tables
temporaires sont stockées sur le disque plutôt qu'en
mémoire. Cela sera un peu plus lent, mais vous
n'obtiendrez jamais l'erreur The table
nom_de_table is full
pour les grands
SELECT
qui requièrent une table
temporaire. La valeur par défaut pour une nouvelle
connexion est 0
(qui est d'utiliser la
mémoire pour les tables temporaires). Cette option se
nommait avant SQL_BIG_TABLES
.
CHARACTER SET {charset_name | DEFAULT}
Cela change le jeu de caractère dans toutes les chaînes
du et vers le client avec le jeu donné. Jusqu'à
maintenant, la seule option pour
nom_jeu_de_caractères
est
cp1251_koi8
, mais vous pouvez
facilement ajouter d'autres possibilités en éditant le
fichier sql/convert.cc
dans la
distribution des sources MySQL. Le jeu de caractères par
défaut peut être restauré en utilisant la valeur
DEFAULT
de
nom_jeu_de_caractères
DEFAULT
.
Notez que la syntaxe pour configurer l'option
CHARACTER SET
diffère de la syntaxe
pour configurer les autres options.
FOREIGN_KEY_CHECKS = {0 | 1}
Si cette option vaut 1
(par défaut),
les contraintes de clé étrangères des tables
InnoDB
sont vérifiées. Si cette
option vaut 0
, elles sont ignorées.
Désactiver les clés étrangères peut être pratique
pour recharger des tables InnoDB
dans
un ordre différent que celui qu'impose les relations de
contraintes. Cette variable a été ajoutée en MySQL
3.23.52. See
Section 15.7.4, « Contraintes de clés étrangères FOREIGN KEY
».
IDENTITY = valeur
Cette variable est un synonyme de la variable
LAST_INSERT_ID
. Elle existe pour des
raisons de compatibilité avec les autres bases. Depuis
MySQL 3.23.25, vous pouvez lire sa valeur avec
SELECT @@IDENTITY
. Depuis MySQL 4.0.3,
vous pouvez aussi modifier cette valeur avec SET
IDENTITY
.
INSERT_ID = valeur
Configure la valeur à utiliser par l'appel suivant à la
commande INSERT
ou ALTER
TABLE
lors de l'insertion d'une valeur
AUTO_INCREMENT
. Cela est souvent
utilisé par le log des modifications.
LAST_INSERT_ID = valeur
Configure la valeur qui doit être retournée par
LAST_INSERT_ID()
. C'est enregistré
dans le log de mises à jour quand vous utilisez
LAST_INSERT_ID()
dans une commande qui
met à jour une table.
NAMES {'charset_name' | DEFAULT}
SET NAMES
spécifie les valeurs des
trois variables systèmes de session
character_set_client
,
character_set_connection
et
character_set_results
avec le jeu de
caractères donné.
La valeur par défaut de ces variables peut être
rappelée avec DEFAULT
.
Notez que la syntaxe de SET NAMES
diffère en cela des autres options. Cette commande est
disponible depuis MySQL 4.1.0.
SQL_AUTO_IS_NULL = {0 | 1}
Si définie à 1
(par défaut) alors on
peut trouver la dernière ligne insérée dans une table
avec une colonne AUTO_INCREMENT
avec la
construction suivante :
WHERE auto_increment_column IS NULL
Ceci est utilisé par des programmes ODBC tel que Access.
SQL_AUTO_IS_NULL
a été ajouté en
MySQL 3.23.52.
SQL_BIG_SELECTS = {0 | 1}
Si configuré à 0
, MySQL interrompra
les requêtes SELECT
qui prendront
probablement trop de temps. C'est utile lorsqu'une clause
WHERE
déconseillée a été utilisée.
Une grosse requête est définie comme étant un
SELECT
qui devra probablement étudier
plus de max_join_size
lignes. La valeur
par défaut d'une nouvelle connexion est
1
(qui permet toutes les requêtes
SELECT
).
SQL_BUFFER_RESULT = {0 | 1}
SQL_BUFFER_RESULT
forcera les
résultats des requêtes SELECT
à
être placés dans une table temporaire. Cela aidera MySQL
à libérer les verrous sur table plus tôt et améliorera
les cas où le jeu de résultats de la requête prend trop
de temps à être envoyée au client.
SQL_LOG_BIN = {0 | 1}
Si cette option vaut 0
, aucun log n'est
fait dans le log binaire du client, si le client a les
droits de SUPER
.
SQL_LOG_OFF = {0 | 1}
Si cette option vaut 1
, aucun log n'est
fait dans le log standard du client, si le client a les
droits de SUPER
.
SQL_LOG_UPDATE = {0 | 1}
Si définie à 0
, aucune trace des
requêtes ne sera gardée dans le log des mises à jour
pour le client, si le client à le privilège
SUPER
. Cette variable est abandonnée
depuis la version 5.0.0 et est remplacée par
SQL_LOG_BIN
(see
Section C.1.7, « Changements de la version 5.0.0 (22 décembre 2003 : Alpha) »).
SQL_QUOTE_SHOW_CREATE = {0 | 1}
Si vous le configurez à 1
,
SHOW CREATE TABLE
protégera les noms
de tables et de colonnes. Ceci est activé par défaut,
pour que la réplication des tables avec des noms à
risques fonctionne. Section 13.5.3.5, « Syntaxe de SHOW CREATE TABLE
».
SQL_SAFE_UPDATES = {0 | 1}
Si définit à 1
, MySQL annulera si un
UPDATE
ou un DELETE
est exécuté alors qu'il n'utilise pas de clef ou de
LIMIT
dans la clause
WHERE
. Cela permet de bloquer les
requêtes erronées crées à la main.
SQL_SELECT_LIMIT = valeur | DEFAULT
Le nombre maximal des enregistrements que doivent
retourner les requêtes SELECT
. Si un
SELECT
possède une clause
LIMIT
, celle-ci est utilisée. La
valeur par défaut pour une nouvelle connexion est
``illimitée.'' Si vous avez changé la limite, la valeur
par défaut peut être retrouvée en utilisant la valeur
DEFAULT
avec
SQL_SELECT_LIMIT
.
SQL_WARNINGS = {0 | 1}
Cette variable contrôle le fait que les insertion
mono-ligne INSERT
produisent une
chaîne d'information si une alerte survient. La valeur
par défaut est 0. Donnez la valeur de 1 pour avoir un
message d'information. Cette variable a été ajoutée en
MySQL 3.22.11.
TIMESTAMP = valeur_timestamp | DEFAULT
Configure le temps pour ce client. C'est utilisé pour
obtenir le timestamp d'origine si vous utilisez le log de
mises à jour pour restaurer des lignes.
valeur_timestamp
doit être un
timestamp Unix, et non un timestamp MySQL.
UNIQUE_CHECKS = {0 | 1}
Si cette option vaut 1
(par défaut),
les tests d'unicité sur les index secondaires des tables
InnoDB
sont effectués. Si l'option
vaut 0
, aucun test d'unicité n'est
fait. Cette variable a été ajouté en MySQL 3.23.52. See
Section 15.7.4, « Contraintes de clés étrangères FOREIGN KEY
».
SHOW CHARACTER SET
SHOW COLLATION
SHOW COLUMNS
SHOW CREATE DATABASE
SHOW CREATE TABLE
SHOW DATABASES
SHOW ENGINES
SHOW ERRORS
SHOW GRANTS
SHOW INDEX
SHOW INNODB STATUS
SHOW LOGS
SHOW PRIVILEGES
SHOW PROCESSLIST
SHOW STATUS
SHOW TABLE STATUS
SHOW TABLES
SHOW VARIABLES
SHOW WARNINGS | ERRORS
SET
vous permet de modifier des variables et
options.
SHOW
a de très nombreuses formes, pour
donner des informations sur les bases, tables, colonnes ou le
serveur. Cette section les décrit.
SHOW [FULL] COLUMNS FROM tbl_name [FROM db_name] [LIKE 'pattern'] SHOW CREATE DATABASE db_name SHOW CREATE TABLE tbl_name SHOW DATABASES [LIKE 'pattern'] SHOW [STORAGE] ENGINES SHOW ERRORS [LIMIT [offset,] row_count] SHOW GRANTS FOR user SHOW INDEX FROM tbl_name [FROM db_name] SHOW INNODB STATUS SHOW [BDB] LOGS SHOW PRIVILEGES SHOW [FULL] PROCESSLIST SHOW STATUS [LIKE 'pattern'] SHOW TABLE STATUS [FROM db_name] [LIKE 'pattern'] SHOW [OPEN] TABLES [FROM db_name] [LIKE 'pattern'] SHOW [GLOBAL | SESSION] VARIABLES [LIKE 'pattern'] SHOW WARNINGS [LIMIT [offset,] row_count]
Si la syntaxe d'une commande SHOW
inclut la
clause LIKE 'pattern'
,
'pattern'
est une expression régulière qui
peut contenir les jokers ‘%
’ et
‘_
’. Ce expression est utile pour
restreindre la commande à une partie des valeurs normalement
retournées.
Notez qu'il y a d'autres formes pour ces commandes, décrites à d'autres endroits du manuel :
La commande SET PASSWORD
pour assigner un
mot de passe à un compte est présentée dans See
Section 13.5.1.5, « Syntaxe de SET PASSWORD
».
La commande SHOW
a des formes pour
afficher des informations sur la réplication, pour le
maître et l'esclave :
SHOW BINLOG EVENTS SHOW MASTER LOGS SHOW MASTER STATUS SHOW SLAVE HOSTS SHOW SLAVE STATUS
Ces formes de SHOW
sont décrites dans
Section 13.6, « Commandes de réplication ».
La commande SHOW CHARACTER SET
montre tous
les jeux de caractères disponibles. Il faut une clause
facultative LIKE
pour limiter les jeux de
caractères à afficher.
Par exemple :
mysql> SHOW CHARACTER SET LIKE 'latin%';
+---------+-----------------------------+-------------------+--------+
| Charset | Description | Default collation | Maxlen |
+---------+-----------------------------+-------------------+--------+
| latin1 | ISO 8859-1 West European | latin1_swedish_ci | 1 |
| latin2 | ISO 8859-2 Central European | latin2_general_ci | 1 |
| latin5 | ISO 8859-9 Turkish | latin5_turkish_ci | 1 |
| latin7 | ISO 8859-13 Baltic | latin7_general_ci | 1 |
+---------+-----------------------------+-------------------+--------+
4 rows in set (0.00 sec)
Remarques sur la liste précédente :
La colonne Maxlen
affiche le nombre
maximum d'octets utilisés pour stocker un caractère.
SHOW COLLATION [LIKE 'pattern']
Le résultat de SHOW COLLATION
inclut tous
les jeux de caractères disponibles. Vous pouvez utiliser
optionnellement la clause LIKE
pour limiter
le nombre de réponses.
mysql> SHOW COLLATION LIKE 'latin1%';
+-------------------+---------+----+---------+----------+---------+
| Collation | Charset | Id | Default | Compiled | Sortlen |
+-------------------+---------+----+---------+----------+---------+
| latin1_german1_ci | latin1 | 5 | | | 0 |
| latin1_swedish_ci | latin1 | 8 | Yes | Yes | 0 |
| latin1_danish_ci | latin1 | 15 | | | 0 |
| latin1_german2_ci | latin1 | 31 | | Yes | 2 |
| latin1_bin | latin1 | 47 | | Yes | 0 |
| latin1_general_ci | latin1 | 48 | | | 0 |
| latin1_general_cs | latin1 | 49 | | | 0 |
| latin1_spanish_ci | latin1 | 94 | | | 0 |
+-------------------+---------+----+---------+----------+---------+
7 rows in set (0.00 sec)
La colonne Default
indique si une collation
est la collation par défaut pour son jeu de caractères.
Compiled
indique si le jeu de caractères
est compilé dans le serveur ou non.
Sortlen
est en relation avec la quantité
de mémoire nécessaire pour trier des chaînes exprimées
dans le jeu de caractéres.
SHOW [FULL] COLUMNS FROM tbl_name [FROM db_name] [LIKE 'pattern']
SHOW COLUMNS
liste les colonnes de la
table. Si les types de colonnes sont différents de ceux que
vous avez utilisé avec la commande CREATE
TABLE
, c'est que MySQL a modifié silencieusement le
type lors de la création. Les conditions de cette
modification sont décrites dans
Section 13.2.5.1, « Modification automatique du type de colonnes ».
Le mot clé FULL
peut être utilisé depuis
MySQL 3.23.32. Il fait afficher les droits dont vous disposez
pour chaque colonne. Depuis MySQL 4.1, FULL
affiche aussi les commentaires par colonne.
Vous pouvez utiliser db_name.tbl_name
comme
syntaxe alternative à tbl_name FROM
db_name
. Ces deux commandes sont équivalentes :
mysql>SHOW COLUMNS FROM mytable FROM mydb;
mysql>SHOW COLUMNS FROM mydb.mytable;
SHOW FIELDS
est un synonyme de
SHOW COLUMNS
. Vous pouvez aussi lister les
colonnes d'une table avec la commande mysqlshow
db_name tbl_name
.
La commande DESCRIBE
fournit une
information similaire à SHOW COLUMNS
. See
Section 13.3.1, « Syntaxe de DESCRIBE
(obtenir des informations sur les
colonnes) ».
SHOW CREATE DATABASE db_name
La requête suivante montre une commande CREATE
DATABASE
qui va créer une base de donnée. Commande
ajoutée en MySQL 4.1.
mysql> SHOW CREATE DATABASE test\G
*************************** 1. row ***************************
Database: test
Create Database: CREATE DATABASE `test`
/*!40100 DEFAULT CHARACTER SET latin1 */
SHOW CREATE TABLE tbl_name
Affiche la commande CREATE TABLE
nécessaire pour créer une table donnée.
mysql> SHOW CREATE TABLE t\G
*************************** 1. row ***************************
Table: t
Create Table: CREATE TABLE t (
id int(11) default NULL auto_increment,
s char(60) default NULL,
PRIMARY KEY (id)
) TYPE=MyISAM
SHOW CREATE TABLE
va protéger le nom de la
table et des colonnes selon l'option
SQL_QUOTE_SHOW_CREATE
.
Section 13.5.2.8, « Syntaxe de SET
».
SHOW {DATABASES | SCHEMAS} [LIKE 'pattern
']
SHOW DATABASES
liste les bases de données
disponible sur le serveur MySQL. Vous pouvez aussi obtenir
cette liste avec l'utilitaire mysqlshow
.
Depuis MySQL 4.0.2, vous ne verrez que les bases pour
lesquelles vous avez des droits, à moins que vous n'ayez le
droit de SHOW DATABASES
.
Si le serveur a été lancé avec l'option
--skip-show-database
, vous ne pouvez pas
utiliser cette commande à moins que vous n'ayez le droit de
SHOW DATABASES
.
SHOW SCHEMAS
est disponible depuis MySQL
5.0.2
SHOW [STORAGE] ENGINES
SHOW ENGINES
affiche les informations sur
les moteurs de stockage du serveur. C'est particulièrement
utile pour connaître les moteurs supportés par votre
serveur, ou le moteur par défaut. Cette commande a été
ajoutée en MySQL 4.1.2. SHOW TABLE TYPES
est un synonyme, mais est abandonnée.
mysql> SHOW ENGINES\G
*************************** 1. row ***************************
Type: MyISAM
Support: DEFAULT
Comment: Default type from 3.23 with great performance
*************************** 2. row ***************************
Type: HEAP
Support: YES
Comment: Hash based, stored in memory, useful for temporary tables
*************************** 3. row ***************************
Type: MEMORY
Support: YES
Comment: Alias for HEAP
*************************** 4. row ***************************
Type: MERGE
Support: YES
Comment: Collection of identical MyISAM tables
*************************** 5. row ***************************
Type: MRG_MYISAM
Support: YES
Comment: Alias for MERGE
*************************** 6. row ***************************
Type: ISAM
Support: NO
Comment: Obsolete table type; Is replaced by MyISAM
*************************** 7. row ***************************
Type: MRG_ISAM
Support: NO
Comment: Obsolete table type; Is replaced by MRG_MYISAM
*************************** 8. row ***************************
Type: InnoDB
Support: YES
Comment: Supports transactions, row-level locking and foreign keys
*************************** 9. row ***************************
Type: INNOBASE
Support: YES
Comment: Alias for INNODB
*************************** 10. row ***************************
Type: BDB
Support: YES
Comment: Supports transactions and page-level locking
*************************** 11. row ***************************
Type: BERKELEYDB
Support: YES
Comment: Alias for BDB
La valeur Support
indique que le moteur est
supporté, et si le moteur est le moteur par défaut. Par
exemple, si le serveur est lancé avec l'option
--default-table-type=InnoDB
alors la valeur
de la colonne Support
de la ligne
InnoDB
contiendra
DEFAULT
.
SHOW ERRORS [LIMIT [offset,] row_count] SHOW COUNT(*) ERRORS
Cette commande est similaire à SHOW
WARNINGS
, hormis le fait qu'au lieu d'afficher les
erreurs, alertes et notes, elle n'affiche que les erreurs.
SHOW ERRORS
est disponible depuis MySQL
4.1.0.
La clause LIMIT
a la même syntaxe que
celle de la commande SELECT
. See
Section 13.1.7, « Syntaxe de SELECT
».
La commande SHOW COUNT(*) ERRORS
affiche le
nombre d'erreurs. Vous pouvez aussi connaître ce nombre en
lisant la variable error_count
:
SHOW COUNT(*) ERRORS; SELECT @@error_count;
Pour plus d'informations, voyez
Section 13.5.3.19, « SHOW WARNINGS | ERRORS
».
SHOW GRANTS FOR user
SHOW GRANTS FOR user
affiche la commande
nécessaire pour donner les même droits qu'un utilisateur
existant.
mysql> SHOW GRANTS FOR 'root'@'localhost';
+---------------------------------------------------------------------+
| Grants for root@localhost |
+---------------------------------------------------------------------+
| GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION |
+---------------------------------------------------------------------+
Depuis MySQL 4.1.2, pour lister les droits de la session courante, vous pouvez connaître le nom d'utilisateur de la session avec ces commandes :
SHOW GRANTS; SHOW GRANTS FOR CURRENT_USER; SHOW GRANTS FOR CURRENT_USER();
Avant MySQL 4.1.2, vous pouviez connaître le nom
d'identification de l'utilisation avec la fonction
CURRENT_USER()
(nouveau en MySQL 4.0.6).
Puis, utilisez cette valeur avec la commande SHOW
GRANTS
. See Section 12.8.3, « Fonctions d'informations ».
SHOW GRANTS
est disponible depuis MySQL
3.23.4.
SHOW INDEX FROM tbl_name [FROM db_name]
SHOW INDEX
retourne les informations sur
les index de la table, dans un format proche de celui de
SQLStatistics
en ODBC.
SHOW INDEX
retourne les champs suivants :
Table
Le nom de la table.
Non_unique
0 si l'index ne peut pas contenir de doublons, et 1 s'il le peut.
Key_name
Le nom de l'index.
Seq_in_index
Le numéro de la colonne dans l'index, en commen¸ant à 1.
Column_name
Le nom de la colonne.
Collation
Comment la colonne est triée dans l'index. Avec MySQL,
les valeurs peuvent être
‘A
’ (Ascendant) ou
NULL
(non trié).
Cardinality
Le nombre de valeurs uniques dans l'index. C'est une
valeur qui est mise à jour avec la commande
ANALYZE TABLE
ou myisamchk
-a
. Cardinality
est compté
en se basant sur des statistiques entières : il n'est
pas toujours exacte pour les petites tables.
Sub_part
Le nombre de caractères indexé si la colonne n'est que
partiellement indexée. NULL
si la
colonne entière est indexée.
Packed
Indique comment la clé est compactée.
NULL
si elle ne l'est pas.
Null
Contient YES
si la colonne contient
NULL
, ''
sinon.
Index_type
La méthode d'indexation utilisée
(BTREE
, FULLTEXT
,
HASH
, RTREE
).
Comment
Différentes remarques. Avant MySQL 4.0.2 lorsque la
colonne Index_type
a été ajoutée,
Comment
indiquait si un index était
FULLTEXT
.
Les colonnes Packed
et
Comment
ont été ajoutée en MySQL 3.23.0.
Les colonnes Null
et
Index_type
ont été ajoutées en MySQL
4.0.2.
Vous pouvez utiliser la syntaxe
db_name.tbl_name
comme alternative à
tbl_name FROM db_name
. Ces deux commandes
sont équivalentes :
mysql>SHOW INDEX FROM mytable FROM mydb;
mysql>SHOW INDEX FROM mydb.mytable;
SHOW KEYS
est un synonyme SHOW
INDEX
. Vous pouvez aussi lister les index d'une
table avec la commande en ligne mysqlshow -k db_name
tbl_name
.
SHOW INNODB STATUS
Cette commente donne des informations exhaustives sur le
moteur de stockage InnoDB
.
SHOW [BDB] LOGS
La commande SHOW LOGS
affiche les
informations d'état de vos fichiers de logs. Actuellement,
elle n'affiche que les informations pour les fichiers de log
des tables Berkeley DB.
File
affiche le chemin complet jusqu'au
fichier de log.
Type
affiche le type de fichier de log
(BDB
pour les tables de types Berkeley
DB)
Status
affiche le status du fichier de
log (FREE
si le fichier peut être
supprimé, ou IN USE
si le fichier est
utilisé par une transaction en cours)
SHOW PRIVILEGES
Cette commande est implémentée en MySQL 4.1.0.
SHOW PRIVILEGES
affiche la liste des droits
que le serveur MySQL supporte.
mysql> show privileges;
+------------+--------------------------+-------------------------------------------------------+
| Privilege | Context | Comment |
+------------+--------------------------+-------------------------------------------------------+
| Select | Tables | Lire des lignes d'une table |
| Insert | Tables | Insérer des lignes dans une table |
| Update | Tables | Modifier les lignes existantes |
| Delete | Tables | Effacer des lignes existantes |
| Index | Tables | Créer ou effacer des indexes |
| Alter | Tables | Modifier la structure d'une table |
| Create | Databases,Tables,Indexes | Créer une nouvelle base ou table |
| Drop | Databases,Tables | Effacer une base ou table |
| Grant | Databases,Tables | Donner à d'autres les droits courants |
| References | Databases,Tables | Avoir des références sur les tables |
| Reload | Server Admin | Rafraîchir les droits, tables et logs |
| Shutdown | Server Admin | Eteindre le serveurver |
| Process | Server Admin | Voir la version texte des requêtes en cours |
| File | File access on server | Lire et écrire des fichiers sur le serveur |
+------------+--------------------------+-------------------------------------------------------+
14 rows in set (0.00 sec)
SHOW [FULL] PROCESSLIST
SHOW [FULL] PROCESSLIST
affiche la liste de
processus qui sont en cours d'exécution. Vous pouvez aussi
obtenir ces informations avec la commande en ligne
mysqladmin processlist
. Si vous avez les
droits de SUPER
, vous pourrez aussi voir
les autres threads. Sinon, vous ne pourrez voir que les votre.
See Section 13.5.4.3, « Syntaxe de KILL
». Si vous n'utilisez pas l'option
FULL
, seuls les 100 premiers caractères de
chaque requête seront affichés.
Cette commande est très pratique si vous obtenez trop
d'erreurs ‘too many
connections
’ et que vous voulez savoir ce qui
se passe. MySQL réserve une connexion supplémentaire pour un
client ayant les droits de SUPER
, de fa¸on
à ce qu'il y ait toujours la possibilité de se connecter et
de vérifier le système (en supposant que vous ne donnez pas
ce droit à tous vos utilisateurs).
Certains états sont souvent disponible dans le résultat de
mysqladmin processlist
Checking table
Le thread fait une vérification (automatique) de la table.
Closing tables
Le thread est en train d'écrire les données modifiées sur le disque, et il va fermer les tables. Cela doit être une opération très rapide. Si ce n'est pas le cas, vous devriez vérifier si vous n'avez pas un disque plein, ou que le disque est sous haute charge.
Connect Out
Connexion d'un esclave sur le maître.
Copying to tmp table on disk
Le résultat temporaire était plus grand que
tmp_table_size
et le thread passe d'une
table en mémoire à une table sur disque.
Creating tmp table
Le thread est en train de créer une table temporaire pour contenir le résultat d'une requête.
deleting from main table
Lors de l'exécution de la première partie d'une requête d'effacement multi-table, et que MySQL n'a commencé à effacer que dans la première table.
deleting from reference tables
Lors de l'exécution de la deuxième partie d'une requête d'effacement multi-table, et que MySQL a commencé à effacer dans les autres tables.
Flushing tables
Le thread exécute la commande FLUSH
TABLES
et il attend que tous les threads ferme
leur tables.
Killed
Quelqu'un a envoyé une commande KILL
et le thread s'annuler la prochaine fois qu'il vérifie
l'option de kill. Cette option est vérifiée dans chaque
boucle majeure de MySQL, mais dans certains cas, il peut
lui prendre un court instant avant de s'arrêter. Si le
thread est verrouillé par un autre thread, l'arrêt va
prendre effet aussitôt que l'autre thread lève son
verrou.
Sending data
Le thread traite des lignes pour une commande
SELECT
et il envoie les données au
client.
Sorting for group
Le thread est en train de faire un tri pour satisfaire une
clause GROUP BY
.
Sorting for order
Le thread est en train de faire un tri pour satisfaire une
clause ORDER BY
.
Opening tables
Cela signifie simplement que le thread essaie d'ouvrir une
table. Ce doit être une opération très rapide, à moins
que quelque chose ne retarde l'ouverture. Par exemple, une
commande ALTER TABLE
ou LOCK
TABLE
peut empêcher l'ouverture de table,
jusqu'à l'achèvement de la commande.
Removing duplicates
La requête utilisait SELECT DISTINCT
de telle manière que MySQL ne pouvait pas optimiser les
lignes distinctes au début du traitement. A cause de
cela, MySQL doit effectuer une opération de plus pour
supprimer toutes les lignes en doubles, avant d'envoyer
les lignes au client.
Reopen table
Le thread a re¸u un verrou pour une table, mais a noté après l'avoir re¸u que la structure de la table a changé. Il a libéré le verrou, fermé la table, et maintenant il essaie de la rouvrir.
Repair by sorting
Le thread répare la table en utilisant la méthode de tri pour créer l'index.
Repair with keycache
Le thread répare la table en utilisant la méthode de
création des clés à partir du cache de clé. C'est bien
plus lent que la réparation par tri
.
Searching rows for update
Le thread effectue une première phase pour trouver toutes
les lignes qui satisfont les critères avant de les
modifier. Cela doit être fait si
UPDATE
modifie l'index qui sera
utilisé pour trouver les lignes.
Sleeping
Le thread attend que le client envoie une nouvelle commande.
System lock
Le thread attend le verrou externe pour la table. Si vous
n'utilisez pas de serveurs MySQL multiples qui exploitent
les mêmes tables, vous pouvez désactiver les verrous
systèmes avec l'option
--skip-external-locking
.
Upgrading lock
Le gestionnaire de INSERT DELAYED
essaie d'obtenir un verrou pour insérer des lignes.
Updating
Le thread recherche des lignes pour les modifier.
User Lock
Le thread attend un GET_LOCK()
.
Waiting for tables
Le thread a re¸u l'annonce que la structure de table a été modifiée, et il doit réouvrir la table pour obtenir une nouvelle structure. Pour être capable de réouvrir la table, il doit attendre que les autres threads aient fermé la table en question.
Cette annonce survient lorsqu'un autre autre thread a
été utilisé avec la commande FLUSH
TABLES
ou une des commandes suivantes,
appliquées à la table en question : FLUSH
TABLES table_name
, ALTER
TABLE
, RENAME TABLE
,
REPAIR TABLE
, ANALYZE
TABLE
ou OPTIMIZE TABLE
.
waiting for handler insert
Le gestionnaire de INSERT DELAYED
a
traité toutes insertions, et en attend de nouvelles.
La plupart des états sont des opérations très rapides. Si le thread s'attarde dans un de ces états pour plusieurs secondes, il doit y avoir un problème qui mérite d'être étudié.
Il existe encore d'autres états qui ne sont pas mentionné
ci-dessus, mais la majorité sont utilisés pour trouver des
bogues dans mysqld
.
SHOW STATUS [LIKE 'pattern']
SHOW STATUS
affiche des informations sur le
statut du serveur. Cette information est aussi accessible avec
la commande la commande mysqladmin
extended-status
.
Un résultat partiel est présenté ci-dessous. La liste complète des variables dépend de votre serveur. Leur signification individuelle est présentée dans la section See Section 5.2.4, « Variables de statut du serveur ».
mysql> SHOW STATUS;
+--------------------------+------------+
| Variable_name | Value |
+--------------------------+------------+
| Aborted_clients | 0 |
| Aborted_connects | 0 |
| Bytes_received | 155372598 |
| Bytes_sent | 1176560426 |
| Connections | 30023 |
| Created_tmp_disk_tables | 0 |
| Created_tmp_tables | 8340 |
| Created_tmp_files | 60 |
...
| Open_tables | 1 |
| Open_files | 2 |
| Open_streams | 0 |
| Opened_tables | 44600 |
| Questions | 2026873 |
...
| Table_locks_immediate | 1920382 |
| Table_locks_waited | 0 |
| Threads_cached | 0 |
| Threads_created | 30022 |
| Threads_connected | 1 |
| Threads_running | 1 |
| Uptime | 80380 |
+--------------------------+------------+
Avec la clause LIKE
, la commande peut
limiter l'affichage des variables à celles qui vérifient un
masque :
mysql> SHOW STATUS LIKE 'Key%';
+--------------------+----------+
| Variable_name | Value |
+--------------------+----------+
| Key_blocks_used | 14955 |
| Key_read_requests | 96854827 |
| Key_reads | 162040 |
| Key_write_requests | 7589728 |
| Key_writes | 3813196 |
+--------------------+----------+
SHOW TABLE STATUS [FROM db_name] [LIKE wild]
SHOW TABLE STATUS
(nouveau en version 3.23)
fonctionne comme SHOW STATUS
, mais fournit
des informations sur les tables. Vous pouvez aussi obtenir ces
informations en utilisant la commande en ligne
mysqlshow --status db_name
. Les données
suivantes sont retournées :
Name
Nom de la table.
Type
Type de table. See Chapitre 14, Moteurs de tables MySQL et types de table.
Row_format
Le format de stockage de ligne (Fixed
,
Dynamic
ou
Compressed
).
Rows
Nombre de lignes.
Avg_row_length
Taille moyenne d'une ligne.
Data_length
Taille du fichier de données.
Max_data_length
Taille maximale du fichier de données. Pour les formats de lignes fixe, c'est le nombre maximal de lignes dans la table. Pour les formats de lignes dynamique, c'est le nombre total d'octets qui peuvent être stockés dans la table, avec le pointeur de données utilisé.
Index_length
Taille du fichier d'index.
Data_free
Nombre d'octets alloués mais non utilisés.
Auto_increment
Prochaine valeur d'auto_increment.
Create_time
Date de création de la table.
Update_time
Date de dernière modification de la table.
Check_time
Date de dernier entretien de la table.
Collation
Le jeu de caractères et la collation de la table (nouveau en 4.1.1)
Checksum
La somme de contrôle en direct (si elle existe). (nouveau en 4.1.1)
Create_options
Options supplémentaires utilisées avec CREATE
TABLE
.
Comment
Le commentaire utilisé lors de la création de la table (ou des informations sur pourquoi MySQL n'a pu accéder aux informations de la table).
Les tables InnoDB
indiqueront l'espace
disque libre dans le commentaire de table.
SHOW [OPEN] TABLES [FROM db_name] [LIKE 'pattern']
SHOW TABLES
liste les tables permanentes
(non TEMPORARY
) dans une base de données.
Vous pouvez obtenir cette liste avec la commande en ligne
mysqlshow db_name
.
Note : Si vous n'avez pas
les droits sur une table, la table n'apparaîtra pas dans le
résultat de SHOW TABLES
et
mysqlshow db_name
.
SHOW OPEN TABLES
liste les tables qui sont
actuellement ouvertes dans le cache de table. See
Section 7.4.8, « Quand MySQL ouvre et ferme les tables ». Le champ
Comment
du résultat indique le nombre
d'ouverture de la table en cache (cached
)
et le nombre d'utilisation (in_use
).
OPEN
est disponible depuis MySQL 3.23.33.
SHOW [GLOBAL | SESSION] VARIABLES [LIKE 'pattern']
SHOW VARIABLES
affiche les valeurs des
variables systèmes de MySQL. Vous pouvez aussi obtenir ces
informations avec la commande mysqladmin
variables
.
Les options GLOBAL
et
SESSION
ont été ajoutées en MySQL 4.0.3.
Avec GLOBAL
, vous obtiendrez les valeurs
qui seront utilisées pour les nouvelles connexions au serveur
MySQL. Avec SESSION
, vous recevez les
valeurs effectives pour la connexion en cours. Si vous ne
précisez ni l'une ni l'autre, la valeur par défaut est
SESSION
. LOCAL
est un
synonyme de SESSION
.
Si les valeurs par défaut ne vous conviennent pas, vous
pouvez modifier la plupart de ces variables, en ligne de
commande, lorsque mysqld
est lancé. Voir
Section 5.2.1, « Options de ligne de commande de mysqld
» et
Section 13.5.2.8, « Syntaxe de SET
».
Voici un extrait du résultat de la commande. La liste complète des variables et de leur valeur peut être différente pour votre serveur. La signification de chaque variable est présentée dans See Section 5.2.3, « Variables serveur système ». Des informations sur comment optimiser ces valeurs sont disponibles dans la section Section 7.5.2, « Réglage des paramètres du serveur ».
mysql> SHOW VARIABLES;
+---------------------------------+------------------------------+
| Variable_name | Value |
+---------------------------------+------------------------------|
| back_log | 50 |
| basedir | /usr/local/mysql |
| bdb_cache_size | 8388572 |
| bdb_log_buffer_size | 32768 |
| bdb_home | /usr/local/mysql |
...
| max_connections | 100 |
| max_connect_errors | 10 |
| max_delayed_threads | 20 |
| max_error_count | 64 |
| max_heap_table_size | 16777216 |
| max_join_size | 4294967295 |
| max_relay_log_size | 0 |
| max_sort_length | 1024 |
...
| timezone | EEST |
| tmp_table_size | 33554432 |
| tmpdir | /tmp/:/mnt/hd2/tmp/ |
| version | 4.0.4-beta |
| wait_timeout | 28800 |
+---------------------------------+------------------------------+
Avec la clause LIKE
, la commande
n'affichera que les variables qui vérifie le masque fourni :
mysql> SHOW VARIABLES LIKE 'have%';
+--------------------+----------+
| Variable_name | Value |
+--------------------+----------+
| have_bdb | YES |
| have_innodb | YES |
| have_isam | YES |
| have_raid | NO |
| have_symlink | DISABLED |
| have_openssl | YES |
| have_query_cache | YES |
+--------------------+----------+
SHOW WARNINGS [LIMIT [offset,] row_count] SHOW COUNT(*) WARNINGS
Cette commande affiche les erreurs, alertes et notes qui ont
été générées par la dernière commande. Les erreurs et
alertes sont remises à zéro pour chaque nouvelle commande
qui utilisent une table. Cette commande a été implémentée
depuis MySQL 4.1.0. Une commande connexe, SHOW
ERRORS
, affiche uniquement les erreurs. See
Section 13.5.3.8, « Syntaxe de SHOW ERRORS
».
La liste de messages est remise à zéro au début de chaque commande qui utilise la table.
La commande SHOW COUNT(*) WARNINGS
affiche
le nombre total d'erreurs, d'alertes et de notes. Vous pouvez
aussi lire ce nombre avec la variable
warning_count
:
SHOW COUNT(*) WARNINGS; SELECT @@warning_count;
La valeur de warning_count
peut être plus
grande que le nombre de messages affichés par SHOW
WARNINGS
si la variable système
max_error_count
est configurée assez bas
pour que tous les messages ne soient pas stockés. Un exemple
plus loin dans cette section montre ce qui arrive.
La clause LIMIT
a la même syntaxe que la
commande SELECT
. See
Section 13.1.7, « Syntaxe de SELECT
».
Le serveur MySQL retourne le nombre total d'alertes et
d'erreurs que vous avez obtenu lors de la dernière commande.
Ils sont disponibles avec la fonction
mysql_warning_count()
. See
Section 24.2.3.61, « mysql_warning_count()
».
Jusqu'à max_error_count
messages peuvent
être stockés (variable globale et spécifique aux threads).
Vous pouvez lire le nombre d'erreurs dans
@error_count
et le nombre d'alertes dans
@warning_count
.
SHOW WARNINGS
affiche aussi toutes les
erreurs, alertes et notes de la dernière commande, alors que
SHOW ERRORS
ne montre que les erreurs.
mysql>DROP TABLE IF EXISTS no_such_table;
mysql>SHOW WARNINGS;
+-------+------+-------------------------------+ | Level | Code | Message | +-------+------+-------------------------------+ | Note | 1051 | Unknown table 'no_such_table' | +-------+------+-------------------------------+
Notez que depuis MySQL 4.1.0, nous avons ajouté un nouveau
système d'alertes, et peu de commandes MySQL génère des
alertes. 4.1.1 supporte toutes sortes d'alertes pour
LOAD DATA INFILE
et les commandes DML
telles que INSERT
,
UPDATE
et ALTER
.
Par exemple, voici une situation simple qui produit des alertes de conversions pour une commande d'insertion :
mysql>create table t1(a tinyint NOT NULL, b char(4));
Query OK, 0 rows affected (0.00 sec) mysql>insert into t1 values(10,'mysql'),(NULL,'test'),(300,'open source');
Query OK, 3 rows affected, 4 warnings (0.15 sec) Records: 3 Duplicates: 0 Warnings: 4 mysql>show warnings;
+---------+------+---------------------------------------------------------------+ | Level | Code | Message | +---------+------+---------------------------------------------------------------+ | Warning | 1263 | Data truncated for column 'b' at row 1 | | Warning | 1261 | Data truncated, NULL supplied to NOT NULL column 'a' at row 2 | | Warning | 1262 | Data truncated, out of range for column 'a' at row 3 | | Warning | 1263 | Data truncated for column 'b' at row 3 | +---------+------+---------------------------------------------------------------+ 4 rows in set (0.00 sec)
Le nombre maximal d'alertes peut être spécifié en utilisant
la variable de serveur 'max_error_count'
,
SET max_error_count=[count]
; Par défaut,
c'est 64. Pour désactiver les alertes, donnez simplement la
valeur de 0 à la variable. Si
max_error_count
vaut 0, alors le nombre
d'alertes représente toujours le nombre d'alertes qui ont eu
lieu, mais aucun message d'erreur n'est accessible.
Par exemple, observez la commande ALTER
suivante, pour l'exemple ci-dessus, qui retourne uniquement
une alerte, même si le nombre total d'alertes est de 3
lorsque 'max_error_count'
=1.
mysql>show variables like 'max_error_count';
+-----------------+-------+ | Variable_name | Value | +-----------------+-------+ | max_error_count | 64 | +-----------------+-------+ 1 row in set (0.00 sec) mysql>set max_error_count=1;
Query OK, 0 rows affected (0.00 sec) mysql>alter table t1 modify b char;
Query OK, 3 rows affected, 3 warnings (0.00 sec) Records: 3 Duplicates: 0 Warnings: 3 mysql>show warnings;
+---------+------+----------------------------------------+ | Level | Code | Message | +---------+------+----------------------------------------+ | Warning | 1263 | Data truncated for column 'b' at row 1 | +---------+------+----------------------------------------+ 1 row in set (0.00 sec) mysql>
CACHE INDEX table_index_list [, table_index_list] ... IN key_cache_name table_index_list: tbl_name [[INDEX] (index_name[, index_name] ...)]
La commande CACHE INDEX
assigne un index de
table à un cache de clé spécifique. Cette commande est
uniquement disponible pour les tables
MyISAM
.
La commande suivante assigne les index des tables
t1
, t2
et
t3
au cache de clé appelé
hot_cache
:
mysql> CACHE INDEX t1, t2, t3 IN hot_cache;
+---------+--------------------+----------+----------+
| Table | Op | Msg_type | Msg_text |
+---------+--------------------+----------+----------+
| test.t1 | assign_to_keycache | status | OK |
| test.t2 | assign_to_keycache | status | OK |
| test.t3 | assign_to_keycache | status | OK |
+---------+--------------------+----------+----------+
La syntaxe de CACHE INDEX
vous permet de
spécifier des index particuliers à un cache. Cependant,
l'implémentation courante assigne tous les index de la table
au cache, et il n'y a donc pas d'intérêt à spécifier autre
chose que le nom de la table.
Le cache de clé utilisé dans une commande CACHE
INDEX
peut être créé en lui donnant une taille
avec une commande de configuration, ou la configuration du
serveur. Par exemple :
mysql> SET GLOBAL keycache1.key_buffer_size=128*1024;
Les paramètres du cache de clé sont accessibles depuis une variable système structurée. See Section 9.4.1, « Variables système structurées ».
Un cache de clé doit exister avant que vous ne l'utilisiez :
mysql> CACHE INDEX t1 in non_existent_cache;
ERROR 1283 (HY000): Unknown key cache 'non_existent_cache'
Par défaut, les index de table sont assignée au cache de clé par défaut, créé au moment du démarrage du serveur. Lorsqu'un cache de clé est détruit, tous les index qui lui étaient assigné sont transmis au cache par défaut.
Les assignations d'index affectent le serveur globalement : si un client assigne un index à un cache donné, ce cache sera utilisé pour tous les requêtes, quelque soit le client qui émet la requête.
CACHE INDEX
a été ajouté en MySQL 4.1.1.
FLUSH flush_option [,flush_option] ...
Vous devez utiliser la commande FLUSH
si
vous voulez effacer certains caches internes de MySQL. Pour
exécuter FLUSH
, vous devez avoir le droit
RELOAD
.
flush_option
peut être l'une des
suivantes :
HOSTS
Vide le cache des hôtes. Vous devez vider ce cache si
certaines des adresses IP de vos clients changent, ou si
vous obtenez des erreurs du type Host ... is
blocked
. Lorsque plus de
max_connect_errors
erreurs successives
surviennent pour un hôte, lors des connexions au serveur
MySQL, MySQL suppose qu'il y a un problème, et interdit
l'accès à l'hôte. See Section A.2.5, « Erreur Host '...' is blocked
».
Vous pouvez démarrer mysqld
avec
-O max_connect_errors=999999999
pour
éviter ce message.
DES_KEY_FILE
Recharge les clés DES depuis le fichier de stockage
spécifié par --des-key-file
lors du
démarrage du serveur.
LOGS
Ferme et réouvre tous les fichiers de log. Si vous avez
spécifié un fichier de log de mise à jour, ou un
fichier de log binaire sans extension, le numéro
d'extension du fichier de log sera incrémenté d'une
unité. Si vous avez utilisé une extension dans le nom du
fichier, MySQL va fermer et réouvrir le même fichier.
See Section 5.9.3, « Le log de modification ». Ceci est la même chose
que d'envoyer le signal SIGHUP
au
serveur mysqld
.
PRIVILEGES
Recharge les privilèges des tables de droits dans la base
mysql
.
QUERY CACHE
Défragmente le cache des requêtes pour mieux en utiliser
la mémoire. Cette commande n'effacera aucune requête du
cache, à la différence de RESET QUERY
CACHE
.
TABLES
Ferme toutes les tables ouvertes, et force les tables utilisées à se refermer. Cela vide aussi le cache de requêtes.
[TABLE | TABLES] nom_de_table
[,nom_de_table...]
Vide du cache uniquement les tables nommées.
TABLES WITH READ LOCK
Ferme toutes les tables ouvertes, et verrouille en lecture
toute les tables et bases, jusqu'à ce que vous exécutiez
une commande UNLOCK TABLES
. C'est très
pratique pour générer des sauvegardes, si vous avez un
système de fichiers comme Veritas, qui peut prendre des
photos du système.
STATUS
Remet la plupart des variables de statut à zéro. A n'utiliser que pour corriger une requête. See Section 1.4.1.3, « Comment rapporter un bogue ou un problème ».
USER_RESOURCES
Remet toutes les ressources à zéro. Cela va autoriser de nouveau les utilisateurs qui ont été bloqués. See Section 5.6.4, « Limiter les ressources utilisateurs ».
Vous pouvez aussi accéder à toutes les commandes décrites
plus haut en les donnant en arguments à
mysqladmin
(exemple :
flush-hosts
, flush-logs
,
reload
, ou encore
flush-tables
).
Reportez-vous aussi à la commande RESET
avec la réplication. See Section 13.5.4.5, « Syntaxe de la commande RESET
».
KILL [CONNECTION | QUERY] thread_id
Chaque connexion à mysqld
utilise un
thread unique. Vous pouvez voir les threads en cours
d'exécution en utilisant la commande SHOW
PROCESSLIST
et en terminer un avec la commande
KILL thread_id
.
Depuis MySQL 5.0.0, KILL
autorise les
options CONNECTION
et
QUERY
:
KILL CONNECTION
est similaire à
KILL
sans option : elle termine la
connexion associée avec le thread
thread_id
.
KILL QUERY
termine la requête que la
connexion est actuellement en train de traiter, mais
laisse la connexion ouverte.
Si vous avez le droit PROCESS
, vous pouvez
voir tous les threads. Si vous avez le droit
SUPER
, vous pouvez terminer tout les
threads. Sinon, vous ne pouvez terminer que vos propres
threads.
Vous pouvez aussi utiliser les commandes mysqladmin
processlist
et mysqladmin kill
pour examiner et terminer les threads.
Note : vous ne pouvez
actuellement pas utiliser KILL
avec la
bibliothèque du serveur embarqué, car celui-ci utilise les
threads de l'application hôte, il ne crée pas ses propres
threads.
Quand vous exécutez un KILL
, un thread
spécifique est crée pour ce thread.
Dans la plupart des cas, la terminaison du thread pourra prendre un certain temps vu que le thread de terminaison est invoqué à intervalles spécifiques.
Pour les boucles de SELECT
,
ORDER BY
et GROUP
BY
, le thread de terminaison est vérifié
après avoir lu un enregistrement. S'il est activé, la
requête est abandonnée.
Lors d'un ALTER TABLE
le thread de
terminaison est vérifié avant la lecture de chacune des
colonnes de la table d'origine. S'il est activé, la
commande est abandonnée et la table temporaire effacée.
Lors d'un UPDATE
ou d'un
DELETE
, le thread de terminaison est
vérifié après chaque lecture de bloc et chaque mise à
jour ou suppression de ligne. S'il est activé, la
requête est abandonnée. Notez que si vous utilisez les
transactions, les modifications ne seront pas perdues !
GET_LOCK()
stoppera avec
NULL
.
Un thread INSERT DELAYED
videra
rapidement toutes les lignes en mémoire et se terminera.
Si le thread est dans le gestionnaire des verrous de
tables (état : Locked
), le verrou sur
la table sera vite enlevé.
Si le thread est en attente de libération d'espace disque
lors d'un appel à write
, l'opération
est avortée avec un message d'erreur indiquant que le
disque est plein.
LOAD INDEX INTO CACHE table_index_list [, table_index_list] ... table_index_list: tbl_name [[INDEX] (index_name[, index_name] ...)] [IGNORE LEAVES]
La commande LOAD INDEX INTO CACHE
précharge un index dans un cache de clé, qui est
explicitement nommé dans dans la commande CACHE
INDEX
, ou dans le cache par défaut. LOAD
INDEX INTO CACHE
ne sert que pour les tables
MyISAM
.
L'option IGNORE LEAVES
fait que les blocs
terminaux de l'index ne sont pas lus.
La commande suivante précharge les noeuds des tables
t1
et t2
:
mysql> LOAD INDEX INTO CACHE t1, t2 IGNORE LEAVES;
+---------+--------------+----------+----------+
| Table | Op | Msg_type | Msg_text |
+---------+--------------+----------+----------+
| test.t1 | preload_keys | status | OK |
| test.t2 | preload_keys | status | OK |
+---------+--------------+----------+----------+
Cette commande charge tous les index de t1
.
Elle ne charge que les index non-terminaux de
t2
.
La syntaxe de LOAD INDEX INTO CACHE
vous
permet de spécifier seulement des index particuliers à
charger dans la table. Cependant, l'implémentation courante
charge tous les index : il n' y a pas de raison pour utiliser
autre chose que le nom de la table.
LOAD INDEX INTO CACHE
a été ajouté en
MySQL 4.1.1.
RESET reset_option [, reset_option] ...
La commande RESET
sert à remettre à zéro
des données. C'est aussi une version plus puissante de la
commande FLUSH
. See
Section 13.5.4.2, « Syntaxe de FLUSH
».
Pour exécuter la commande RESET
, vous
devez avoir les droits RELOAD
.
MASTER
Efface tous les logs binaires listés dans le fichier
d'index, et l'index binlog est vidé. Dans les version
antérieures à la version 3.23.26, cette commande
s'appelait FLUSH MASTER
(Master) See
Section 13.6.1, « Requêtes SQL pour contrôler les maîtres de réplication ».
QUERY CACHE
Supprime tous les résultats de requêtes du cache de requête.
SLAVE
Annule la position de réplication de l'esclave dans les
historiques du maître. Dans les version antérieures à
la version 3.23.26, cette commande s'appelait
FLUSH SLAVE
(Slave)See
Section 13.6.2, « Commandes SQL de contrôle des esclaves de réplication ».
Cette section décrit les commandes liées à la réplication. Un groupe de commande peut être utilisé pour contrôler le serveur. L'autre groupe sert avec les esclaves.
La réplication est contrôlable via l'interface SQL. Cette section présente les commandes qui contrôlent les maîtres de réplication. La section Section 13.6.2, « Commandes SQL de contrôle des esclaves de réplication » présente les commandes pour gérer les esclaves.
PURGE {MASTER | BINARY} LOGS TO 'log_name' PURGE {MASTER | BINARY} LOGS BEFORE 'date'
Efface tous les logs binaires listés dans l'index de logs, qui sont antérieurs à la date ou au log indiqué. Les logs sont aussi supprimés de cette liste : le log donné en paramètre devient alors le premier de la liste.
Exemple :
PURGE MASTER LOGS TO 'mysql-bin.010'; PURGE MASTER LOGS BEFORE '2003-04-02 22:46:26';
La variante BEFORE
est disponible en MySQL
4.1; son argument de date peut être au format
'YYYY-MM-DD hh:mm:ss'
.
MASTER
et BINARY
sont
synonymes, mais BINARY
ne peut être
utilisé que depuis MySQL 4.1.1.
Si vous avez un esclave actif qui est actuellement en train de lire l'un des logs que vous voulez effacer, la commande ne fera rien, et échouera avec une erreur. Cependant, si l'esclave est inactif, et que vous effacez un des logs qu'il utilisait, l'esclave sera incapable de reprendre la réplication. Cette commande peut être utilisée sans problème durant la réplication : vous n'avez pas besoin d'arrêter les esclaves.
Pour purger les logs, suivez cette procédure :
Sur chaque esclave, utilisez la commande SHOW
SLAVE STATUS
pour vérifier quel log est lu.
Faite une liste des logs sur le maître avec SHOW
MASTER LOGS
.
Déterminez le plus ancien log parmi ceux utilisés par les esclaves. C'est votre limite. Si vous les esclaves sont à jour, alors ce sera le dernier log de la liste.
Faites une sauvegarde de tous les logs que vous allez effacer. Cette étape est optionnelle, mais c'est une bonne idée.
Purgez tous les logs jusqu'à celui qui précède votre limite.
RESET MASTER
Efface tous les fichiers de logs binaires dans le fichier d'index, et vide le fichier d'index des logs.
Cette commande s'appelait FLUSH MASTER
avant MySQL 3.23.26.
SET SQL_LOG_BIN = {0|1}
Inactive ou active le log binaire de la connexion courante
(SQL_LOG_BIN
est une variable de session),
si le client se connecte avec un compte qui a les droits de
SUPER
. La commande est ignorée si le
client n'a pas de droits.
SHOW BINLOG EVENTS [ IN 'log_name' ] [ FROM pos ] [ LIMIT [offset,] row_count ]
Affiche les événements du log binaire. Si vous ne spécifiez
pas 'log_name'
, le premier log binaire sera
affiché.
La clause LIMIT
a la même syntaxe que
celle de la commande SELECT
. See
Section 13.1.7, « Syntaxe de SELECT
».
Cette commande est disponible en MySQL 4.0
SHOW MASTER LOGS
Liste les logs binaires disponibles sur le maître. Vous
devriez utiliser cette commande avant PURGE MASTER
LOGS
pour savoir jusqu'où vous pouvez aller.
La réplication est contrôlable via l'interface SQL. Cette section présente les commandes qui contrôlent les esclaves de réplication. La section Section 13.6.1, « Requêtes SQL pour contrôler les maîtres de réplication » présente les commandes pour gérer les maîtres.
CHANGE MASTER TO master_def [, master_def] ... master_def = MASTER_HOST = 'host_name' | MASTER_USER = 'user_name' | MASTER_PASSWORD = 'password' | MASTER_PORT = port_num | MASTER_CONNECT_RETRY = count | MASTER_LOG_FILE = 'master_log_name' | MASTER_LOG_POS = master_log_pos | RELAY_LOG_FILE = 'relay_log_name' | RELAY_LOG_POS = relay_log_pos | MASTER_SSL = {0|1} | MASTER_SSL_CA = 'ca_file_name' | MASTER_SSL_CAPATH = 'ca_directory_name' | MASTER_SSL_CERT = 'cert_file_name' | MASTER_SSL_KEY = 'key_file_name' | MASTER_SSL_CIPHER = 'cipher_list'
Modifie les paramètres que l'esclave utilise pour se
connecter et pour communiquer avec le serveur maître. Les
valeurs possibles pour master_def
sont
présentées ci-dessus.
Les options de log de relais,
RELAY_LOG_FILE
et
RELAY_LOG_POS
, sont disponibles depuis
MySQL 4.0.
Les options SSL, MASTER_SSL
,
MASTER_SSL_CA
,
MASTER_SSL_CAPATH
,
MASTER_SSL_CERT
,
MASTER_SSL_KEY
et
MASTER_SSL_CIPHER
, sont disponibles depuis
MySQL 4.1.1. Vous pouvez changer ces options même sur les
esclaves qui sont compilé sans le support SSL. Elles seront
sauvées dans le fichier master.info
mais
ignorées jusqu'à ce que le support SSL soit activé.
Par exemple :
mysql>CHANGE MASTER TO
->MASTER_HOST='master2.mycompany.com',
->MASTER_USER='replication',
->MASTER_PASSWORD='bigs3cret',
->MASTER_PORT=3306,
->MASTER_LOG_FILE='master2-bin.001',
->MASTER_LOG_POS=4,
->MASTER_CONNECT_RETRY=10;
mysql>CHANGE MASTER TO
->RELAY_LOG_FILE='slave-relay-bin.006',
->RELAY_LOG_POS=4025;
MASTER_USER
,
MASTER_PASSWORD
,
MASTER_SSL
,
MASTER_SSL_CA
,
MASTER_SSL_CAPATH
,
MASTER_SSL_CERT
,
MASTER_SSL_KEY
, et
MASTER_SSL_CIPHER
sont des informations qui
permettent à l'esclave de se connecter au maître. Si vous
omettez certains paramètres, les paramètres omis
conserveront leur ancienne valeur. Par exemple, si le mot de
passe sur le maître a changé, il suffit de faire :
mysql>STOP SLAVE; -- if replication was running
mysql>CHANGE MASTER TO MASTER_PASSWORD='new3cret';
mysql>START SLAVE; -- if you want to restart replication
pour indiquer à l'esclave le nouveau mot de passe : il n'y a pas besoin de spécifier les informations qui n'ont pas changé, comme l'hôte, le port, l'utilisateur, etc...
MASTER_HOST
, MASTER_PORT
sont le nom d'hôte ou l'adresse IP du maître, et son port
TCP. Notez que si MASTER_HOST
est égal à
localhost
, alors, comme généralement avec
MySQL, le port sera ignoré si les sockets Unix sont
utilisables.
Si vous spécifiez MASTER_HOST
ou
MASTER_PORT
, l'esclave supposera que le
serveur maître est différent du précédent, même si vous
spécifier les mêmes valeurs d'hôte et de port que
précédemment. Dans ce cas, les anciennes valeurs et position
de l'historique binaire ne sont plus valides. Ainsi, si vous
ne spécifiez pas MASTER_LOG_FILE
et
MASTER_LOG_POS
dans la commande,
MASTER_LOG_FILE=''
et
MASTER_LOG_POS=4
sont ajoutés
silencieusement.
MASTER_LOG_FILE
et
MASTER_LOG_POS
sont les coordonnées
auxquelles le thread d'I/O doit commencer à lire chez le
maître, lorsque le thread redémarrera. Si vous spécifiez
l'un d'entre eux, vous ne pourrez pas spécifier
RELAY_LOG_FILE
ou
RELAY_LOG_POS
. Si
MASTER_LOG_FILE
, ni
MASTER_LOG_POS
n'ont été spécifiés,
alors les dernières coordonnées du thread
esclave d'avant la commande CHANGE
MASTER
seront utilisées. Cela assure que la
réplication ne connaît pas de discontinuité, même si le
thread esclave était en retard sur le thread d'I/O, alors que
vous ne voulez changer que le mot de passe. Ce comportement
sécuritaire a été introduit à partir de MySQL versions
4.0.17 et 4.1.1. Avant ces versions, les coordonnées
utilisées celles du thread d'I/O, avant que la commande
CHANGE MASTER
soit émise, ce qui
conduisait à des pertes d'événements au niveau du maître,
et donc, la corruption de la réplication.
CHANGE MASTER
efface tous les
logs de relais (et en démarre de nouveaux), à
moins que vous ne spécifiez l'option
RELAY_LOG_FILE
ou
RELAY_LOG_POS
(dans ce cas, les logs de
relais seront conservés; depuis MySQL 4.1.1 la variable
globale RELAY_LOG_PURGE
sera
automatiquement mise à 0). CHANGE MASTER
TO
modifie master.info
et
relay-log.info
.
CHANGE MASTER
sert à configurer un esclave
lorsque vous avez une sauvegarde du maître, son log et la
position qui correspond à la sauvegarde du maître. Vous
pouvez utiliser la commande CHANGE MASTER TO
MASTER_LOG_FILE='log_name_on_master',
MASTER_LOG_POS=log_offset_on_master
sur l'esclave
après la restauration de la sauvegarde.
Le premier exemple ci-dessus (CHANGE MASTER TO
MASTER_HOST='master2.mycompany.com' etc
) modifie les
coordonnées du maître et de son log binaire. Cela est utile
lorsque vous voulez que l'esclave réplique le maître. Le
second exemple, moins fréquent, sert lorsque l'esclave a des
logs de relais que vous voulez utiliser à nouveau. Pour cela,
le maître n'a pas besoin d'être rejoint : il suffit
d'utiliser la commande CHANGE MASTER TO
et
de lancer le thread SQL START SLAVE
SQL_THREAD
. Vous pouvez même utiliser cela dans une
configuration de réplication, sur un serveur indépendant,
pour assurer la restauration après crash. Supposez que votre
serveur soit planté, et que vous avez restauré la
sauvegarde. Vous voulez que le serveur exécute à nouveau ses
propres logs (non pas des logs de relais, mais ses logs
binaires), qui sont par exemple, stockés sous le nom
myhost-bin.*
. Tout d'abord, faite une
copie des fichiers de log dans un entrepôt, au cas où une
erreur de manipulation surviendrait, et que le serveur vide
ses logs. Si vous utilisez MySQL 4.1.1 ou plus récent,
utilisez la commande suivante pour plus de sécurité :
SET GLOBAL RELAY_LOG_PURGE=0
.
Puis, lancez le serveur sans log-bin
, et
avec un nouvel identifiant (différent du précédent), avec
l'option relay-log=myhost-bin
(pour faire
croire au serveur que ses propres logs sont des logs de
relais), et skip-slave-start
. Puis, envoyez
cette commande :
mysql>CHANGE MASTER TO
->RELAY_LOG_FILE='myhost-bin.153',
->RELAY_LOG_POS=410,
->MASTER_HOST='some_dummy_string';
mysql>START SLAVE SQL_THREAD;
Le serveur va alors lire et exécuter ses propres logs, et rattraper les données jusqu'au crash.
Une fois la restauration finie, faites STOP
SLAVE
, éteignez le serveur, supprimez
master.info
et
relay-log.info
, puis relancez le serveur
avec ses options originales.
Pour le moment, spécifier MASTER_HOST
(même avec une valeur insignifiante) est obligatoire pour que
le serveur pense qu'il est un esclave. Donner au serveur un
nouvel identifiant, différent du précédent, est aussi
obligatoire, car sinon, le serveur va voir des événements
avec son identifiant, et il va conclure que c'est une
réplication circulaire, et il va les ignorer. Dans le futur,
nous envisageons de nous débarasser de ces petites
contraintes.
LOAD DATA FROM MASTER
Fait une sauvegarde du maître et la copie vers l'esclave. Met
à jour les valeurs de MASTER_LOG_FILE
et
MASTER_LOG_POS
pour que la réplication
reprennent à la bonne position. Respecte les interdictions de
réplications de tables et de bases spécifiées par les
options replicate-*
.
L'utilisation de cette commande est sujette aux conditions suivantes :
Fonctionne avec les tables MyISAM
.
Pose un verrou global en lecture sur le maître durant la sauvegarde, qui empêche les modifications sur le maître durant la phase de chargement.
Dans le futur, il est prévu de faire que cette commande
fonctionne avec les tables InnoDB
, et
qu'elle se passe du verrou global en utilisant des
fonctionnalités de sauvegarde à chaud non-bloquantes.
Si vous chargez de très grosses tables, pensez à augmenter
les valeurs des options net_read_timeout
et
net_write_timeout
sur vos maître et
esclave. See Section 5.2.3, « Variables serveur système ».
Notez que LOAD DATA FROM MASTER
ne copie pas les tables de droits de la
base mysql
. C'est fait pour simplifier
l'utilisation de droits et utilisateurs différents sur le
maître et les esclaves.
Cette commande requiert les droits de
RELOAD
et SUPER
sur le
maître, et le droit de SELECT
sur toutes
les tables du maître qui seront lues. Toutes les tables du
maître sur lesquelles l'utilisateur n'a pas de droits de
SELECT
seront ignorées par LOAD
DATA FROM MASTER
; ceci est dû au fait que le
maître va masquer ces tables à l'utilisateur :
LOAD DATA FROM MASTER
utilise SHOW
DATABASES
pour connaître les tables à charger,
mais SHOW DATABASES
ne retourne que les
bases pour lesquelles l'utilisateur a des droits. Voyez
Section 13.5.3.6, « Syntaxe de SHOW DATABASES
». Sur l'esclave, l'utilisateur
qui envoie la commande LOAD DATA FROM
MASTER
doit avoir les droits de création et
d'effacement des tables et bases impliquées.
LOAD TABLE tbl_name FROM MASTER
Télécharge une copie d'une table depuis le maître vers
l'esclave. Cette commande est implémentée pour déboguer la
commande LOAD DATA FROM MASTER
. Elle
requiert un compte pour se connecter au maître, avec les
droits de RELOAD
et
SUPER
, ainsi que les droits de
SELECT
sur la table a charger. Coté
esclave, l'utilisateur qui émet la commande doit avoir les
droits de LOAD TABLE FROM MASTER
pour
créer et effacer les tables. Lisez les informations sur les
problèmes réseau dans LOAD DATA FROM
MASTER
; elles s'appliquent aussi ici. Notez aussi
que les limitations de LOAD DATA FROM
MASTER
s'appliquent aussi (par exemple,
LOAD TABLE FROM MASTER
ne fonctionne que
sur les tables de type MyISAM
).
SELECT MASTER_POS_WAIT('master_log_file', master_log_pos)
C'est une fonction et non pas une commande. Elle sert à s'assurer que l'esclave a atteint (lu et exécuté) les événements du log binaire du maître jusqu'à une certaine position. Voyez la section See Section 12.8.4, « Fonctions diverses » pour une description complète.
RESET SLAVE
Force l'esclave a oublier toute les positions de réplications
dans les logs du maître. Cette commande permet de faire un
démarrage propre : elle efface les fichiers
master.info
et
relay-log.info
, et les logs de relais,
puis créer un nouveau log de relais.
Note : tous les logs de
relais sont effacés, même si il n'ont pas été totalement
exécutés par le thread SQL. (C'est un état qui est probable
si l'esclave de réplication est fortement chargé, ou si vous
avez lancé une commande STOP SLAVE
.) Les
informations de connexions stockées dans le fichier
master.info
reprennent immédiatement les
valeurs spécifiées dans les options de démarrage, si elles
étaient précisées. Ces informations incluent notamment le
nom de l'hôte maître, le port, l'utilisateur et le mot de
passe. Si le thread esclave était au milieu d'une
réplication temporaire lorsqu'il a été arrêté, et que
RESET SLAVE
a été émise, ces tables
temporaires sont aussi effacées.
Cette commande s'appelait FLUSH SLAVE
avant
MySQL 3.23.26.
SET GLOBAL SQL_SLAVE_SKIP_COUNTER = n
Ignore les n
prochains événements du
maître. C'est une commande pratique pour rattraper les
arrêts de réplications causés par une commande.
Cette commande n'est valide que lorsque le thread esclave ne fonctionne pas. Sinon, elle produit une erreur.
Avant MySQL 4.0, omettez le mot clé GLOBAL
dans la commande.
SHOW SLAVE STATUS
Affiche des informations sur les paramètres essentiels des
threads esclaves. Si vous utilisez cette commande avec le
client mysql
, vous pouvez utiliser le
terminateur de commande \G
plutôt que le
point-virgule pour avoir un format plus lisible :
mysql> SHOW SLAVE STATUS\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: localhost
Master_User: root
Master_Port: 3306
Connect_Retry: 3
Master_Log_File: gbichot-bin.005
Read_Master_Log_Pos: 79
Relay_Log_File: gbichot-relay-bin.005
Relay_Log_Pos: 548
Relay_Master_Log_File: gbichot-bin.005
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB:
Replicate_Ignore_DB:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 79
Relay_Log_Space: 552
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: 8
Suivant votre version de MySQL, vous pourriez ne pas voir tous les champs qui sont dans cet exemple. Notamment, il y a plusieurs champs qui ne sont disponibles qu'avec MySQL 4.1.1.
Les champs affichés par SHOW SLAVE STATUS
ont les définitions suivantes :
Slave_IO_State
Une copie de la colonne State
de la
commande SHOW PROCESSLIST
pour le
thread d'I/O. Elle va vous indiquer si le thread essaye de
se connecter au maître, attend des événements, se
reconnecte, etc. Les différents états possibles sont
listés dans la section
Section 6.3, « Détails d'implémentation de la réplication ».
Etudier cette colonne est nécessaire, par exemple, car le
thread peut fonctionner mais ne pas réussir à se
connecter au maître : seule cette colonne vous indiquera
ce type de problèmes. D'un autre coté, l'état du thread
SQL n'est pas indiqué, car les problèmes sont bien plus
simples avec lui : soit il fonctionne, et il n'y a pas de
problème; soit il ne fonctionne pas, et vous trouverez
les messages d'erreur dans la colonne
Last_Error
, décrite plus bas.
Ce champ a été ajouté en MySQL 4.1.1.
Master_Host
L'hôte maître courant.
Master_User
Le nom de l'utilisateur utilisé pour se connecter au maître.
Master_Port
Le port courant sur le maître.
Connect_Retry
La valeur courante de l'option
master-connect-retry
.
Master_Log_File
Le nom du fichier de log binaire que le thread d'I/O utilise sur le maître.
Read_Master_Log_Pos
La position que le thread d'I/O a atteint dans le fichier de log binaire du maître.
Relay_Log_File
Le nom du fichier de log de relais dans lequel le thread SQL est actuellement en train de lire et de travailler.
Relay_Log_Pos
La position à laquelle le thread SQL est en train de travailler.
Relay_Master_Log_File
Le nom du fichier de log binaire du maître qui contient le dernier événement exécuté par le thread SQL.
Slave_IO_Running
Indique si le thread d'I/O est lancé ou pas.
Slave_SQL_Running
Indique si le thread SQL est lancé ou pas.
Replicate_Do_DB, Replicate_Ignore_DB
La liste des bases de données qui ont été spécifiée
dans l'option --replicate-do-db
et
--replicate-ignore-db
, éventuellement.
Replicate_Do_Table, Replicate_Ignore_Table,
Replicate_Wild_Do_Table,
Replicate_Wild_Ignore_Table
La liste des tables qui ont été spécifiées
respectivement dans les options
--replicate-do-table
,
--replicate-ignore-table
,
--replicate-wild-do-table
et
--replicate-wild-ignore_table
,
éventuellement.
Ces champs ont été ajoutés en MySQL 4.1.1.
Last_Errno, Last_Error
Last_Errno
est le numéro d'erreur de
la plus récent requête exécutée. La valeur de 0
signifie ``pas d'erreur''. Last_Error
est le message d'erreur de la plus récent requête
exécutée. Par exemple :
Last_Errno: 1051 Last_Error: error 'Unknown table 'z'' on query 'drop table z'
Le message indique que la table z
existait sur le maître et a été effacée, mais qu'elle
n'existe pas sur l'esclave, et que DROP
TABLE
a échoué sur l'esclave. Cela peut
arriver si vous avez oublié de copier une table dans
l'esclave avant de lancer la réplication.
Une chaîne vide signifie ``pas d'erreur''. Si
Last_Error
n'était pas vide, alors le
même message apparaîtra dans le log d'erreur de
l'esclave.
Skip_Counter
La dernière valeur utilisée par
SQL_SLAVE_SKIP_COUNTER
.
Exec_Master_Log_Pos
La position dans les logs binaires du maître
(Relay_Master_Log_File
) pour le dernier
événement exécuté par le thread SQL.
((Relay_Master_Log_File
,Exec_Master_Log_Pos
)
dans le log binaire du maître correspond à
(Relay_Log_File
,Relay_Log_Pos
)
dans le log de relais.
Relay_Log_Space
La taille combinée de tous les logs de relais.
Until_Condition, Until_Log_File,
Until_Log_Pos
Les valeurs spécifiées dans la clause
UNTIL
de la commande START
SLAVE
.
Until_Condition
peut prendre ces
valeurs :
None
(aucune) si aucune clause
UNTIL
n'a été spécifiée
Master
(maître), si l'esclave lit
depuis une position donnée, dans le log binaire du
maître
Relay
(relais) si l'esclave lit
dans une position donnée dans le log de relais.
Until_Log_File
et
Until_Log_Pos
indique le nom du fichier
de log et la position qui définissent le point où le
thread SQL va s'arrêter d'exécuter.
Ces champs ont été ajoutés en MySQL 4.1.1.
Master_SSL_Allowed, Master_SSL_CA_File,
Master_SSL_CA_Path, Master_SSL_Cert, Master_SSL_Cipher,
Master_SSL_Key
Ces champs indiquent les paramètres SSL utilisés par l'esclave pour se connecter au maître, s'ils sont fournis.
Master_SSL_Allowed
prend ses valeurs :
Yes
(oui) si la connexion SSL au
maître est autorisée
No
(non) si la connexion SSL au
maître est interdite
Ignored
(ignoré) si la connexion
SSL au maître est autorisée par l'esclave mais que
le support de SSL n'est pas là.
Les valeurs des autres champs correspondent aux valeurs
des options --master-ca
,
--master-capath
,
--master-cert
,
--master-cipher
et
--master-key
.
Ces champs ont été ajoutés en MySQL 4.1.1.
Seconds_Behind_Master
Le nombre de secondes qui se sont écoulées depuis le
timestamp du dernier événement maître exécuté par le
thread SQL. Ce sera NULL
si aucun
événement n'a été exécuté, ou après une commande
CHANGE MASTER
et RESET
SLAVE
. Cette colonne sert à mesurer le retard
de l'esclave sur le maître. Cela fonctionne même si le
maître et l'esclave on des horloges réglées
différemment.
Ce champ a été ajouté en MySQL 4.1.1.
START SLAVE [thread_name [, thread_name] ... ] START SLAVE [SQL_THREAD] UNTIL MASTER_LOG_FILE = 'log_name', MASTER_LOG_POS = log_pos START SLAVE [SQL_THREAD] UNTIL RELAY_LOG_FILE = 'log_name', RELAY_LOG_POS = log_pos thread_name = IO_THREAD | SQL_THREAD
START SLAVE
, appelé sans option, démarre
les deux threads esclaves. Le thread I/O lire les requêtes du
maître et les stocke dans le log de relais. Le thread SQL
lire le log de relais, et exécute les requêtes. Notez que si
START SLAVE
réussi à lancer le thread
esclave, elle se terminera sans erreur. Mais même dans ce
cas, il se peut que le thread esclave se lance, puis s'arrête
(car il n'a pas pu se connecter au maître, ou lire le log
binaire ou tout autre problème). START
SLAVE
ne vous préviendra pas de cet événement.
Vous devez vérifier le log d'erreur de l'esclave pour voir si
des messages ont été générés, ou encore vérifier que
tout fonctionne avec la commande SHOW SLAVE
STATUS
.
Depuis MySQL 4.0.2, vous pouvez ajouter les options
IO_THREAD
ou SQL_THREAD
à la commande, pour nommer les threads que vous lancez.
Depuis MySQL 4.1.1, une clause UNTIL
peut
être ajoutée pour spécifier que l'esclave doit commencer à
un certain point dans le log binaire, ou dans le log de
relais. Lorsque le thread SQL atteint ce point, il s'arrête.
Si l'option SQL_THREAD
est spécifiée dans
la commande, seule le thread SQL est lancé. Sinon, les deux
threads sont lancés. Si le thread SQL est déjà lancé, la
clause UNTIL
est ignorée, et une alerte
est émise.
Avec la clause UNTIL
, vous devez spécifier
à la fois un fichier de log et une position. Ne confondez pas
les options du maître et celles du log de relais.
Toute condition UNTIL
est annulée par une
commande STOP SLAVE
, ou une commande
START SLAVE
qui n'inclut pas de condition
UNTIL
, ou encore un redémarrage serveur.
La clause UNTIL
peut être utile pour
déboguer la réplication, ou pour vous assurer que la
réplication s'effectue jusqu'à un certain point. Par
exemple, si une commande imprudente DROP
TABLE
a été exécutée sur le maître, vous pouvez
utiliser la clause UNTIL
pour dire à
l'esclave de s'exécuter jusqu'à ce moment, puis de
s'arrêter. Pour trouver cet événement, utilisez
l'utilitaire mysqlbinlog
sur le log du
maître, ou sur le log de relais, ou encore utilisez la
commande SHOW BINLOG EVENTS
.
Si vous utilisez la clause UNTIL
pour faire
des réplications par portions, il est recommandé de lancer
l'esclave avec l'option --skip-slave-start
pour éviter que le thread SQL ne se lance lorsque l'esclave
se lance. Il est probablement idéale d'utiliser cette option
dans un fichier d'options plutôt qu'en ligne de commande,
pour qu'un redémarrage intempestif ne l'oublie pas.
La commande SHOW SLAVE STATUS
affiche un
champ qui indique la valeur courante de la clause
UNTIL
.
STOP SLAVE [thread_name [, thread_name] ... ] thread_name = IO_THREAD | SQL_THREAD
Arrête l'esclave. Tout comme START SLAVE
,
cette commande peut être utilisée avec les options
IO_THREAD
et SQL_THREAD
pour identifier le thread par son nom.
Cette commande s'appelait SLAVE STOP
avant
MySQL 4.0.5. Actuellement, SLAVE STOP
est
toujours disponible pour assurer la compatibilité ascendante,
mais c'est une commande abandonnée.
Le support des commandes préparées coté serveur a été ajouté en MySQL 4.1. Ce support tire profit du protocole client/serveur plus efficace, en supposant que vous utilisez la bonne interface client. Les interfaces correctes sont l'API C MySQL (pour les programmes en C), et MySQL Connector/J (pour les programmes Java). Par exemple, l'API C fournit un jeu de fonctions qui prépare les commandes. See Section 24.2.4, « Fonctions C de commandes préparées ». Les autres interfaces de langages peuvent fournir un support pour les commandes préparées, en utilisant le protocole binaire grâce à l'interface du client C. L'extension PHP 5 mysqli est un exemple.
Depuis MySQL 4.1.3, une interface alternative pour les commandes préparées est disponible : la suntaxe SQL pour les commandes préparées. Cette interface n'est pas aussi efficace que le protocole binaire, mais elle n'impose aucune programmation, car elle est disponible directement au niveau SQL.
Vous pouvez l'utiliser lorsqu'aucune interface de programmation n'est disponible.
Vous pouvez l'utiliser depuis n'importe quel programme qui vous permet d'envoyer des commandes au serveur, comme le client mysql.
Vous pouvez l'utiliser même si le client utilise une vieille version de la bibliothèque d'interface. La seule contrainte est que vous devez pouvoir vous connecter à un serveur suffisamment récent pour supporter cette syntaxe.
La syntaxe SQL pour les commandes préparées sert dans les situations suivantes :
Vous voulez tester les commandes préparées avec votre application sans faire de codage. Ou bien, votre application a des problèmes avec les commandes préparées, et vous voulez déterminer ce problème interactivement.
Vous voulez créer un cas de test qui décrit les problèmes que vous avez avec les commandes préparées, pour pouvoir envoyer un rapport de bogue.
Vous deve utiliser les commandes préparées, mais vous n'avez pas accès à une interface qui les supporte.
La syntaxe SQL pour les commandes préparées est basée sur 3 commandes SQL :
PREPAREstmt_name
FROMpreparable_stmt
; EXECUTEstmt_name
[USING @var_name
[, @var_name
] ...]; DEALLOCATE PREPAREstmt_name
;
La commande PREPARE
prépare la commande, lui
assigne le nom stmt_name
, qui sera
utilisé ultérieurement.
preparable_stmt
est soit une chaîne
littérale, soit une variable utilisateur, qui contient le texte
de la commande. Le texte doit représenter une seule commande SQL,
et non pas plusieurs. Dans la commande, le caractère
‘?
’ sert de variable de requête :
ils indiquent que les valeurs seront fournies à l'application
ultérieurement. Le caractère ‘?
’
ne doit pas être placé entre guillemets, même si vous voulez
leur donner des valeurs de chaînes de caractères.
Si une commande préparée existe déjà avec le même nom, elle sera détruite implicitement avant la préparation de la nouvelle commande. Cela signifie que si la nouvelle commande contient une erreur et ne peut pas être préparée, une erreur sera retournée, et la commande aura simplement été détruite.
Le contexte d'une commande préparée est celui de la session client dans laquelle elle est créée. Les autres clients ne peuvent y accéder.
Après avoir préparé une commande, vous l'exécutez avec la
commande EXECUTE
, qui fait référence au nom
de la commande préparée. Si la commande préparée contient des
variables, vous devez fournir leur valeur avec la clause
USING
qui liste les variables contenant les
valeurs des paramètres. Les valeurs des paramètres doivent être
aussi nombreuses que les paramètres de la commande.
Vous pouvez exécuter une commande préparée plusieurs fois, en lui passant différentes valeurs, ou différentes variables.
Pour détruire une commande préparée, utilisez la commande
DEALLOCATE PREPARE
. Tenter d'exécuter la
commande préparée après destruction conduit à une erreur.
Si vous quittez la session client sans libérer les commandes préparées, le serveur le fera pour vous.
Les exemples suivants montre deux méthodes équivalentes pour préparer les commandes qui calculent l'hypothénuse d'un triangle à partir de la taille de deux de ses cotés.
Le premier exemple montre comment créer la commande préparée avec une chaîne littérale :
mysql>PREPARE stmt1 FROM 'SELECT SQRT(POW(?,2) + POW(?,2)) AS hypotenuse';
mysql>SET @a = 3;
mysql>SET @b = 4;
mysql>EXECUTE stmt1 USING @a, @b;
+------------+ | hypotenuse | +------------+ | 5 | +------------+ mysql>DEALLOCATE PREPARE stmt1;
Le second exexemple est similaire, mais fournit le texte de la commande dans une variable utilisateur :
mysql>SET @s = 'SELECT SQRT(POW(?,2) + POW(?,2)) AS hypotenuse';
mysql>PREPARE stmt2 FROM @s;
mysql>SET @a = 6;
mysql>SET @b = 8;
mysql>EXECUTE stmt2 USING @a, @b;
+------------+ | hypotenuse | +------------+ | 10 | +------------+ mysql>DEALLOCATE PREPARE stmt2;
La syntaxe SQL des commandes préparées syntax ne peut pas être
utilisée par imbrication. C'est à dire, une commande passée à
PREPARE
ne peut pas exécuter les commandes
PREPARE
, EXECUTE
ou
DEALLOCATE PREPARE
.
De plus, la syntaxe SQL pour les commandes préparées est
distincte de l'API des commandes préparées. Par exemple, vous
pouvez utiliser la fonction C
mysql_stmt_prepare()
pour préparer une
commande PREPARE
, EXECUTE
,
or DEALLOCATE PREPARE
.