13. Syntaxe des commandes SQL▲
Ce chapitre décrit la syntaxe des commandes que MySQL supporte.
13-1. Manipulation de données : SELECT, INSERT, UPDATE, DELETE▲
13-1-1. Syntaxe de DELETE▲
DELETE
[LOW_PRIORITY]
[QUICK]
[IGNORE]
FROM
table_name
[WHERE where_definition]
[ORDER BY ...]
[LIMIT row_count]
Syntaxe multitable :
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
. Voir Section 13.1.9, « Syntaxe de TRUNCATE »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émarre à zéro pour tous les types de tables 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 15.7.3, « Comment les colonnes AUTO_INCREMENT fonctionnent avec InnoDB »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é multicolonne. Dans ce cas, la réutilisation des clés à partir de la fin de la séquence se fait aussi pour les tables MyISAM. Voir Section 3.6.9, « Utiliser AUTO_INCREMENT »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 commandeDELETE
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 option 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 suppression peut être affectée par les facteurs présentés dans la Section 7.2.16, « Rapidité des requêtes DELETE »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 »13.5.2.5. Syntaxe de OPTIMIZE TABLE et Section 5.7.3.10, « Optimisation de table »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 lignes à 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érieur à la valeur de LIMIT
.
Si la commande DELETE
inclut la clause ORDER
BY
, les lignes sont effacées dans l'ordre spécifié par cette clause. Elle n'est vraiment utile 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
multitable.
La première syntaxe de DELETE
multitable est supportée depuis MySQL 4.0.0. La deuxième syntaxe de DELETE
multitable 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 13.1.7.1, « Syntaxe de JOIN »13.1.7.1. Syntaxe de JOIN.
L'idée est que seules les lignes concordantes dans les tables énumérées avant le FROM
ou avant la clause USING
sont effacées. 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ésentent des jointures internes, en utilisant l'opérateur virgule, mais les DELETE
multitables 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
multitable 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és à ne pas faire ce changement en version 4.0, est la compatibilité ascendante avec les vieilles applications 4.0, qui utilisent la vieille syntaxe.
13-1-2. Syntaxe de DO▲
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
.
13-1-3. Syntaxe de HANDLER▲
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. Cet 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. Voir Section 13.1.7, « Syntaxe de SELECT »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 les suivantes.
-
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 perte 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 traverser 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.
13-1-4. Syntaxe de INSERT▲
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ée à 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étail : Voir Section 13.1.4.1, « Syntaxe de INSERT ... SELECT »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 où la clause SET
indique les colonnes qui seront affectées.
-
La liste des noms de colonnes où la clause
SET
indique explicitement les colonnes utilisées. -
Si vous ne spécifiez pas de liste de colonnes avec
INSERT
...VALUES
ouINSERT
...SELECT
, les valeurs pour toutes les colonnes doivent être fournies dans la clauseVALUES
()
ou par la commandeSELECT
. Si vous ne connaissez pas l'ordre des colonnes, utilisez la commandeDESCRIBE
nom_de_table pour le connaître.
Les valeurs des colonnes peuvent être spécifiées de plusieurs façons.
-
À 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 table, 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 »13.2.5. Syntaxe de CREATE TABLE.
MySQL a toujours une valeur par défaut pour chaque champ. 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 par 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. Voir Section 2.4.2, « Options habituelles de configure »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 commandesINSERT
lors de l'assignation de quelques colonnes, sans écrire de valeursVALUES
incomplètes. Sinon, il faut écrire la liste des colonnes utilisées pour chaque valeur de la listeVALUES
. -
Si la liste de colonnes et de valeurs
VALUES
est vide,INSERT
crée une ligne pour chaque colonne avec sa valeur par défaut :Sélectionnezmysql
>
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 :
Sélectionnezmysql
>
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 :
Sélectionnezmysql
>
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 commandeINSERT
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. Voir Section 13.1.4.2, « Syntaxe de INSERT DELAYED »13.1.4.2. Syntaxe de INSERT DELAYED. -
Si on spécifie le mot
LOW_PRIORITY
, l'exécution deINSERT
sera retardée 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 avecINSERT
DELAYED
, qui laisse le client continuer tout de suite. Voir Section 13.1.4.2, « Syntaxe de INSERT DELAYED »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. Voir Section 14.1, « Le moteur de tables MyISAM »14.1. Le moteur de tables MyISAM. -
Si on spécifie le mot
IGNORE
dans unINSERT
avec les valeurs de plusieurs lignes, chaque ligne qui ferait doublon avec une cléPRIMARY
ouUNIQUE
existant dans la table sera ignorée et ne sera pas insérée. Si on ne spécifie pasIGNORE
, 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 même façon dans toutes les circonstances. Le comportement des commandes INSERT
avec les colonnes AUTO_INCREMENT
sont décrites dans la Section 12.8.3, « Fonctions d'informations »12.8.3. Fonctions d'informations et Section 24.2.3.33, « mysql_insert_id() »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 lignes qui ont été traitées par cette commande. Ce n'est pas forcément le nombre de lignes 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éeNOT
NULL
. Pour les commandes d'insertions multiplesINSERT
ou les commandesINSERT
...SELECT
, la colonne prend la valeur par défaut adaptée au type de colonne. C'est0
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 colonne. 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 valeur0
est insérée. -
L'insertion d'une chaîne dans une colonne
CHAR
,VARCHAR
,TEXT
, ouBLOB
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
ouTIME
. 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(). Voir Section 24.2.3.31, « mysql_info() »24.2.3.31. mysql_info().
13-1-4-1. Syntaxe de INSERT ... SELECT▲
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 modeIGNORE
. Depuis MySQL version 4.0.1, vous devez spécifier le modeIGNORE
explicitement, pour ignorer les lignes qui causeront des erreurs de doublons pour les index uniques. -
N'utilisez pas
DELAYED
avecINSERT
...SELECT
. -
Avant MySQL version 4.0.14, la table de destination de la requête
INSERT
ne peut apparaître dans la clauseFROM
de la partieSELECT
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 leSELECT
pourrait trouver des enregistrements qui auraient é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 recré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.
13-1-4-2. Syntaxe de INSERT DELAYED▲
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 acquittement, 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ées, et écrites d'un seul bloc. C'est beaucoup plus rapide que de faire des insertions séparées.
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, lesSELECT
etINSERT
simultanés sont supportés. Dans ces circonstances, vous n'aurez que très rarement besoin deINSERT
DELAYED
avec MyISAM. Voir Section 14.1, « Le moteur de tables MyISAM »14.1. Le moteur de tables MyISAM. -
INSERT
DELAYED
doit être utilisé uniquement avec les commandesINSERT
qui spécifient une liste de valeurs. C'est le cas depuis MySQL 4.0.18. Le serveur ignoreDELAYED
pour les commandesINSERT
DELAYED
...SELECT
. -
Le serveur ignore
DELAYED
dans les commandesINSERT
DELAYED
...ON
DUPLICATE
UPDATE
. -
Comme la commande s'exécute immédiatement, sans que la ligne ne soit insérée, vous ne pouvez pas utiliser
LAST_INSERT_ID
()
pour lire la valeur que la colonneAUTO_INCREMENT
va générer. -
Les lignes
DELAYED
ne sont visibles par les commandesSELECT
que lorsqu'elles ont été réellement insérées.
Actuellement, les lignes en attente sont uniquement stockées en mémoire tant qu'elles 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
et « 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érationsDELAYED
pour cette table - si ce thread de gestion n'existe pas. -
Le thread vérifie que le thread de gestion a déjà reçu un verrou
DELAYED
; sinon, il dit au thread de gestion de le faire. Le verrouDELAYED
peut être obtenu même si d'autres threads ont des verrousREAD
ouWRITE
sur la table. Cependant le gestionnaire attendra que tous les verrousALTER
TABLE
ouFLUSH
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 averti 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 leINSERT
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 modifications 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ées. -
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 avecKILL
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 commandeINSERT
d'aucun autre thread. Si on exécute une commandeINSERT
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 commandesINSERT
normales si un gestionnaire deINSERT
DELAYED
existe déjà ! les autres commandes de modification devront attendre que la file d'attente deINSERT
DELAYED
soit vide, que quelqu'un tue le gestionnaire (avecKILL
thread_id), ou que quelqu'un exécuteFLUSH
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 !
13-1-5. Syntaxe de LOAD DATA INFILE▲
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 »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 fait que mysqlimport lit les fichiers de données chez le client. Vous pouvez spécifier l'option --compress pour avoir de meilleures performances avec les connexions lentes si le client et le serveur supportent le protocole compressé. Voir Section 8.10, « mysqlimport, importer des données depuis des fichiers texte »8.10. mysqlimport, importer des données depuis des fichiers texte.
Si vous spécifiez le mot-clé LOW_PRIORITY
, l'exécution de la commande LOAD
DATA
est ajournée jusqu'à ce qu'aucun client n'utilise plus la table.
Si vous spécifiez le mot-clé CONCURRENT
avec une 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écents.
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 lisibles par tous. Pour utiliser la commande LOAD
DATA
INFILE
sur des fichiers du serveur, vous devez avoir le droit de FILE
sur le serveur. Voir Section 5.5.3, « Droits fournis par MySQL »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 côté, 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és pour. Par exemple, si mysqld a été lancé avec --local-infile=0, LOCAL
ne fonctionnera pas. Voir Section 5.4.4, « Problèmes de sécurité avec LOAD DATA LOCAL »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. Voir Section 13.1.6, « Syntaxe de REPLACE »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. Voir Section 5.7.3, « Utilisation de myisamchk pour la maintenance des tables et leur recouvrement »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
. Voir Section 13.1.7, « Syntaxe de SELECT »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 pas de clause FIELDS
, les valeurs par défaut sont :
FIELDS
TERMINATED
BY
'\t'
ENCLOSED
BY
''
ESCAPED
BY
'\\'
Si vous ne spécifiez pas 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 champ.
À l'inverse, les valeurs par défaut font que SELECT
... INTO
OUTFILE
écrit les données comme ceci :
-
Écriture des tabulations entre les champs ;
-
Les champs ne sont pas entourés de guillemets ;
-
Utilisation de '\' pour échapper les occurrences de tabulation, nouvelle ligne, et '\' trouvées dans les valeurs ;
-
Insertion d'une nouvelle ligne entre les lignes.
Notez que pour utiliser FIELDS
ESCAPED
BY
'\\'
, vous devez spécifier deux antislashes pour que cette valeur soit interprétée comme un antislash 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 un 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
a é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 ne 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 champ sont échappées 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
. 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és, 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 :
-
le caractère
FIELDS
ESCAPED
BY
; -
le caractère
FIELDS
[OPTIONALLY]
ENCLOSED
BY
; -
le premier caractère des valeurs de
FIELDS
TERMINATED
BY
etLINES
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 »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 deFIELDS
TERMINATED
BY
ne l'est pas, ce dernier sera celui utilisé pourLINES
TERMINATED
BY
. -
Si les valeurs
FIELDS
TERMINATED
BY
etFIELDS
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éeINT
(
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 valeurNULL
; voyez plus loin pour cela. Notez que ce format ne fonctionne pas avec les jeux de caractères multioctets.
La gestion des valeurs NULL
dépend des options FIELDS
et LINES
que vous utilisez.
-
Pour les valeurs par défaut de
FIELDS
etLINES
,NULL
est écrit \N et \N est luNULL
(en supposant que le caractère d'échappement est '\'). -
Si
FIELDS
ENCLOSED
BY
n'est pas vide, un champ contenant le motNULL
comme valeur sera lu comme la valeurNULL
(ce qui diffère du motNULL
, entouré du caractèreFIELDS
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
etFIELDS
ENCLOSED
BY
sont tous les deux vides), les valeursNULL
sont écrites sous forme de chaîne vide. Notez que cela fait queNULL
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
etFIELDS
ENCLOSED
BY
sont tous les deux vides) et les types de colonnesBLOB
ouTEXT
. -
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 clauseFIELDS
suivante posera sûrement des problèmes :SélectionnezFIELDS
TERMINATED
BY
'"'
ENCLOSED
BY
'"'
-
Si
FIELDS
ESCAPED
BY
est vide, une valeur de colonne qui contient une occurrence deFIELDS
ENCLOSED
BY
ou deLINES
TERMINATED
BY
suivi du caractèreFIELDS
TERMINATED
BY
interrompra la lecture deLOAD
DATA
INFILE
trop tôt. Cela est dû au fait queLOAD
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 »13.2.5. Syntaxe de CREATE TABLE.
Une valeur de champ 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. Voir Section 11.3, « Les types date et heure »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ées 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
(voir Section 13.1.4, « Syntaxe de INSERT »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. Voir Section 13.5.3.19, « SHOW WARNINGS | ERRORS »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
: voir Section 7.2.14, « Vitesse des requêtes INSERT »7.2.14. Vitesse des requêtes INSERT.
13-1-6. Syntaxe de REPLACE▲
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. Voir Section 13.1.4, « Syntaxe de INSERT »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'était 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 une 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ée 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.
-
13-1-7. Syntaxe de SELECT▲
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 disponible depuis MySQL 4.0 et 4.1, respectivement. Voir Section 13.1.7.2, « Syntaxe de UNION »13.1.7.2. Syntaxe de UNION et Section 13.1.8, « Sous-sélections (SubSELECT) »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 »13.1.7.1. Syntaxe de JOIN.
-
where_definition indique les conditions auxquelles 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 utilisantAS
. L'alias est utilisé de la même façon que le nom du champ et peut être employé avec des clausesORDER
BY
ouHAVING
. Par exemple :Sélectionnezmysql
>
SELECT
CONCAT
(
last_name,', '
,first_name)
AS
full_nameFROM
mytableORDER
BY
full_name;Le mot-clé
AS
est optionnel lors de la création d'un alias pour une expressionSELECT
. L'exemple précédent aurait pu être écrit comme ceci :Sélectionnezmysql
>
SELECT
CONCAT
(
last_name,', '
,first_name)
full_nameFROM
mytableORDER
BY
full_name;Comme
AS
est optionnel, un problème subtil peut survenir si vous oubliez une virgule entre deux expressions deSELECT
: 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 :Sélectionnezmysql
>
SELECT
columna columnbFROM
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 clauseWHERE
est exécutée. Voir Section A.5.4, « Problèmes avec les alias »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 »13.1.7.1. Syntaxe de JOIN. Pour chaque table spécifiée, vous pouvez éventuellement indiquer un alias.Sélectionneztbl_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 »13.1.7.1. Syntaxe de JOIN.En MySQL 4.0.14, vous pouvez utiliser
SET
MAX_SEEKS_FOR_KEY=
value
comme une autre solution 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é 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 ambigüe. Consultez Section 9.2, « Noms de bases, tables, index, colonnes et alias »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é à spécifier
DUAL
comme nom de table, dans les situations où aucune table n'est référencée. C'est une fonctionnalité pure de compatibilité, car certains autres serveurs requièrent cette syntaxe.Sélectionnezmysql
>
SELECT
1
+
1
FROM
DUAL
;->
2
-
Une référence à une table peut être « aliasée » en utilisant nom_de_table
[AS]
alias_name :Sélectionnezmysql
>
SELECT
t1.name
, t2.salaryFROM
employeeAS
t1, infoAS
t2->
WHERE
t1.name
=
t2.name
; mysql>
SELECT
t1.name
, t2.salaryFROM
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. Voir Chapitre 12, Fonctions à utiliser dans les clauses SELECT et WHEREChapitre 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
etGROUP
BY
en utilisant leur nom de colonne, les alias ou leur position de colonne. Les positions commencent à 1 :Sélectionnezmysql
>
SELECT
college, region, seedFROM
tournament->
ORDER
BY
region, seed; mysql>
SELECT
college, regionAS
r, seedAS
sFROM
tournament->
ORDER
BY
r, s; mysql>
SELECT
college, region, seedFROM
tournament->
ORDER
BY
2
,3
;Pour trier dans l'ordre inverse, ajoutez le mot-clé
DESC
(descendant) au nom du champ dans la clauseORDER
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 colonnesGROUP
BY
comme si on avait ajouté la clauseORDER
BY
pour ces colonnes. MySQL a amélioré la clauseGROUP
BY
depuis la version 3.23.34 pour que vous puissiez aussi spécifierASC
etDESC
après le nom de la colonne :SélectionnezSELECT
a,COUNT
(
b)
FROM
test_tableGROUP
BY
aDESC
-
MySQL améliore l'utilisation de
GROUP
BY
en vous autorisant à l'utiliser avec des champs qui ne sont pas mentionnés dans la clauseGROUP
BY
. Si vous n'obtenez pas les résultats que vous attendiez, lisez la description deGROUP
BY
. Voir Section 12.9, « Fonctions et options à utiliser dans les clauses GROUP BY »12.9. Fonctions et options à utiliser dans les clauses GROUP BY. -
Depuis MySQL 4.1.1,
GROUP
BY
dispose de l'optionWITH
ROLLUP
. Voir Section 12.9.2, « Options de GROUP BY »12.9.2. Options de GROUP BY. -
La clause
HAVING
peut faire référence à n'importe quel champ ou alias définis 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 clauseWHERE
. Par exemple, n'écrivez pas ceci :Sélectionnezmysql
>
SELECT
nom_de_colonneFROM
nom_de_tableHAVING
nom_de_colonne>
0
;Écrivez plutôt cela :
Sélectionnezmysql
>
SELECT
nom_de_colonneFROM
nom_de_tableWHERE
nom_de_colonne>
0
;Dans les versions 3.22.5 et supérieures de MySQL, vous pouvez aussi écrire des requêtes ainsi :
Sélectionnezmysql
>
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 :
Sélectionnezmysql
>
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 clauseWHERE
ne le peut pas :Sélectionnezmysql
>
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
:Sélectionnezmysql
>
SELECT
user
,MAX
(
salary)
AS
max_salaryFROM
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 commandeSELECT
.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'enregistrements à 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
.Sélectionnezmysql
>
SELECT
*
FROM
table
LIMIT
5
,10
;# Retourne les enregistrements 6 à 15
Pour obtenir tous les enregistrements d'un certain décalage jusqu'à la fin du résultat, vous pouvez utiliser de grands entiers en tant que second paramètre :
Sélectionnezmysql
>
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 :
Sélectionnezmysql
>
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'
deSELECT
écrit les lignes sélectionnées dans un fichier. Le fichier est créé sur le serveur et ne peut y être déjà présent (cela permet entre autres d'éviter la destruction des tables et de fichiers tels que /etc/passwd). Vous devez avoir le droitFILE
sur le serveur pour utiliser cette forme deSELECT
.SELECT
...INTO
OUTFILE
a 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 utiliserSELECT
...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 deLOAD
DATA
INFILE
. La syntaxe pour la partie export_options de la requête se compose des mêmes clausesFIELDS
etLINES
que celles utilisées avec la commandeLOAD
DATA
INFILE
. Voir Section 13.1.5, « Syntaxe de LOAD DATA INFILE »13.1.5. Syntaxe de LOAD DATA INFILE.Dans le fichier résultant, seuls les caractères suivants sont protégés par le caractère
ESCAPED
BY
:-
le caractère
ESCAPED
BY
; -
les premiers caractères de
FIELDS
TERMINATED
BY
; -
les premiers caractères de
LINES
TERMINATED
BY
; -
ASCII
0
est converti enESCAPED
BY
suivi de 0 (ASCII
48
).
Si le caractère
FIELDS
ESCAPED
BY
est vide, aucun caractère n'est protégé, etNULL
vautNULL
, 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 si 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
, ouLINES
TERMINATED
BY
pour assurer une relecture fiable du fichier. Le caractèreASCII
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 pas besoin d'échapper autre chose.
Voici un exemple de relecture de fichier au format utilisé par plusieurs anciens programmes.
SélectionnezSELECT
a,b,a+
bINTO
OUTFILE
'/tmp/result.text'
FIELDS
TERMINATED
BY
','
OPTIONALLY
ENCLOSED
BY
'"'
LINES
TERMINATED
BY
'\n'
FROM
test_table; -
-
Si vous utilisez
INTO
DUMPFILE
au lieu deINTO
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 unBLOB
dans un fichier. -
Note : notez que les fichiers créés par
INTO
OUTFILE
etINTO
DUMPFILE
seront lisibles par tous 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 mots lisibles 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 »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 ligne ou de page, 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 indiquent que les doublons doivent être éliminés du résultat.
HIGH_PRIORITY
, STRAIGHT_JOIN
, et les options commençant par SQL_ sont des extensions MySQL au standard SQL.
-
HIGH_PRIORITY
donne à une commandeSELECT
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êteSELECT
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 commandesSELECT
qui font partie d'uneUNION
. -
STRAIGHT_JOIN
force l'optimiseur à joindre les tables dans l'ordre dans lequel elles sont listées dans la clauseFROM
. Vous pouvez utiliser cela pour accélérer la requête, si les tables sont réordonnées sub-optimalement par l'optimiseur. Voir Section 7.2.1, « Syntaxe de EXPLAIN (Obtenir des informations sur les SELECT) »7.2.1. Syntaxe de EXPLAIN (Obtenir des informations sur les SELECT).STRAIGHT_JOIN
peut aussi être utilisée dans la liste table_references. Voir Section 13.1.7.1, « Syntaxe de JOIN »13.1.7.1. Syntaxe de JOIN. -
SQL_BIG_RESULT
peut être utilisé avecGROUP
BY
ouDISTINCT
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 duGROUP
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 important. -
SQL_SMALL_RESULT
, une option spécifique à MySQL, peut être utilisée avecGROUP
BY
ouDISTINCT
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érieures) indique à MySQL de calculer combien d'enregistrements seront dans le jeu de résultats, indépendamment de n'importe quelle clauseLIMIT
. Le nombre d'enregistrements peut alors être obtenu avecSELECT
FOUND_ROWS
()
. Voir Section 12.8.4, « Fonctions diverses »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 ligne). Voir Section 7.2.12, « Comment MySQL optimise LIMIT »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 valeur2
ou DEMAND. Pour une requête qui utiliseUNION
ou une sous-requête, cette option prend effet si elle est utilisée dans n'importe quelle partie de la requêteSELECT
. Voir Section 5.11, « Cache de requêtes MySQL »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). Voir Section 5.11, « Cache de requêtes MySQL »5.11. Cache de requêtes MySQL. Pour les requêtes qui utilisentUNION
ou les sous-requêtes, cette option aura un effet sur toutes les parties de la requêteSELECT
.
13-1-7-1. Syntaxe de JOIN▲
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_cles)]
[IGNORE INDEX (liste_de_cles)]
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 :Sélectionnezmysql
>
SELECT
t1.name
, t2.salaryFROM
employeeAS
t1, infoAS
t2->
WHERE
t1.name
=
t2.name
; -
La condition
ON
est de la même forme qu'une condition pouvant être utilisée dans la clauseWHERE
. -
Si aucune ligne ne correspond dans la table de droite dans la partie
ON
ouUSING
duLEFT
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 :Sélectionnezmysql
>
SELECT
table1.*
FROM
table1->
LEFT
JOIN
table2ON
table1.id=
table2.id->
WHERE
table2.idIS
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 correspondance dans la table table2). Cela demande que table2.id soit déclaré
NOT
NULL
, bien sûr. Voir Section 7.2.9, « Comment MySQL optimise les clauses LEFT JOIN et RIGHT JOIN »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 clausesUSING
suivantes sont identiques :Sélectionneza
LEFT
JOIN
bUSING
(
c1,c2,c3)
aLEFT
JOIN
bON
a.c1=
b.c1AND
a.c2=
b.c2AND
a.c3=
b.c3 -
La jointure de deux tables avec
NATURAL
[LEFT]
JOIN
est définie pour être sémantiquement équivalente à unINNER
JOIN
ou unLEFT
JOIN
avec une clauseUSING
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 clauseWHERE
. -
RIGHT
JOIN
fonctionne de façon analogue àLEFT
JOIN
. Pour garder un code facilement portable, il est recommandé d'utiliser lesLEFT
JOIN
à la place desRIGHT
JOIN
. -
STRAIGHT_JOIN
est identique àJOIN
, sauf que la table de gauche est toujours lue avant celle de droite. Cela peut être utilisé dans les cas (rares) où l'optimiseur des jointures place les tables dans le mauvais ordre.
À 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_cles)
, vous pouvez forcer MySQL à utiliser un index spécifique pour trouver les enregistrements dans la table. Une variante réside dans l'utilisation de IGNORE
INDEX
(
liste_de_cles)
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 scans de tables seront très coûteux. En d'autres termes, les scans de tables ne 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
;
13-1-7-2. Syntaxe de UNION▲
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és comme noms de champ 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 clauseINTO
OUTFILE
. -
HIGH_PRIORITY
ne peut être utilisée avec les commandesSELECT
qui ne font pas partie de l'UNION
. Si vous la spécifiez pour la première commandeSELECT
, elle n'aura pas d'effet. Si vous la spécifiez pour toute autre commandeSELECT
suivante, une erreur de syntaxe sera signalée.
Si vous n'utilisez pas le mot-clé 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 tous 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ées 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 |
+
---------------+
13-1-8. Sous-sélections (SubSELECT)▲
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 les suivantes.
-
Elles permettent aux requêtes d'être structurées 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. Voir Section 13.1.8.11, « Se passer des sous-requêtes avec les premières versions de MySQL »13.1.8.11. Se passer des sous-requêtes avec les premières versions de MySQL.
13-1-8-1. Les sous-requêtes comme opérateur scalaire▲
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'utiliser à 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
etDO
. -
Une sous-requête peut contenir les mots-clés 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;
13-1-8-2. Comparaisons avec les sous-requêtes▲
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 classique, 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)
;
13-1-8-3. Sous-requêtes avec les clauses ANY, IN et SOME▲
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.
13-1-8-4. Sous-requêtes avec ALL▲
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 penser 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.
13-1-8-5. Sous-requêtes de ligne▲
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)
;
13-1-8-6. EXISTS et NOT EXISTS▲
Si une sous-requête ne 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 ?
SélectionnezSELECT
DISTINCT
store_typeFROM
StoresWHERE
EXISTS
(
SELECT
*
FROM
Cities_StoresWHERE
Cities_Stores.store_type=
Stores.store_type)
; -
Quel type de magasin n'est présent dans aucune ville ?
SélectionnezSELECT
DISTINCT
store_typeFROM
StoresWHERE
NOT
EXISTS
(
SELECT
*
FROM
Cities_StoresWHERE
Cities_Stores.store_type=
Stores.store_type)
; -
Quel type de magasin est présent dans toutes les villes ?
SélectionnezSELECT
DISTINCT
store_typeFROM
Stores S1WHERE
NOT
EXISTS
(
SELECT
*
FROM
CitiesWHERE
NOT
EXISTS
(
SELECT
*
FROM
Cities_StoresWHERE
Cities_Stores.city=
Cities.cityAND
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 ? ».
13-1-8-7. Sous-requêtes corrélées▲
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.
13-1-8-8. Sous-requêtes dans la clause FROM▲
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.
13-1-8-9. Erreurs de sous-requêtes▲
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.
-
Sélectionnez
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
SélectionnezSELECT
*
FROM
t1WHERE
s1IN
(
SELECT
s2FROM
t2ORDER
BY
s1LIMIT
1
)
ne fonctionnera pas, mais uniquement dans certaines versions d'origine, comme MySQL 4.1.1.
-
Sélectionnez
ERROR
1240
(
ER_CARDINALITY_COL)
SQLSTATE
=
21000
Message=
"Operand should contain 1 column(s)"
Cette erreur va survient dans des cas comme celui-ci :
SélectionnezSELECT
(
SELECT
column1, column2FROM
t2)
FROM
t1;Il est valide d'utiliser une sous-requête qui utilise plusieurs colonnes, dans le cadre d'une comparaison. Voir Section 13.1.8.5, « Sous-requêtes de ligne »13.1.8.5. Sous-requêtes de ligne. Mais dans d'autres contextes, la sous-requête doit être un opérande scalaire.
-
Sélectionnez
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 :
SélectionnezSELECT
*
FROM
t1WHERE
column1=
(
SELECT
column1FROM
t2)
;mais uniquement lorsque plus d'une ligne est extraite de t2. Cela signifie que cette erreur peut survenir dans du code qui fonctionne depuis longtemps : quelqu'un vient de modifier le nombre de lignes 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é :
SélectionnezSELECT
*
FROM
t1WHERE
column1=
ANY
(
SELECT
column1FROM
t2)
; -
Sélectionnez
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 :
SélectionnezUPDATE
t1SET
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'une sous-requête entraîne l'échec de toute la commande.
13-1-8-10. Optimisation des sous-requêtes▲
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 :
SélectionnezSELECT
*
FROM
t1WHERE
t1.column1IN
(
SELECT
column1FROM
t2ORDER
BY
column1)
;SELECT
*
FROM
t1WHERE
t1.column1IN
(
SELECT
DISTINCT
column1FROM
t2)
;SELECT
*
FROM
t1WHERE
EXISTS
(
SELECT
*
FROM
t2LIMIT
1
)
; -
Remplacer une jointure par une sous-requête. Par exemple :
SélectionnezSELECT
DISTINCT
column1FROM
t1WHERE
t1.column1IN
(
SELECT
column1FROM
t2)
;au lieu de
SélectionnezSELECT
DISTINCT
t1.column1FROM
t1, t2WHERE
t1.column1=
t2.column1; -
Déplacer une clause
FROM
externe dans une sous-requête, comme ceci :SélectionnezSELECT
*
FROM
t1WHERE
s1IN
(
SELECT
s1FROM
t1UNION
ALL
SELECT
s1FROM
t2)
;au lieu de
SélectionnezSELECT
*
FROM
t1WHERE
s1IN
(
SELECT
s1FROM
t1)
OR
s1IN
(
SELECT
s1FROM
t2)
;Un autre exemple :
SélectionnezSELECT
(
SELECT
column1+
5
FROM
t1)
FROM
t2;au lieu de
SélectionnezSELECT
(
SELECT
column1FROM
t1)
+
5
FROM
t2; -
Utiliser une sous-requête de ligne plutôt qu'une corrélation. Par exemple :
SélectionnezSELECT
*
FROM
t1WHERE
(
column1,column2)
IN
(
SELECT
column1,column2FROM
t2)
;au lieu de
SélectionnezSELECT
*
FROM
t1WHERE
EXISTS
(
SELECT
*
FROM
t2WHERE
t2.column1=
t1.column1AND
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 optimisations 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 corrélé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 les sous-requêtes sont indexées. -
MySQL remplacera les sous-requêtes de la forme
Sélectionnez...
IN
(
SELECT
indexed_columnFROM
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
Sélectionnezvaleur {
ALL
|
ANY
|
SOME
} {>
|
<
|
>=
|
<=
}(
sous-
requête non corrélée)
avec une expression impliquant
MIN
ouMAX
(à moins d'une valeurNULL
ou d'ensemblesSET
vides). Par exemple,SélectionnezWHERE
5
>
ALL
(
SELECT
x
FROM
t)
revient à
SélectionnezWHERE
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.
13-1-8-11. Se passer des sous-requêtes avec les premières versions de MySQL▲
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 équivalente, 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 :
-
passer en MySQL version 4.1 ;
-
utiliser 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 typeDELETE
(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 commandes
DELETE
automatiquement, avec la fonctionCONCAT
()
au lieu de l'opérateur ||. Par exemple :SélectionnezSELECT
CONCAT
(
'DELETE FROM tab1 WHERE pkid = '
,"'"
, tab1.pkid,"'"
,';'
)
FROM
tab1, tab2WHERE
tab1.col1=
tab2.col2;Vous pouvez placer cette requête dans un fichier de scripts, 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 :
Sélectionnezshell
>
mysql --skip-column-names mydb<
myscript.sql|
mysql mydb
MySQL 4.0 supporte les commandes DELETE
multitables 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
multitables sont aussi supportées depuis la version 4.0.
13-1-9. Syntaxe de TRUNCATE▲
TRUNCATE
TABLE
nom_de_table
Dans la version 3.23, TRUNCATE
TABLE
est équivalent à COMMIT
; DELETE
FROM
nom_de_table. Voir Section 13.1.1, « Syntaxe de DELETE »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éfinitions nom_de_table.frm est valide, la table peut être recréée, même si les données ou un index ont été corrompus.
-
Le gestionnaire de tables 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.
13-1-10. Syntaxe de UPDATE▲
UPDATE
[LOW_PRIORITY]
[IGNORE]
tbl_name
SET
col_name1=
expr1 [, col_name2=expr2 ...]
[WHERE where_definition]
[ORDER BY ...]
[LIMIT row_count]
Syntaxe multitable :
UPDATE
[LOW_PRIORITY]
[IGNORE]
tbl_name [, tbl_name ...]
SET
col_name1=
expr1 [, col_name2=expr2 ...]
[WHERE where_definition]
UPDATE
met à jour des enregistrements dans une table 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-clé
LOW_PRIORITY
, l'exécution de l'UPDATE
sera repoussé jusqu'à ce qu'aucun client ne lise plus de la table. -
Si vous spécifiez le mot-clé
IGNORE
, la mise à jour ne s'interrompra pas même si on rencontre des problèmes d'unicité de clés durant l'opération. Les enregistrements posant problème 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 colonne â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 utiliser le code LIMIT
#
pour vous assurer que seul un nombre d'enregistrements bien précis sont changés.
-
Avant MySQL 4.0.13,
LIMIT
est une restriction sur le nombre de lignes affectées. Cette clause stoppe dès que row_count ont été trouvées par la clauseWHERE
. -
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 clauseWHERE
, qu'elles aient été changées ou pas.
Si 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
multitable 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
multitables.
13-2. Définition de données : CREATE, DROP, ALTER▲
13-2-1. Syntaxe de ALTER DATABASE▲
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 UnicodeChapitre 10. Jeux de caractères et Unicode.
ALTER
DATABASE
a été ajoutée MySQL 4.1.1.
13-2-2. Syntaxe de ALTER TABLE▲
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 similaire aux clauses de la commande CREATE
TABLE
. Voir Section 13.2.5, « Syntaxe de CREATE TABLE »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écrites dans Section 13.2.5.1, « Modification automatique du type de colonnes »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é, 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 droitsALTER
,INSERT
, etCREATE
sur la table. -
IGNORE
est une extension MySQL pour ANSI SQL92. Cette option contrôle la façon dontALTER
TABLE
fonctionne s'il y a des duplications sur une clé unique de la nouvelle table. SiIGNORE
n'est pas spécifiée, la copie est annulée et la table originale est restaurée. SiIGNORE
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
, etCHANGE
dans une même commandeALTER
TABLE
. C'est une extension de MySQL à la norme ANSI SQL92, qui n'autorise qu'une seule modification par commandeALTER
TABLE
. -
CHANGE
nom_colonne,DROP
nom_colonne, etDROP
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_tableRENAME
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. Voir Section 13.2.9, « Syntaxe de RENAME TABLE »13.2.9. Syntaxe de RENAME TABLE. -
La définition create_definition utilise la même syntaxe pour les clauses
ADD
etCHANGE
que dansCREATE
TABLE
. Notez que cette syntaxe inclut le nom de la colonne, et pas seulement son type Voir Section 13.2.5, « Syntaxe de CREATE TABLE »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 typeINTEGER
, de a en b, vous pouvez faire ceci :Sélectionnezmysql
>
ALTER
TABLE
t1CHANGE
a bINTEGER
;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 :Sélectionnezmysql
>
ALTER
TABLE
t1CHANGE
b bBIGINT
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 :Sélectionnezmysql
>
ALTER
TABLE
t1MODIFY
bBIGINT
NOT
NULL
; -
Si vous utilisez les clauses
CHANGE
ouMODIFY
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 typeVARCHAR
), 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
ouMODIFY
, MySQL essaye de convertir les données au niveau type dans la mesure du possible. -
À partir de la version 3.22 de MySQL, vous pouvez utiliser
FIRST
ouADD
...AFTER
nom_colonne pour ajouter la colonne à un endroit spécifique dans la table. Par défaut, la colonne est ajoutée à la fin. À partir de la version 4.0.1, vous pouvez aussi utiliser les mots-clésFIRST
etAFTER
avecCHANGE
ouMODIFY
. -
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 êtreNULL
, la nouvelle valeur par défaut seraNULL
. Si la colonne ne peut êtreNULL
, MySQL assigne une valeur par défaut, comme défini dans Section 13.2.5, « Syntaxe de CREATE TABLE »13.2.5. Syntaxe de CREATE TABLE. -
DROP
INDEX
supprime un index. C'est une extension MySQL à la norme ANSI SQL92. Voir Section 13.2.7, « Syntaxe de DROP INDEX »13.2.7. Syntaxe de DROP INDEX. -
Si des colonnes sont effacées d'une table, ces colonnes sont aussi supprimées 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 clé primaire. Si cette clé n'existe pas, cette commande effacera le premier indexUNIQUE
de la table. (MySQL marque la première cléUNIQUE
en tant quePRIMARY
KEY
si aucunePRIMARY
KEY
n'a été spécifiée explicitement.)Si vous ajoutez un
UNIQUE
INDEX
ouPRIMARY
KEY
à une table, c'est enregistré avant les index nonUNIQUE
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 dansREPAIR
). Cela devrait rendreALTER
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 clés une par une, désactiver les clés peut vous faire gagner en performances. -
Les clauses
FOREIGN
KEY
etREFERENCES
sont supportées par le moteur de tables InnoDB, qui implémente les clausesADD
[CONSTRAINT [symbol]
]FOREIGN
KEY
(
...)
REFERENCES
...(
...)
. Voir Section 15.7.4, « Contraintes de clés étrangères FOREIGN KEY »15.7.4. Contraintes de clés étrangères FOREIGN KEY. Pour les autres moteurs de stockage, ces clauses sont lues, mais ignorées. La clauseCHECK
est analysée, mais ignorée par tous les moteurs de stockage. Voir Section 13.2.5, « Syntaxe de CREATE TABLE »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. Voir Section 1.5.5, « Différences entre MySQL et le standard SQL-92 »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 :SélectionnezALTER
TABLE
yourtablenameDROP
FOREIGN
KEY
fk_symbolPour plus d'informations, voyez Section 15.7.4, « Contraintes de clés étrangères FOREIGN KEY »15.7.4. Contraintes de clés étrangères FOREIGN KEY.
-
ALTER
TABLE
ignore les options de tablesDATA
DIRECTORY
etINDEX
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 :SélectionnezALTER
TABLE
tbl_nameCONVERT
TO
CHARACTER
SET
charset_name;C'est pratique lorsque vous passez de MySQL 4.0.x en 4.1.x. Voir Section 10.10, « Préparer le passage de version 4.0 en 4.1 »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 :
SélectionnezALTER
TABLE
t1CHANGE
c1 c1BLOB
;ALTER
TABLE
t1CHANGE
c1 c1TEXT
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 :
SélectionnezALTER
TABLE
tbl_nameDEFAULT
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, avecALTER
TABLE
...ADD
column
.Attention : depuis MySQL 4.1.2 et plus récents,
ALTER
TABLE
...DEFAULT
CHARACTER
SET
etALTER
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, maisALTER
TABLE
...CHARACTER
SET
(sansDEFAULT
) 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 :
SélectionnezALTER
TABLE
tbl_nameDISCARD
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 :
SélectionnezALTER
TABLE
tbl_nameIMPORT
TABLESPACE
; -
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 clé unique. Voir Section 24.2.3.31, « mysql_info() »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 clé 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. Voir Section 13.5.2.8, « Syntaxe de SET »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'autoincrémentation ne sera pas affecté. Si vous effacez une colonne AUTO_INCREMENT
puis en ajoutez une autre, l'indexation recommencera à partir de 1.
Voir Section A.7.1, « Problèmes avec ALTER TABLE. »A.7.1. Problèmes avec ALTER TABLE..
13-2-3. Syntaxe de CREATE DATABASE▲
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ées sont présentées dans la Section 9.2, « Noms de bases, tables, index, colonnes et alias »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és dans le Chapitre 10, Jeux de caractères et UnicodeChapitre 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. Voir Section 8.4, « mysqladmin, administration d'un serveur MySQL »8.4. mysqladmin, administration d'un serveur MySQL.
13-2-4. Syntaxe de CREATE INDEX▲
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. Voir Section 13.2.2, « Syntaxe de ALTER TABLE »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
. Voir Section 13.2.5, « Syntaxe de CREATE TABLE »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 multicolonne. 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 peuvent ê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érieures 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 »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 »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écents. Les colonnes spatiales sont présentées dans le Chapitre 18, Données spatiales avec MySQLChapitre 18. Données spatiales avec MySQL.
13-2-5. Syntaxe de CREATE TABLE▲
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 »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écents, 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 celui 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écents, 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ée si la table que vous essayez de créer existe déjà. Notez qu'il n'y a pas de comparaison 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 stockage pour représenter les tables sont décrits dans le Chapitre 14, Moteurs de tables MySQL et types de tableChapitre 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 colonnesChapitre 11. Types de colonnes. Pour des informations sur les types de données spatiaux, voyez Chapitre 18, Données spatiales avec MySQLChapitre 18. Données spatiales avec MySQL.
-
Si ni
NULL
, niNOT
NULL
n'est spécifié, une colonne utilisera par défaut l'attributNULL
(elle acceptera les valeursNULL
). -
Une colonne de nombres entiers peut se voir attribuer l'attribut
AUTO_INCREMENT
. Lorsque vous insérez la valeurNULL
(recommandée) ou0
dans une colonneAUTO_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 valeursAUTO_INCREMENT
commence à1
. Voir Section 24.2.3.33, « mysql_insert_id() »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 typeAUTO_INCREMENT
, au lieu de voir0
prendre le prochain numéro de séquence. Voir Section 5.2.1, « Options de ligne de commande de mysqld »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 passent de positif à négatif lorsqu'ils atteignent leur valeur maximale positive. C'est aussi pour éviter qu'une colonne de typeAUTO_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 commandeDELETE
FROM
nom_de_table (sans la clauseWHERE
)
en mode AUTOCOMMIT, la série des valeursAUTO_INCREMENT
recommencera à1
.Avec les tables MyISAM et BDB, vous pouvez spécifier une colonne secondaire d'
AUTO_INCREMENT
dans une clé multicolonne. Voir Section 3.6.9, « Utiliser AUTO_INCREMENT »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 :
SélectionnezSELECT
*
FROM
nom_de_tableWHERE
auto_colIS
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 UnicodeChapitre 10. Jeux de caractères et Unicode.SélectionnezCREATE
TABLE
t(
cCHAR
(
20
)
CHARACTER
SET
utf8COLLATE
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ètent comme des octets.
-
La valeur
NULL
est traitée différemment dans les colonnes de typeTIMESTAMP
. Vous ne pouvez pas stocker de valeurNULL
littérale dans une colonneTIMESTAMP
; insérer une valeurNULL
dans une telle colonne revient à insérer la date et l'heure courante. Car les colonnesTIMESTAMP
ignorent les attributs NULL etNOT
NULL
.Cela facilite grandement l'utilisation des colonnes
TIMESTAMP
pour les clients MySQL : le serveur indique que ces colonnes peuvent se voir assigner une valeurNULL
(ce qui est vrai), même si les colonnesTIMESTAMP
ne contiendront jamais de valeurNULL
. Vous pouvez le constater lorsque vous utilisez la commandeDESCRIBE
nom_de_table pour avoir une description de votre table.Notez qu'affecter la valeur
0
à une colonneTIMESTAMP
n'est pas la même chose que lui affecter la valeurNULL
, car0
est une valeurTIMESTAMP
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 fonctionNOW
()
ouCURRENT_DATE
.Si aucune valeur par défaut (attribut
DEFAULT
) n'est spécifiée, MySQL en assigne une automatiquement.Si la colonne accepte la valeur
NULL
, la valeur par défaut sera la valeurNULL
.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 sera0
. Pour une colonneAUTO_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 colonnesTIMESTAMP
, la valeur par défaut est la date et l'heure courante. Voir Section 11.3, « Les types date et heure »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. PourENUM
, la valeur par défaut est la première valeur de l'énumération.
Les colonnes
BLOB
etTEXT
ne peuvent pas recevoir de valeur par défaut. -
-
Un commentaire pour une colonne peut être spécifié avec
COMMENT
. Le commentaire est affiché par la commandeSHOW
CREATE
TABLE
et parSHOW
FULL
COLUMNS
. Cette option est disponible depuis MySQL 4.1. Elle était autorisée, mais ignorée dans les anciennes versions. -
Depuis MySQL version 4.1.0, l'attribut
SERIAL
peut être utilisé comme alias pour les colonnesBIGINT
UNSIGNED
NOT
NULL
AUTO_INCREMENT
UNIQUE
. C'est une fonctionnalité de compatibilité. -
KEY
est un synonyme deINDEX
. Depuis la version 4.1, l'attribut de cléPRIMARY
KEY
peut aussi être spécifié avec la clauseKEY
. Il a été implémenté pour assurer la compatibilité avec les autres bases. -
Avec MySQL, une clé
UNIQUE
peut avoir uniquement 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 indexUNIQUE
avec la contrainte supplémentaire que toutes les colonnes utilisées doivent avoir l'attributNOT
NULL
. En MySQL, cette clé est ditePRIMARY
. Une table ne peut avoir qu'une seule clé primaire. Si vous n'avez pas dePRIMARY
KEY
et que des applications demandent laPRIMARY
KEY
dans vos tables, MySQL retournera la première cléUNIQUE
, qui n'a aucune valeurNULL
. -
Dans une table créée, la clé primaire
PRIMARY
KEY
est placée en première, suivie de tous les indexUNIQUE
, et enfin, les index non uniques. Cela permet à l'optimiseur MySQL d'utiliser en priorité les index, et de détecter rapidement les doublons pour les clésUNIQUE
. -
Une
PRIMARY
KEY
peut être multicolonne. Cependant, vous ne pouvez pas créer d'index multicolonne avec l'attributPRIMARY
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 syntaxePRIMARY
KEY
(
index_nom_de_colonne, ...)
. -
Si une clé primaire (
PRIMARY
) ou unique (UNIQUE
) est établie 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
estPRIMARY
. 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 commandeSHOW
INDEX
FROM
tbl_name. Voir Section 13.5.3.6, « Syntaxe de SHOW DATABASES »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 stockage sont listées 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
/
HEAPHASH
,BTREE
Exemple :
SélectionnezCREATE
TABLE
lookup(
idINT
,INDEX
USING
BTREE
(
id))
ENGINE
=
MEMORY
;TYPE
type_name peut être utilisé comme synonyme deUSING
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 optionnel avecTYPE
. 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 colonnesNOT
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
ouVARCHAR
. Cela peut réduire la taille des fichiers d'index. Voir Section 7.4.3, « Index de colonnes »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
etTEXT
. Lorsque vous ajoutez un index à une colonneBLOB
ouTEXT
, vous devez absolument spécifier une longueur d'index :SélectionnezCREATE
TABLE
test(
blob_colBLOB
,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ée 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 multioctet. -
Une spécification index_col_name peut se terminer avec
ASC
ouDESC
. 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
ouGROUP
BY
sur une colonne de typeTEXT
ouBLOB
, seuls, les max_sort_longueur premiers octets seront lus. Voir Section 11.4.3, « Les types BLOB et TEXT »11.4.3. Les types BLOB et TEXT. -
En MySQL version 3.23.23 ou plus récentes, vous pouvez aussi créer des index spéciaux
FULLTEXT
. Ils sont utilisés pour faire des recherches en texte plein. Seul, le format de table MyISAM supporte les indexFULLTEXT
. Ils peuvent être créés uniquement pour les colonnes de typeVARCHAR
etTEXT
. 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 »12.6. Recherche en texte intégral (Full-text) dans MySQL pour les détails. -
En MySQL version 4.1 ou plus récentes, 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 commeNOT
NULL
. Voyez Chapitre 18, Données spatiales avec MySQLChapitre 18. Données spatiales avec MySQL. -
En MySQL version 3.23.44 et plus récentes, les tables InnoDB supportent la vérification de clés étrangères. Voir Chapitre 15, Le moteur de tables InnoDBChapitre 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 clausesON
DELETE
etON
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 »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
etREFERENCES
dans les commandesCREATE
TABLE
, et aucune action n'est réalisée. Voir Section 1.5.5.5, « Les clés étrangères »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 :
Sélectionnezrow
longueur=
1
+
(
somme des longueurs de colonnes)
+
(
nombre de colonnesNULL
+
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érence entre les colonnes
NULL
et les colonnesNOT
NULL
.
Les options options_de_table et SELECT
ne sont implémentées que dans MySQL version 3.23 et plus récents.
Les options ENGINE
et TYPE
spécifient 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. Voir Section 14.7, « Le moteur de table ARCHIVE »14.7. Le moteur de table ARCHIVE. |
BDB | Tables avec transactions. Voir Section 14.4, « Tables BDB ou BerkeleyDB »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. Voir Section 14.8, « Le moteur CSV »14.8. Le moteur CSV. |
EXAMPLE | Un moteur d'exemple. Voir Section 14.5, « Le moteur de table EXAMPLE »14.5. Le moteur de table EXAMPLE. |
FEDERATED | Un moteur qui accède à des tables distantes. Voir Section 14.6, « Le moteur de table FEDERATED »14.6. Le moteur de table FEDERATED. |
HEAP | Les données de ces tables ne sont stockées qu'en mémoire. Voir Section 14.3, « Le moteur de table MEMORY (HEAP) »14.3. Le moteur de table MEMORY (HEAP). |
ISAM | Le gestionnaire originel de tables. Voir Section 14.9, « Tables ISAM »14.9. Tables ISAM. |
InnoDB | Tables transactionnelles avec verrou de lignes. Voir Chapitre 15, Le moteur de tables InnoDBChapitre 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. Voir Section 14.2, « Tables assemblées MERGE »14.2. Tables assemblées MERGE. |
MRG_MyISAM | Un synonyme pour les tables MERGE. |
MyISAM | Le nouveau gestionnaire de tables binaires et portable. Voir Section 14.1, « Le moteur de tables MyISAM »14.1. Le moteur de tables MyISAM. |
NDB
|
Alias de NDBCLUSTER . |
NDBCLUSTER
|
Tables en grappe et en mémoire, tolérantes aux pannes. Voir Chapitre 16, Introduction à MySQL ClusterChapitre 16. Introduction à MySQL Cluster. |
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 colonneAUTO_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éez une table MyISAM, MySQL utilise le produit des options
MAX_ROWS
etAVG_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 de petite 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. Voir Section 5.2.3, « Variables serveur système »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 colonnesCHAR
/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 utilisezPACK_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é estNULL
.) -
-
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
etFIXED
en format de ligne. Voir Section 14.1.3, « Formats de table MyISAM »14.1.3. Formats de table MyISAM. -
RAID_TYPE
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 comportent comme une seule table. Cela fonctionne avec les tablesMERGE
. Voir Section 14.2, « Tables assemblées MERGE »14.2. Tables assemblées MERGE.Pour le moment, vous devez avoir les droits de
SELECT
,UPDATE
etDELETE
pour les tables intégrées dans la tableMERGE
. Originalement, toutes les tables utilisées devaient être dans la même base de données, que la tableMERGE
. 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'attributINSERT_METHOD
. L'optionINSERT_METHOD
est utilisée uniquement avec les tablesMERGE
. Cette option a été introduite en MySQL 4.0.0. Voir Section 14.2, « Tables assemblées MERGE »14.2. Tables assemblées MERGE. -
DATA
DIRECTORY
,INDEX
DIRECTORY
En utilisant
DATA
DIRECTORY
=
'directory'
ouINDEX
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. Voir Section 7.6.1.2, « Utiliser les liens symboliques avec les tables sous Unix »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 expressions de la requête. Si vous ne le faites 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ées. 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és, 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
.
13-2-5-1. Modification automatique du type de colonnes▲
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 enCHAR
. -
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
ouBLOB
) toutes les colonnesCHAR
de plus de trois caractères sont transformées enVARCHAR
. 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. Voir Chapitre 14, Moteurs de tables MySQL et types de tableChapitre 14. Moteurs de tables MySQL et types de table. -
Depuis la version 4.1.0, si un champ
CHAR
ouVARCHAR
est spécifié avec une taille supérieure à 255, il est converti enTEXT
. 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 paire supérieure la plus proche. -
Vous ne pouvez pas stocker de valeur littérale
NULL
dans une colonne de typeTIMESTAMP
. Cette valeur sera remplacée par la date et l'heure courante. De ce fait, les attributsNULL
etNOT
NULL
n'ont pas de sens pour ces colonnes et sont ignorés.DESCRIBE
nom_de_table indiquera toujours que la colonneTIMESTAMP
accepte les valeursNULL
. -
Les colonnes qui font partie d'une
PRIMARY
KEY
ont l'attributNOT
NULL
même si elles ne sont pas déclarées comme telles. -
Depuis MySQL 3.23.51, les espaces terminaux sont automatiquement supprimés des valeurs
ENUM
etSET
lors de la création de la table. -
MySQL change certains types de colonnes utilisés par d'autres serveurs SQL en types MySQL. Voir Section 11.7, « Utilisation des types de données issues d'autres SGBDR »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. Voir Section 14.1.3.3, « Caractéristiques des tables compressées »14.1.3.3. Caractéristiques des tables compressées.
13-2-6. Syntaxe de DROP DATABASE▲
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-clé 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és. 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 a supprimé ceux listés ci-dessus, le dossier de base ne pourra pas être supprimé. Dans ce cas, vous devez supprimer manuellement les fichiers restants, et lancer à nouveau la commande DROP
DATABASE
.
Vous pouvez aussi supprimer des bases de données avec mysqladmin. Voir Section 8.4, « mysqladmin, administration d'un serveur MySQL »8.4. mysqladmin, administration d'un serveur MySQL.
13-2-7. Syntaxe de DROP INDEX▲
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.
Voir Section 13.2.2, « Syntaxe de ALTER TABLE »13.2.2. Syntaxe de ALTER TABLE.
13-2-8. Syntaxe de DROP TABLE▲
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 table 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. Voir Section 13.5.3.19, « SHOW WARNINGS | ERRORS »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 droit 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.
13-2-9. Syntaxe de RENAME TABLE▲
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 à leur valeur d'origine pour revenir à l'état d'origine.
RENAME
TABLE
a été ajouté à la version 3.23.23 de MySQL.
13-3. Commandes de base de l'utilisateur de MySQL▲
13-3-1. Syntaxe de DESCRIBE (obtenir des informations sur les colonnes)▲
{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
.
Voir Section 13.5.3.3, « Syntaxe de SHOW COLUMNS »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éfini lors du CREATE
TABLE
, notez que MySQL change le type des colonnes de temps en temps. Voir Section 13.2.5.1, « Modification automatique du type de colonnes »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. Voir Section 13.5.3, « Syntaxe de SHOW »13.5.3. Syntaxe de SHOW.
13-3-2. Syntaxe de USE▲
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.
13-4. Commandes relatives aux verrous et aux transactions▲
13-4-1. Syntaxes de START TRANSACTION, COMMIT et ROLLBACK▲
Par défaut, MySQL est lancé en mode autocommit. Cela signifie que chaque modification effectuée est enregistrée 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
À 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és à 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 transactionnelle, 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. Voir Section 5.9.4, « Le log binaire »5.9.4. Le log binaire.
Vous pouvez changer le niveau d'isolation des transactions avec SET
TRANSACTION
ISOLATION
LEVEL
.... Voir Section 13.4.6, « Syntaxe de SET TRANSACTION »13.4.6. Syntaxe de SET TRANSACTION .
13-4-2. Commandes qui ne peuvent pas être annulées▲
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 ne pourrez pas annuler l'ensemble de la transaction avec ROLLBACK
.
13-4-3. Commandes qui peuvent causer une validation implicite▲
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.
13-4-4. Syntaxe de SAVEPOINT et ROLLBACK TO SAVEPOINT▲
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 faites 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. Dans ce cas, le verrou sera levé par l'annulation. Les jalons qui ont été posés 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.
13-4-5. Syntaxe de LOCK TABLES/UNLOCK TABLES▲
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) peut uniquement accéder à 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
. Voir Section 13.5.4.3, « Syntaxe de KILL »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 sûr, 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 queUNLOCK
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 unSELECT
et unUPDATE
. L'exemple suivant nécessiteLOCK
TABLES
pour s'exécuter en toute sécurité :Sélectionnezmysql
>
LOCK
TABLES
transREAD
, customerWRITE
; mysql>
SELECT
SUM
(
value
)
FROM
transWHERE
customer_id=
some_id; mysql>
UPDATE
customerSET
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 duSELECT
et l'exécution de la requêteUPDATE
.
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. Voir Section 1.5.5.3, « Transactions et opérations atomiques »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. Voir Section 12.8.4, « Fonctions diverses »12.8.4. Fonctions diverses.
Voir Section 7.3.1, « Méthodes de verrouillage »7.3.1. Méthodes de verrouillage pour plus de détails.
Il est possible de verrouiller toutes les tables de toutes les bases avec la commande FLUSH
TABLES
WITH
READ
LOCK
.
Voir Section 13.5.4.2, « Syntaxe de FLUSH »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 verrouiller la table. Voir Section A.7.1, « Problèmes avec ALTER TABLE. »A.7.1. Problèmes avec ALTER TABLE..
13-4-6. Syntaxe de SET TRANSACTION▲
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 connexions. 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 ... »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=.... Voir Section 4.3.1, « Options de ligne de commande de mysqld »4.3.1. Options de ligne de commande de mysqld.
13-5. Référence de langage d'administration de la base de données▲
13-5-1. Commande de gestion des comptes utilisateur▲
13-5-1-1. Syntaxe de CREATE USER▲
CREATE
USER
user
[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és de la même manière que dans la commande GRANT
.
La commande CREATE
USER
a été ajoutée en MySQL 5.0.2.
13-5-1-2. Effacer des utilisateurs MySQL▲
DROP
USER
user_name
Cette commande a été ajoutée en MySQL 4.1.1.
Elle efface un utilisateur qui n'a aucun droit.
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
. Voir Section 13.5.3.13, « SHOW PRIVILEGES »13.5.3.13. SHOW PRIVILEGES ; -
Effacez tous les droits de l'utilisateur avec la commande
REVOKE
. Voir Section 13.5.1.3, « Syntaxe de GRANT et REVOKE »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
;
13-5-1-3. Syntaxe de GRANT et REVOKE▲
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écents. Pour les anciennes versions de MySQL, ces commandes ne font rien.
Les informations sur les comptes MySQL sont stockées dans la base mysql. Cette base et son accès sont présentés en détail dans le Chapitre 5, Administration du serveurChapitre 5. Administration du serveur.
Les droits sont donnés à quatre 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 vu 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 droit ». |
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. Voir Section 2.6.7, « Mise à jour des tables de droits »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 les 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 jokers '_' 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 jokers (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 jokers 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 base 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. Les détails de la procédure de vérification des droits sont disponibles dans Section 5.5, « Règles de sécurité et droits d'accès au serveur MySQL »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'autres 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écentes, 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
. Voir Section 13.5.1.5, « Syntaxe de SET PASSWORD »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'ait 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 donniez à 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 faites, 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. Voir Section 5.6.4, « Limiter les ressources utilisateur »5.6.4. Limiter les ressources utilisateur. 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 »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.Sélectionnezmysql
>
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.Sélectionnezmysql
>
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'optionSSL
est inutile.Sélectionnezmysql
>
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.Sélectionnezmysql
>
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és. En utilisant cette option, vous pouvez spécifier un chiffrement spécifique.Sélectionnezmysql
>
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 un peu MySQL.
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. Voir Section 5.5.7, « Quand les modifications de privilèges prennent-ils effets ? »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 suivantes.
-
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.
13-5-1-4. Syntaxe de RENAME USER▲
RENAME
USER
old_user TO
new_user
[, old_user TO new_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.
13-5-1-5. Syntaxe de SET PASSWORD▲
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
;
13-5-2. Commandes d'entretien des tables▲
13-5-2-1. Syntaxe de ANALYZE TABLE▲
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
. Voir Section 13.5.3.6, « Syntaxe de SHOW DATABASES »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.
13-5-2-2. Syntaxe de BACKUP TABLE▲
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 tables dont on a besoin pour la restaurer vers le dossier de sauvegardes après avoir rafraîchi 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 »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 tables, 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.
13-5-2-3. Syntaxe de CHECK TABLE▲
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 statuts 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. Voir Section 5.7.3, « Utilisation de myisamchk pour la maintenance des tables et leur recouvrement »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é 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 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éussi).
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 colonneAUTO_INCREMENT
vaut 0 en spécifiant explicitement la valeur 0 dans la colonne avec la commandeUPDATE
.Ce n'est pas une erreur en soi, 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 colonneAUTO_INCREMENT
va changer automatiquement de valeur, en suivant les règles des colonnes de typeAUTO_INCREMENT
, qui vont causer un problème de clé doublon.Pour se débarrasser de cette alerte, vous devez utiliser une commande
UPDATE
sur la table, pour mettre une valeur différente de 0 dans cette colonne.
13-5-2-4. Syntaxe de CHECKSUM TABLE▲
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. Voir Section 13.2.5, « Syntaxe de CREATE TABLE »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.
13-5-2-5. Syntaxe de OPTIMIZE TABLE▲
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
. Voir Section 13.5.2.1, « Syntaxe de ANALYZE TABLE »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 soient utilisés.
13-5-2-6. Syntaxe de REPAIR TABLE▲
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é de retrouver vos données dans les tables MyISAM, avec la commande REPAIR
TABLE
. Si vos tables sont souvent corrompues, vous devriez toutefois rechercher la cause de ce problème ! Voir Section A.4.2, « Que faire si MySQL plante constamment ? »A.4.2. Que faire si MySQL plante constamment ?. Voir Section 14.1.4, « Problèmes avec les tables MyISAM »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 statuts 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
ne 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 toute manière). 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
).
13-5-2-7. Syntaxe de RESTORE TABLE▲
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 clés, 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. |
13-5-2-8. Syntaxe de SET▲
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 »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 utilisateur sont données dans Section 9.3, « Variables utilisateur »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
. sont 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 requiert le privilège SUPER
, l'option est gardée en mémoire et utilisée pour les nouvelles connexions 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. Voir Section 4.3.2, « Fichier d'options my.cnf »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 utilisé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
. Voir Section 13.5.3.18, « Syntaxe de SHOW VARIABLES »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 5.2.3, « Variables serveur système »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 multicommande, vous devez utiliser la commandeBEGIN
. Voir Section 13.4.1, « Syntaxes de START TRANSACTION, COMMIT et ROLLBACK »13.4.1. Syntaxes de START TRANSACTION, COMMIT et ROLLBACK. Si définie à0
vous devez utiliserCOMMIT
/ROLLBACK
pour accepter/annuler cette transaction. Notez que quand vous passez du mode non AUTOCOMMIT vers le mode AUTOCOMMIT, MySQL fera unCOMMIT
automatique sur toutes les transactions en cours. -
BIG_TABLES
=
{0
|
1
}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 grandsSELECT
qui requièrent une table temporaire. La valeur par défaut pour une nouvelle connexion est0
(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ères 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èresDEFAULT
.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és étrangères des tables InnoDB sont vérifiées. Si cette option vaut0
, 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'imposent les relations de contraintes. Cette variable a été ajoutée en MySQL 3.23.52. Voir Section 15.7.4, « Contraintes de clés étrangères FOREIGN KEY »15.7.4. Contraintes de clés étrangères FOREIGN KEY. -
IDENTITY
=
valeurCette 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 avecSELECT
@@IDENTITY
. Depuis MySQL 4.0.3, vous pouvez aussi modifier cette valeur avecSET
IDENTITY
. -
INSERT_ID
=
valeurConfigure la valeur à utiliser par l'appel suivant à la commande
INSERT
ouALTER
TABLE
lors de l'insertion d'une valeurAUTO_INCREMENT
. Cela est souvent utilisé par le log des modifications. -
LAST_INSERT_ID
=
valeurConfigure la valeur qui doit être retournée par
LAST_INSERT_ID
()
. C'est enregistré dans le log de mises à jour quand vous utilisezLAST_INSERT_ID
()
dans une commande qui met à jour une table. -
NAMES
{'charset_name'
|
DEFAULT
}SET
NAMES
spécifie les valeurs des trois variables système 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 colonneAUTO_INCREMENT
avec la construction suivante :SélectionnezWHERE
auto_increment_columnIS
NULL
Ceci est utilisé par des programmes ODBC tels 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êtesSELECT
qui prendront probablement trop de temps. C'est utile lorsqu'une clauseWHERE
déconseillée a été utilisée. Une grosse requête est définie comme étant unSELECT
qui devra probablement étudier plus de max_join_size lignes. La valeur par défaut d'une nouvelle connexion est1
(qui permet toutes les requêtesSELECT
). -
SQL_BUFFER_RESULT
=
{0
|
1
}SQL_BUFFER_RESULT
forcera les résultats des requêtesSELECT
à ê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é 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 deSUPER
. -
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 deSUPER
. -
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 a le privilègeSUPER
. Cette variable est abandonnée depuis la version 5.0.0 et est remplacée par SQL_LOG_BIN (voir Section C.1.7, « Changements de la version 5.0.0 (22 décembre 2003 : Alpha) »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 »13.5.3.5. Syntaxe de SHOW CREATE TABLE. -
SQL_SAFE_UPDATES
=
{0
|
1
}Si défini à
1
, MySQL annulera si unUPDATE
ou unDELETE
sont exécutés alors qu'ils n'utilisent pas de clé ou deLIMIT
dans la clauseWHERE
. 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 unSELECT
possède une clauseLIMIT
, 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 valeurDEFAULT
avec SQL_SELECT_LIMIT. -
SQL_WARNINGS
=
{0
|
1
}Cette variable contrôle le fait que les insertions monolignes
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 vaut0
, aucun test d'unicité n'est fait. Cette variable a été ajoutée en MySQL 3.23.52. Voir Section 15.7.4, « Contraintes de clés étrangères FOREIGN KEY »15.7.4. Contraintes de clés étrangères FOREIGN KEY.
13-5-3. Syntaxe de SHOW▲
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 '_'. Cette 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 Section 13.5.1.5, « Syntaxe de SET PASSWORD »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 :SélectionnezSHOW
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 »13.6. Commandes de réplication.
13-5-3-1. Commande SHOW CHARACTER SET▲
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)
Remarque sur la liste précédente :
-
la colonne Maxlen affiche le nombre maximum d'octets utilisés pour stocker un caractère.
13-5-3-2. Syntaxe de SHOW COLLATION▲
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.
13-5-3-3. Syntaxe de SHOW COLUMNS▲
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és 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 »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 autre syntaxe que 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
. Voir Section 13.3.1, « Syntaxe de DESCRIBE (obtenir des informations sur les colonnes) »13.3.1. Syntaxe de DESCRIBE (obtenir des informations sur les colonnes).
13-5-3-4. Syntaxe de SHOW CREATE DATABASE▲
SHOW
CREATE
DATABASE
db_name
La requête suivante montre une commande CREATE
DATABASE
qui va créer une base de données. 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 */
13-5-3-5. Syntaxe de SHOW CREATE TABLE▲
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 »13.5.2.8. Syntaxe de SET.
13-5-3-6. Syntaxe de SHOW DATABASES▲
SHOW
{DATABASES
|
SCHEMAS
} [LIKE 'pattern']
SHOW
DATABASES
liste les bases de données disponibles 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.
13-5-3-7. Syntaxe SHOW ENGINES▲
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
.
13-5-3-8. Syntaxe de SHOW ERRORS▲
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
. Voir Section 13.1.7, « Syntaxe de SELECT »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 »13.5.3.19. SHOW WARNINGS | ERRORS.
13-5-3-9. SHOW GRANTS▲
SHOW
GRANTS
FOR
user
SHOW
GRANTS
FOR
user
affiche la commande nécessaire pour donner les mêmes 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
. Voir Section 12.8.3, « Fonctions d'informations »12.8.3. Fonctions d'informations.
SHOW
GRANTS
est disponible depuis MySQL 3.23.4.
13-5-3-10. Syntaxe de SHOW INDEX▲
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 exact pour les petites tables. -
Sub_part
Le nombre de caractères indexés 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ées 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 substitut à 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.
13-5-3-11. Syntaxe de SHOW INNODB STATUS▲
SHOW
INNODB STATUS
Cette commande donne des informations exhaustives sur le moteur de stockage InnoDB.
13-5-3-12. Syntaxe de SHOW LOGS▲
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 logs des tables Berkeley DB.
-
File affiche le chemin complet jusqu'au fichier de logs.
-
Type affiche le type de fichier de logs (BDB pour les tables de types Berkeley DB).
-
Status affiche le statut du fichier de logs (FREE si le fichier peut être supprimé, ou
IN
USE
si le fichier est utilisé par une transaction en cours).
13-5-3-13. SHOW PRIVILEGES▲
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 index |
| 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 | Éteindre le serveur |
| 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)
13-5-3-14. Syntaxe de SHOW PROCESSLIST▲
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 vôtres. Voir Section 13.5.4.3, « Syntaxe de KILL »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 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 disponibles 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 multitable, 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 multitable, 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 ferment leurs tables. -
Killed
Quelqu'un a envoyé une commande
KILL
et le thread s'annulera 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
ouLOCK
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. À cause de cela, MySQL doit effectuer une opération de plus pour supprimer toutes les lignes en double, 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és. 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ème 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 rouvrir la table pour obtenir une nouvelle structure. Pour être capable de rouvrir la table, il doit attendre que les autres threads aient fermé la table en question.
Cette annonce survient lorsqu'un 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
ouOPTIMIZE
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és ci-dessus, mais la majorité sont utilisés pour trouver des bogues dans mysqld.
13-5-3-15. Syntaxe de SHOW STATUS▲
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 Voir Section 5.2.4, « Variables de statut du serveur »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
|
+
--------------------+----------+
13-5-3-16. SHOW TABLE STATUS▲
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. Voir Chapitre 14, Moteurs de tables MySQL et types de tableChapitre 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 fixes, c'est le nombre maximal de lignes dans la table. Pour les formats de lignes dynamiques, 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.
13-5-3-17. Syntaxe de SHOW TABLES▲
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 tables. Voir Section 7.4.8, « Quand MySQL ouvre et ferme les tables »7.4.8. Quand MySQL ouvre et ferme les tables. Le champ Comment du résultat indique le nombre d'ouvertures de la table en cache (cached) et le nombre d'utilisations (in_use). OPEN
est disponible depuis MySQL 3.23.33.
13-5-3-18. Syntaxe de SHOW VARIABLES▲
SHOW
[GLOBAL | SESSION]
VARIABLES
[LIKE 'pattern']
SHOW
VARIABLES
affiche les valeurs des variables système 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 »5.2.1. Options de ligne de commande de mysqld et Section 13.5.2.8, « Syntaxe de SET »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 Section 5.2.3, « Variables serveur système »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 »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érifient 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 |
+
--------------------+----------+
13-5-3-19. SHOW WARNINGS | ERRORS▲
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 utilise une table. Cette commande a été implémentée depuis MySQL 4.1.0. Une commande connexe, SHOW
ERRORS
, affiche uniquement les erreurs. Voir Section 13.5.3.8, « Syntaxe de SHOW ERRORS »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
. Voir Section 13.1.7, « Syntaxe de SELECT »13.1.7. Syntaxe de SELECT.
Le serveur MySQL retourne le nombre total d'alertes et d'erreurs que vous avez obtenues lors de la dernière commande. Ils sont disponibles avec la fonction mysql_warning_count(). Voir Section 24.2.3.61, « mysql_warning_count() »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èrent 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>
13-5-4. Autres commandes d'administration▲
13-5-4-1. Syntaxe de CACHE INDEX▲
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és 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és 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és sont accessibles depuis une variable système structurée. Voir Section 9.4.1, « Variables système structurées »9.4.1. Variables système structurées.
Un cache de clés 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és au cache de clés par défaut, créé au moment du démarrage du serveur. Lorsqu'un cache de clés est détruit, tous les index qui lui étaient assignés 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 toutes les requêtes, quel que soit le client qui émet la requête.
CACHE
INDEX
a été ajouté en MySQL 4.1.1.
13-5-4-2. Syntaxe de FLUSH▲
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. Voir Section A.2.5, « Erreur Host '...' is blocked »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 rouvre tous les fichiers de logs. Si vous avez spécifié un fichier de logs de mises à jour, ou un fichier de logs binaire sans extension, le numéro d'extension du fichier de logs sera incrémenté d'une unité. Si vous avez utilisé une extension dans le nom du fichier, MySQL va fermer et rouvrir le même fichier. Voir Section 5.9.3, « Le log de modification »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 toutes 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. À n'utiliser que pour corriger une requête. Voir Section 1.4.1.3, « Comment rapporter un bogue ou un problème »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. Voir Section 5.6.4, « Limiter les ressources utilisateur »5.6.4. Limiter les ressources utilisateur.
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. Voir Section 13.5.4.5, « Syntaxe de la commande RESET »13.5.4.5. Syntaxe de la commande RESET.
13-5-4-3. Syntaxe de KILL▲
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 tous 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éé 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
etGROUP
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'unDELETE
, 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 avecNULL
. -
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.
13-5-4-4. Syntaxe de LOAD INDEX INTO CACHE▲
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és, qui est explicitement nommé 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 nœuds 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.
13-5-4-5. Syntaxe de la commande RESET▲
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
. Voir Section 13.5.4.2, « Syntaxe de FLUSH »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 versions antérieures à la version 3.23.26, cette commande s'appelait
FLUSH
MASTER
(Master). Voir Section 13.6.1, « Requêtes SQL pour contrôler les maîtres de réplication »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êtes.
-
SLAVE
Annule la position de réplication de l'esclave dans les historiques du maître. Dans les versions antérieures à la version 3.23.26, cette commande s'appelait
FLUSH
SLAVE
(Slave). Voir Section 13.6.2, « Commandes SQL de contrôle des esclaves de réplication »13.6.2. Commandes SQL de contrôle des esclaves de réplication.
13-6. Commandes de réplication▲
Cette section décrit les commandes liées à la réplication. Un groupe de commandes peut être utilisé pour contrôler le serveur. L'autre groupe sert avec les esclaves.
13-6-1. Requêtes SQL pour contrôler les maîtres de réplication▲
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 13.6.2, « Commandes SQL de contrôle des esclaves de réplication »13.6.2. Commandes SQL de contrôle des esclaves de réplication présente les commandes pour gérer les esclaves.
13-6-1-1. PURGE MASTER LOGS▲
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 ; -
Faites 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 tous 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.
13-6-1-2. RESET MASTER▲
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.
13-6-1-3. SET SQL_LOG_BIN▲
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.
13-6-1-4. SHOW BINLOG EVENTS▲
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
. Voir Section 13.1.7, « Syntaxe de SELECT »13.1.7. Syntaxe de SELECT.
Cette commande est disponible en MySQL 4.0.
13-6-1-5. SHOW MASTER LOGS▲
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.
13-6-1-6. SHOW MASTER STATUS▲
SHOW
MASTER
STATUS
Affiche les informations d'état du log binaire du maître.
13-6-1-7. SHOW SLAVE HOSTS▲
SHOW
SLAVE
HOSTS
Affiche la liste des esclaves actuellement enregistrée sur le maître. Notez que les esclaves qui ne sont pas lancés avec l'option --report-host=nom_d_esclave ne seront pas visibles dans cette liste.
13-6-2. Commandes SQL de contrôle des esclaves de réplication▲
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 13.6.1, « Requêtes SQL pour contrôler les maîtres de réplication »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.
13-6-2-1. CHANGE MASTER TO▲
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és 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écifiez les mêmes valeurs d'hôte et de port que précédemment. Dans ce cas, les anciennes valeurs et positions 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 étaient 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écifiiez 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, faites une copie des fichiers de logs 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écents, 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ébarrasser de ces petites contraintes.
13-6-2-2. LOAD DATA FROM MASTER▲
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 reprenne à 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. Voir Section 5.2.3, « Variables serveur système »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 »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.
13-6-2-3. Syntaxe de LOAD TABLE tbl_name FROM MASTER▲
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 à charger. Côté 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).
13-6-2-4. MASTER_POS_WAIT()▲
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 12.8.4, « Fonctions diverses »12.8.4. Fonctions diverses pour une description complète.
13-6-2-5. RESET SLAVE▲
RESET
SLAVE
Force l'esclave à oublier toutes 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ée un nouveau log de relais.
Note : tous les logs de relais sont effacés, même s'ils 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.
13-6-2-6. SET GLOBAL SQL_SLAVE_SKIP_COUNTER▲
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.
13-6-2-7. SHOW SLAVE STATUS▲
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 6.3, « Détails d'implémentation de la réplication »6.3. Détails d'implémentation de la réplication. Étudier 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 côté, 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 logs 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 atteinte dans le fichier de logs binaire du maître.
-
Relay_Log_File
Le nom du fichier de logs 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 logs 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ées 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écente requête exécutée. La valeur de 0 signifie « pas d'erreur ». Last_Error est le message d'erreur de la plus récente requête exécutée. Par exemple :
SélectionnezLast_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 commandeSTART
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 indiquent le nom du fichier de logs 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 commandeCHANGE
MASTER
etRESET
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 ont des horloges réglées différemment.Ce champ a été ajouté en MySQL 4.1.1.
13-6-2-8. START SLAVE▲
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 lit les requêtes du maître et les stocke dans le log de relais. Le thread SQL lit le log de relais, et exécute les requêtes. Notez que si START
SLAVE
réussit à 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, seul 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 logs 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éal 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
.
13-6-2-9. STOP SLAVE▲
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.
13-7. Syntaxe SQL pour les commandes préparées▲
Le support des commandes préparées côté 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. Voir Section 24.2.4, « Fonctions C de commandes préparées »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 autre interface pour les commandes préparées est disponible : la syntaxe 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 devez 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 trois commandes SQL :
PREPARE
stmt_name FROM
preparable_stmt;
EXECUTE
stmt_name [USING @var_name [, @var_name]
...];
DEALLOCATE
PREPARE
stmt_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 montrent deux méthodes équivalentes pour préparer les commandes qui calculent l'hypoténuse d'un triangle à partir de la taille de deux de ses côté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 exemple 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 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
.