Amusons-nous avec le PHP
Last updated on Thursday, January 10, 2013
  • Facile

Ce cours est visible gratuitement en ligne.

Got it!

Gérons nos tables !

Dans le chapitre précédent, on a vu comment créer une table simple. Mais je ne vous ai pas montré tous les types de colonnes, et je n'ai encore rien dit sur la gestion de la table après sa création.

Par gestion, j'entends un peu de tout : ajouter une colonne, en supprimer, en modifier, etc. !
Un chapitre très intéressant qui vous permettra de commencer à vraiment manipuler les tables. ;)

Une histoire d'entiers

Il est temps de quitter un peu la pratique pour revenir à la bonne vieille théorie. Comme je vous l'ai dit, il faut toujours utiliser le type de colonnes qui correspond le mieux au type de données que vous y stockerez. C'est pour cela que MySQL met à notre disposition un très grand nombre de types de colonnes, près d'une trentaine. :p

Tout d'abord, je vais vous donner une requête qui ne fonctionne pas mais qui représente tous les types de colonnes et leurs options :

CREATE TABLE nom_table (
nom_colonne type_colonne [NULL | NOT NULL] [DEFAULT valeur_par_defaut] [AUTO_INCREMENT] [[PRIMARY] KEY] [COMMENT 'commentaire']
);

Il y a quelques mots en français, ça devrait donc vous aider. :) Tout d'abord nom_table, c'est bien logiquement le nom de la table que vous allez créer. Ensuite vient nom_colonne : c'est le nom que vous donnerez à une colonne. Après, on a type_colonne, ça indique le type de la colonne ; on verra tous les types possibles par la suite.
Maintenant on commence les choses sérieuses : tout d'abord, les crochets. Quand quelque chose est mis entre crochets, il est facultatif, on peut ne pas le mettre. Et vous le voyez, les crochets peuvent s'imbriquer.
Deuxième chose, la barre verticale(|), alias le pipe. Quand vous avez plusieurs valeurs possibles pour un même élément, on les sépare par une barre verticale.

Après le type de la colonne, on peut trouver soit un NULL, soit un NOT NULL. Je vous ai déjà expliqué en quoi ces mots-clés consistaient, je ne reviens donc pas dessus.

Mais voilà un petit nouveau : DEFAULT. Imaginons que vous fassiez un système de news avec validation des news (c'est-à-dire qu'un administrateur doit autoriser l'affichage de la news pour qu'elle soit visible aux yeux de tous). Pour différencier une news validée d'une news non validée, vous utiliseriez une colonne supplémentaire qui pourrait prendre deux états, validée ou pas (on verra plus tard quel type de colonne correspondait à cette donnée). Seulement, vous devez bien vous rendre compte que la plupart du temps, quand on va ajouter une news, elle ne sera pas validée. La colonne qui contiendra cette information aura donc très souvent la même information quand on insérera la news dans la table. Et je ne sais pas pour vous, mais je trouve ça ennuyeux de devoir toujours dire à MySQL que la news n'est pas validée.

C'est pour cela que MySQL nous permet d'utiliser des valeurs par défaut. Si on ne renseigne pas la valeur d'une colonne qui a une valeur par défaut, MySQL stockera la valeur par défaut, sinon il stockera la valeur qu'on lui donne.
Ça doit vous rappeler quelque chose, non ? Oui ! Les fonctions en PHP : souvenez-vous, on pouvait donner une valeur par défaut à un ou plusieurs paramètres ; eh bien c'est pareil avec MySQL.
Pour reprendre l'exemple de la table du Livre d'or, on aurait pu mettre une valeur par défaut sur une colonne : celle qui stocke la date.

Mais c'est variable la date, non ?

Oui, la date à laquelle le message est posté varie, mais la façon dont on obtient la date ne varie pas (en réalité, on utilise une fonction de MySQL : oui, oui, en SQL aussi il y a des fonctions ^^ ).
Quand vous pouvez utiliser une valeur par défaut, faites-le. Vos requêtes seront plus courtes et plus rapides à exécuter.
valeur_par_défaut est bien entendu à remplacer par la valeur par défaut.

La prochaine option, également facultative et connue, c'est l'auto-incrémentation. Je ne reviens pas non plus là-dessus, mais je vous rappelle quand même qu'on ne peut utiliser l'auto-incrémentation que sur des colonnes de type entier !

Voici ensuite quelque chose qu'on a déjà vu, mais dont je n'ai pas parlé en détail, et je ne le ferai pas maintenant. Pour le moment, retenez juste que vous n'avez pas à utiliser cette option, sauf sur les colonnes qui ont une auto-incrémentation.

Dernier mot-clé : COMMENT. Ce dernier sert à donner un commentaire sur une colonne, sur son rôle. Parfois, les noms des colonnes ne sont pas très explicites (si je nomme ma colonne gbook_ivba, vous ne savez pas à quoi elle sert !), et c'est assez difficile de savoir à quoi sert l'une ou l'autre. Mais si vous mettez un commentaire, ça sera un jeu d'enfant :) (mais bon, le mieux c'est de donner des noms explicites :p ).

Voilà pour le gros de la requête, on va maintenant passer à quelque chose de tout aussi intéressant : les types de colonnes !

Commençons en douceur par les colonnes de types entiers. Eh oui, il y a plusieurs types de colonnes pour stocker des nombres entiers, cinq exactement : TINYINT, SMALLINT, MEDIUMINT, INT et BIGINT.
Si vous parlez un peu anglais, vous pouvez traduire le nom des différents types : très petit entier, petit entier, moyen entier, entier et grand entier.
Si je vous dis que stocker le nombre 200 prend beaucoup moins de place que de stocker le nombre 2 000 000 000, vous êtes d'accord ?

MySQL lui l'est. Si vous ne lui dites pas que vous stockez un petit nombre, MySQL va devoir lire plus d'informations pour s'assurer qu'il lit bien tout le nombre, qu'il n'en oublie pas un morceau. Et donc, si le nombre est petit, MySQL va lire des données pour rien, ce qui est une perte de temps. C'est pourquoi MySQL nous permet de spécifier la grandeur du nombre grâce à ces cinq types. Plus exactement, ces types permettent de stocker un nombre compris dans un intervalle (en gros, le nombre qu'on veut stocker doit être compris entre un nombre plus petit et un nombre plus grand ; on appelle ces deux nombres limites les bornes).
Voici les intervalles :

Type de colonne

Intervalle

TINYINT

de - 128 à + 127

SMALLINT

de - 32 768 à + 32 767

MEDIUMINT

de - 8 388 808 à + 8 388 807

INT

de - 2 147 483 648 à + 2 147 483 647

BIGINT

de - 9 223 372 036 854 775 808 à + 9 223 372 036 854 775 807

Comme vous pouvez le constater, les intervalles sont plutôt variés et certains sont vraiment énormes. Quand vous stockerez un nombre, vous devrez toujours vous poser la question : « Quelle est la valeur maximale que je pourrais stocker ? ».
Il y a des cas où c'est très simple, par exemple dans le cas d'une colonne servant à stocker un pourcentage de réussite. La limite étant 100 %, la valeur maximale est 100. Le type de colonne le plus adapté est donc TINYINT.
Malheureusement, il n'est pas toujours aisé de trouver cette valeur maximale, par exemple pour l'id des messages de votre livre d'or. Combien y en aura-t-il ? 100 ? 1 000 ? 10 000 ?
Dans ce genre de cas, n'hésitez pas à utiliser le type INT (quand vous aurez plus de deux milliards de messages, vous m'appellerez ^^ ) qui suffit amplement dans la plupart des cas.

Vous connaissez donc cinq types de colonnes, eh bien je dois vous avouer quelque chose : vous en connaissez en réalité dix, le double !
Pourquoi ? À cause de l'UNSIGNED. Je vous ai parlé de la différence entre le type INT et INT UNSIGNED dans le chapitre précédent : c'est pareil pour ces cinq types, on peut les mettre en UNSIGNED.
Et en réalité, la seule chose qui change entre un entier et un entier UNSIGNED, ce sont les bornes de l'intervalle. La borne inférieure est 0 (le plus petit nombre entier positif), et la borne supérieure est...

Type de colonne

Intervalle

TINYINT UNSIGNED

de 0 à 255

SMALLINT UNSIGNED

de 0 à 65 535

MEDIUMINT UNSIGNED

de 0 à 16 777 615

INT UNSIGNED

de 0 à 4 294 967 295

BIGINT UNSIGNED

de 0 à 18 446 744 073 709 551 615

Si vous avez fait attention aux bornes supérieures, vous aurez peut-être remarqué trois choses.

Premièrement, les bornes supérieures sont égales à deux fois la borne supérieure des colonnes correspondantes sans leUNSIGNEDplus 1. Par exemple pour le TINYINT, la borne supérieure était 127. Avec la formule, on a comme borne supérieure pour le TINYINT UNSIGNED : (2*127)+1 = 254+1.
La seconde, c'est que la borne supérieure est également égale à une certaine puissance de 2 moins 1 (pour ceux qui ne savent pas encore ce que sont les puissances, 2 puissance 3 est égal à 2*2*2, 2 puissance 7 est égal à 2*2*2*2*2*2*2). Pour le TINYINT UNSIGNED, la borne supérieure est égale à 255 = 256-1 = (2^16)-1.
La troisième chose, c'est que la borne supérieure est égale à la somme des valeurs absolues des deux bornes du type de colonne correspondant sans leUNSIGNED (pour ceux qui ne savent pas encore ce qu'est la valeur absolue, la valeur absolue de -3 est égale à 3, la valeur absolue de -4 est égale à 4, la valeur absolue de 5 est égale à 5). Pour le TINYINT UNSIGNED, la borne supérieure est égale à 255 = |-128|+|127| = 128+127.

Mine de rien, c'est déjà pas mal. :)

Mais si on avance bien, on n'en a pas encore tout à fait fini avec ces entiers. En plus d'avoir cinq types de colonnes, on peut en plus préciser le nombre de chiffres que le nombre qu'on veut stocker peut comporter. Relisez cette phrase une ou deux fois. :p
Juste au cas où, je fais un petit écart pour rappeler la différence entre un chiffre et un nombre. Un chiffre est un symbole qui permet de représenter une valeur numérique. Dans le système décimal, il n'y a que dix chiffres : 0, 1, 2, 3, 4, 5, 6, 7, 8, 9.
Un nombre est un concept qui représente une unité, une collection d'unités ou une fraction d'unité. 65 est un nombre, par exemple.
Un nombre est écrit avec des chiffres, mais un chiffre n'est pas écrit avec des nombres.

Donc, revenons à nos colonnes. Je vous ai dit qu'on peut indiquer à MySQL le nombre de chiffres qui composent un nombre. Vous comprendrez l'intérêt dans quelques lignes : voici comment indiquer le nombre de chiffres qui composent un nombre.

nom_col SMALLINT UNSIGNED

On va mettre :

nom_col SMALLINT(3) UNSIGNED

Si vous tentez de stocker le nombre 9999, c'est ce nombre qui sera stocké. Mais alors, quel intérêt ?

L'intérêt, c'est le ZEROFILL. Imaginons que vous vouliez insérer des nombres avec des zéros devant, 004 par exemple. Si vous utilisez ce que je vous ai appris jusqu'à maintenant, vous n'arriverez jamais à récupérer autre chose que 4 bien que vous tentiez de stocker 004.
Pour arriver à faire cela, MySQL a prévu une autre option, le ZEROFILL. Si vous utilisez le ZEROFILL, MySQL ajoutera des 0 devant le nombre jusqu'à obtenir le nombre de chiffres qui peuvent composer les nombres stockés dans la colonne. Par exemple, je veux stocker le nombre 0004.
Si je fais cette colonne :

nom_col SMALLINT

je ne récupérerai jamais rien d'autre que 4.
Avec le ZEROFILL, ça ira mieux :

nom_col SMALLINT ZEROFILL

Aucun souci, j'aurai mon 0004, mais en fait, j'aurai mieux : 000004. Oui, le nombre de chiffres que peut contenir un SMALLINT est six, MySQL rajoute donc cinq zéros.
Pour obtenir mon 0004, je devrai faire ceci :

nom_col SMALLINT(4) ZEROFILL

Et magie, voilà le 0004 grâce à ce qu'on a vu un peu plus tôt.
Vous pouvez bien sûr utiliser ça avec les UNSIGNED :

nom_col SMALLINT(4) UNSIGNED ZEROFILL

Là je vous invite sérieusement à faire une pause parce que mine de rien, vous venez de voir plusieurs notions.

Des types en pagaille

Bon, si vous êtes frais et dispos, on va pouvoir passer à tous les autres types, et il en reste !

Le prochain est encore un type qu'on utilise pour stocker des nombres, mais cette fois, c'est pour stocker des nombres à virgule. Voici comment créer une colonne de ce type :

nom_col DECIMAL(5,2) [UNSIGNED] [ZEROFILL]

Comme vous le voyez, j'ai mis le UNSIGNED et le ZEROFILL entre crochets, ils sont facultatifs et je n'expliquerai pas leur rôle puisque c'est du déjà vu.
La seule nouveauté, c'est DECIMAL(5,2).
Pour les nombres entiers, on pouvait dire à MySQL combien de chiffres au maximum on voulait stocker dans une colonne ; on peut faire pareil avec les décimaux. Mais en plus de cela, on peut également indiquer à MySQL combien de chiffres après la virgule on veut garder.
Dans mon exemple, je crée une colonne de type DECIMAL qui peut contenir des nombres à cinq chiffres, avec deux chiffres après la virgule.
Ainsi, si je tente de stocker 999999.99999, MySQL stockera 999.99. Si je tente de stocker 55.5555555, MySQL stockera 55.56 (quand MySQL tronque un nombre, il l'arrondit au passage).

À présent, passons à autre chose avec des colonnes qui nous permettront de stocker des dates, des heures, etc.

On a déjà vu un type de colonne pour stocker une date, le type DATETIME. Il permet de stocker des dates avec ce format : AAAA-MM-JJ HH:MM:SS. Ce n'est pas un format français, c'est un format anglais (là-bas on indique l'année, puis le mois, puis le jour, puis les heures, puis les minutes, puis les secondes) mais ne vous en faites pas, on verra comment changer ce format.
Il existe d'autres types de colonnes pour les dates. Imaginons que vous n'ayez besoin que de l'année, du mois et du jour. Ça serait assez inutile de stocker l'heure puisqu'elle n'est pas souhaitée. On va donc utiliser un autre type, DATE. Ce type de colonnes permet de stocker une date au format AAAA-JJ-MM.
Il existe encore d'autres types de colonnes, le type TIMESTAMP par exemple. C'est un type assez proche du type DATETIME mais quelques différences subsistent.

Tout comme avec les nombres, les dates que vous pouvez stocker sont limitées par deux bornes. Pour une colonne de type DATETIME, vous pouvez stocker des dates comprises entre 1000-01-01 00:00:00 et 9999-12-31 23:59:59, donc de minuit le 1 janvier de l'an 1000 à 23 heures 59 minutes 59 secondes le 31 décembre 9999, on a de la marge. :p
Pour le type DATE, vous pouvez stocker des dates comprises entre 1000-01-01 et 9999-12-31, et pour le type TIMESTAMP, ça va du 1er janvier 1970 jusqu'à approximativement l'année 2037.

Passons maintenant au quatrième type de colonne temporelle, le type TIME. Ce type peut poser des problèmes de compréhension si on ne fait pas attention, on va voir pourquoi.
On a vu le type DATE et le type DATETIME, on a vu que le type DATE est une partie du type DATETIME, on peut donc supposer que TIME est la partie manquante.
Et ce n'est pas faux, mais c'est incomplet. En plus de permettre de stocker une heure au format HH:MM:SS, le type TIME convient parfaitement pour stocker une durée, par exemple, 106 heures 23 minutes 43 secondes.
Imaginons que vous fassiez une table destinée à des durées de la traversée de la France à cheval (c'est un exemple ^^ ), vous aurez peut-être 36 heures 20 minutes, mais vous pouvez aussi avoir 300 heures 56 minutes 06 secondes. Pour stocker cette information, le meilleur type de colonne est TIME.
Mais ce n'est pas tout ! On peut également stocker une durée négative. Je n'ai pas d'exemple d'utilisation sous la main, mais c'est pas grave.
Vous pouvez stocker des durées / heures comprises entre -838:59:59 et 838:59:59, donc de -838 heures 59 minutes 59 secondes à 838 heures 59 minutes 59 secondes.

Finissons-en avec les dates avec le cinquième et dernier type de colonne temporelle, le type YEAR. Ce type de colonne permet de stocker des dates au format YYYY entre 1901 et 2155 (mais ne me demandez pas pourquoi :-° ).

Sans plus attendre, parlons des colonnes servant à stocker des chaînes de caractères. On a déjà vu un de ces types : le VARCHAR. Cette colonne sert à stocker des chaînes avec au maximum 255 caractères, mais on a vu qu'on pouvait diminuer cette limite. Par exemple, si au lieu de 255 caractères :

nom_col VARCHAR(255)

je n'en veux que 108 :

nom_col VARCHAR(108)

Il existe un autre type très proche du VARCHAR, le type CHAR. Pour vous, les deux types sont strictement identiques (il faut aussi spécifier le nombre maximal de caractères qu'on pourra y stocker, la limite maximale étant 255), la seule différence réside dans la façon dont MySQL les stockent. Je vous conseille d'utiliser le VARCHAR, il est en général plus économe en terme de place sur le disque dur (le seul cas où il est plus lourd, c'est quand vous stockez des chaînes qui ont le nombre maximal de caractères autorisés : donc, si vous êtes certains que la majorité des données de la colonne aura le nombre maximal de caractères autorisés, utiliser un CHAR est plus économe).

Après les textes courts, on va passer aux textes plus longs avec le type TEXT et ses trois frères. Pourquoi trois frères ? C'est tout simplement que le type TEXT, tout comme le type INT, possède plusieurs types identiques, la seule différence étant le nombre maximal de caractères qu'on pourra y stocker. Ces trois frères sont : TINYTEXT, MEDIUMTEXT et LONGTEXT.
Pour créer ce genre de colonnes, c'est encore et toujours très simple : vous n'avez même pas à indiquer de limite pour le nombre de caractères comme on devait le faire pour le VARCHAR. Voici quatre colonnes :

nom_col_1 TINYTEXT,
nom_col_2 TEXT,
nom_col_3 MEDIUMTEXT,
nom_col_4 LONGTEXT

Et voici un tableau reprenant la limite de caractères :

Type de colonne

Nombre maximal de caractères

TINYTEXT

256

TEXT

65 536

MEDIUMTEXT

16 777 216

LONGTEXT

4 294 967 296

Vous l'avez peut-être remarqué, encore une fois, les limites sont des puissances de 2 (2^8, 2^16, 2^24 et 2^32). En fait il y a énormément de mathématiques qui se cachent derrière les bases de données, mais ce n'est pas le sujet. ^^

Le type suivant est un peu particulier, il sert à stocker tout ce que l'on veut sous forme binaire. Vous pourriez par exemple l'utiliser pour stocker une image, mais en pratique, on ne le fera pas. Je ne vous montrerai sans doute aucun exemple dans lequel ce type de colonnes sera nécessaire. Ce type si particulier est BLOB. Et tout comme le type TEXT, il a trois frères : TINYBLOB, MEDIUMBLOB et LONGBLOB.
Là encore, pas besoin de spécifier une taille :

nom_col_1 TINYBLOB,
nom_col_2 BLOB,
nom_col_3 MEDIUMBLOB,
nom_col_4 LONGBLOB

La limite de caractères de ces colonnes est la même que leur équivalent en TEXT.

Courage, il n'y a plus que deux types ! :)

Le type qui nous intéresse maintenant va permettre d'insérer des données qui appartiennent à une liste. Reprenons l'exemple de la news validée ou non, les deux seules données possibles sont validée et non validée. Avec ce type, si on tente d'insérer une autre donnée qu'une de ces deux-là, MySQL stockera une chaîne vide. Ce type si particulier est ENUM.
Pour créer une colonne de ce type, voici comment il faut faire :

nom_col ENUM('valeur_1', 'valeur_2')

Vous pouvez mettre 65 535 (= (2^16)-1, quand je vous disais que les mathématiques sont partout) éléments possibles dans un ENUM. Et le -1 dans (2^16)-1 s'explique tout simplement par le fait que si vous tentez de stocker une valeur non-autorisée, MySQL stockera une chaîne vide (en gros, si vous spécifiez trois valeurs possibles, ça revient à en spécifier quatre car MySQL peut stocker une chaîne vide). En conséquence de ça, il est bien sûr totalement inutile de permettre de stocker une chaîne vide, vu que MySQL le fait déjà quand il faut.

Le dernier type, SET, est un peu plus complexe que les autres, je n'en parlerai donc pas. Et de toute façon, il est assez rare qu'on s'en serve.

Petit cadeau, une liste de tous les types de colonnes avec leurs options !

  • TINYINT[(nombre_de_chiffres)] [UNSIGNED] [ZEROFILL]

  • SMALLINT[(nombre_de_chiffres)] [UNSIGNED] [ZEROFILL]

  • MEDIUMINT[(nombre_de_chiffres)] [UNSIGNED] [ZEROFILL]

  • INT[(nombre_de_chiffres)] [UNSIGNED] [ZEROFILL]

  • INTEGER[(nombre_de_chiffres)] [UNSIGNED] [ZEROFILL]

  • BIGINT[(nombre_de_chiffres)] [UNSIGNED] [ZEROFILL]

  • DECIMAL(nombre_de_chiffres, nombre_de_chiffres_après_la_virgule) [UNSIGNED] [ZEROFILL]

  • DATE

  • TIME

  • TIMESTAMP

  • DATETIME

  • CHAR(nombre_de_caractères)

  • VARCHAR(nombre_de_caractères)

  • TINYBLOB

  • BLOB

  • MEDIUMBLOB

  • LONGBLOB

  • TINYTEXT

  • TEXT

  • MEDIUMTEXT

  • LONGTEXT

  • ENUM('valeur_1', 'valeur_2', 'valeur_3', ...)

Avec tout ça, celui qui ose choisir un mauvais type de colonne, je le mords. :-°

Et la gestion ?

C'est bien joli tout ça, mais maintenant, on va mettre en pratique toute cette théorie pour gérer un peu nos tables. Pour le moment, vous savez créer une table, mais une fois créée, c'est fini, vous êtes cuits.

La première chose qu'on va faire, c'est apprendre à supprimer une table.

Supprimer une table relève du jeu d'enfant quand on sait supprimer une base de données ; on avait :

DROP DATABASE nom_base;

Et maintenant on a :

DROP TABLE nom_table;

Testons donc ceci. On va d'abord créer une table, puis la supprimer. Et on affichera la liste des tables à chaque fois pour voir ce qui se passe.

USE dev_dev;
SHOW TABLES;
CREATE TABLE test (test TEXT);
SHOW TABLES;
DROP TABLE test;
SHOW TABLES;

En regardant attentivement ce que nous renvoie le SHOW TABLES;, on voit bien que la table est créée puis supprimée.

Après la suppression d'une table, on va voir comment modifier une table. Je vais vous apprendre à faire quatre choses : supprimer une colonne, ajouter une colonne, changer une colonne et enfin changer le type d'une colonne.

Bon, fini le blabla, on va commencer à jouer. On va travailler sur la table dev_gbook que je vous ai fait créer dans le chapitre précédent. En réalité, j'y ai volontairement glissé une petite erreur. Je vous avais dit qu'on transformerait l'IP en entier grâce à une fonction PHP, seulement, cette fonction peut retourner un nombre négatif. Or, la colonne qui stockera l'IP, gbook_ip, est de type INT UNSIGNED. On ne peut donc pas y stocker de nombre négatif. On va donc faire joujou avec cette colonne pour illustrer la gestion d'une table.

On va commencer par quelque chose d'assez simple, on va supprimer cette colonne.
Voici une requête générique pour supprimer une colonne quelconque :

ALTER TABLE nom_table DROP COLUMN nom_col;

Si je l'applique à l'exemple qui nous intéresse, ça donne :

ALTER TABLE dev_gbook DROP COLUMN gbook_ip;

Testez cette requête et faites un :

SHOW COLUMNS FROM dev_gbook;

Vous voyez que la colonne gbook_ip a bien été supprimée. :)

Maintenant qu'on a supprimé cette colonne, on a un gros problème : on ne peut plus stocker l'IP de la personne qui a posté le message. On va donc recréer cette colonne.
Créer une colonne est assez simple en soi pour autant qu'on sache manipuler les types de colonnes (vous avez intérêt à le savoir après tout ce blabla là-dessus ^^ ) et leurs options.
Voici la requête générique qui ajoute une colonne :

ALTER TABLE nom_table ADD COLUMN nom_col type_col [NULL | NOT NULL] [DEFAULT valeur_par_defaut] [AUTO_INCREMENT] [[PRIMARY] KEY] [COMMENT 'commentaire'] [FIRST | AFTER nom_col_prec];

Ça fait peur, mais on a déjà vu une grande partie de ce monstre ; d'ailleurs, je vais enlever les éléments qu'on a déjà vus pour simplifier tout ça. Je vais remplacer tout ceci par option_col :

[NULL | NOT NULL] [DEFAULT valeur_par_defaut] [AUTO_INCREMENT] [[PRIMARY] KEY] [COMMENT 'commentaire'];

Ce qui me donne :

ALTER TABLE nom_table ADD COLUMN nom_col type_col option_col [FIRST | AFTER nom_col_prec];

Mais on va présenter ça autrement pour que ça soit plus agréable :

ALTER TABLE nom_table
ADD COLUMN nom_col type_col option_col
[FIRST | AFTER nom_col_prec];

Je vous ai dit qu'en PHP, il était de mise de ne mettre qu'une seule instruction par ligne. En SQL, il arrive qu'on ait des requêtes tout simplement monstrueuses avec des tonnes de trucs. Dans ce genre de cas, tout taper sur une ligne est assez rédhibitoire, et ça rend la requête difficile à lire.
C'est pour ça que j'ai pris l'habitude de mettre des retours à la ligne et des indentations même dans mes requêtes.
Je ne sais pas pour vous, mais je préfère de loin ma dernière requête à la précédente, elle est bien plus aérée et agréable à lire. Et bien entendu, ces trois lignes ne forment qu'une et une seule requête, étant donné qu'il n'y a qu'un point-virgule (qui sert, je vous le rappelle, à marquer la fin d'une requête).
Au fil du temps, vous commencerez à sentir quand il faut mettre des retours à la ligne ou des indentations sans même regarder votre requête.

Bref, on en était à la création d'une colonne. L'ALTER TABLE nom_table ne vous est pas inconnu, ça indique qu'on modifie (alter) une table (table).
Les mots-clés ADD COLUMN (ajouter colonne en français) indiquent qu'on veut ajouter une colonne. nom_col est le nom de la future colonne, type_col est son type et option_col représente les options (NULL, NOT NULL, etc.).

La nouveauté, c'est ce qu'il y a entre les crochets de la troisième ligne. Imaginons que vous soyez chargés d'organiser l'implantation des produits dans un rayon d'un super-marché : comment allez-vous savoir où placer les salades par rapport aux fruits, les fruits par rapport aux chocolats, etc. ?
On va devoir vous le dire, vous donner un ordre à respecter. Pour les colonnes d'une table, c'est pareil. On les crée dans un ordre particulier (l'ordre dans lequel on les définit quand on crée la table), et cet ordre ne change pas. Si on veut ajouter une colonne, il faut dire à MySQL où ranger cette colonne.
C'est à ça que sert ce qu'il y a entre ces crochets. Mais comme vous le voyez, c'est entre crochets, ça veut donc dire que c'est facultatif. En effet, reprenons l'exemple des rayons, on pourrait dire à la personne qui range : si tu ne sais pas où ça va, mets-le à la fin du rayon.
Eh bien c'est pareil avec MySQL : si vous ne lui dites pas où ranger cette nouvelle colonne, il la mettra à la suite des autres, à la fin, en dernière position.

Maintenant, regardons les deux possibilités qui se cachent dans ses crochets : on a deux mots-clés. Le premier est FIRST : si vous mettez ce mot-clé, MySQL ira mettre cette colonne en première position, ce qui est assez logique si on sait qu'en français, FIRST veut dire premier.
Maintenant on a le mot-clé AFTER, qui veut dire après en français. Pour positionner notre colonne par rapport aux autres, on va utiliser les colonnes déjà existantes. On va par exemple lui dire de rajouter la colonne après la colonne x ou y. nom_col_prec est le nom de la colonne qui sera utilisée comme repère.

Reprenons l'exemple de la table dev_gbook, on va recréer la colonne gbook_ip à la même place qu'elle occupait avant qu'on la supprime, c'est-à-dire après la colonne gbook_id et avant la colonne gbook_msg.
On devra donc utiliser le mot-clé AFTER, et la colonne gbook_id sera le repère puisque c'est après cette colonne qu'on veut placer la nouvelle.

Le type de la nouvelle colonne sera INT(10). Et zoup, mini-TP, à vous de créer cette requête. Voici ce que vous devez obtenir :

ALTER TABLE dev_gbook
ADD COLUMN gbook_ip INT(10) 
AFTER gbook_id;

Avec un SHOW COLUMNS FROM dev_gbook;, vous pourrez vérifier si la colonne a bien été créée et si elle est au bon endroit.

Maintenant que notre colonne n'est plus en UNSIGNED, tout va bien. Mais manque de chance, je suis vraiment maladroit et j'ai totalement oublié de dire à MySQL que la colonne ne peut pas contenir de NULL.
Mais c'est très bien en fait, je vais vous montrer comment changer le type d'une colonne. :p

Voici la requête générique :

ALTER TABLE nom_table
MODIFY COLUMN nom_col type_col option_col
[FIRST | AFTER nom_col_prec]

Cette requête ressemble énormément à la requête qui ajoute une colonne, et c'est assez normal. La seule différence est que ADD COLUMN est remplacé par MODIFY COLUMN (modifier colonne en français).
Maintenant, à vous de jouer, vous allez modifier la colonne gbook_ip (pour le moment de type INT(10) et qui a l'option NULL) pour lui donner le type INT(10) et l'option NOT NULL. C'est relativement simple si vous avez compris ce que j'ai dit, mais c'est toujours intéressant d'essayer par soi-même.

ALTER TABLE dev_gbook
MODIFY COLUMN gbook_ip INT(10) NOT NULL
AFTER gbook_id;

Affichez à nouveau la liste des colonnes, et on voit bien que la colonne gbook_ip ne peut plus stocker de NULL.

Courage, plus qu'une seule sorte de requête et c'est fini. :)

C'est à peu près la même chose que la requête précédente, sauf que là on peut également changer le nom de la colonne. Voici la requête générique :

ALTER TABLE nom_table
CHANGE COLUMN nom_col nom_col_nouveau type_col option_col
[FIRST | AFTER nom_col_prec]

Il n'y a que deux différences avec la requête précédente, la première étant le CHANGE COLUMN à la place de MODIFY COLUMN.
La seconde, c'est l'apparition de nom_col_nouveau entre le nom de colonne qu'on traite, le nouveau type et les nouvelles options. nom_col_nouveau est le nom qu'aura la nouvelle colonne (si le nouveau nom est le même que l'ancien, ça revient à utiliser MODIFY COLUMN). Le CHANGE COLUMN permet de renommer simplement une colonne.

On va prendre un exemple inutile : on va transformer la colonne gbook_ip en une nouvelle colonne qui aura le même nom, le même type et les mêmes options. À vous de jouer !

ALTER TABLE dev_gbook
CHANGE COLUMN gbook_ip gbook_ip INT(10) NOT NULL
AFTER gbook_id;

Mais tant qu'on en est à parler de renommage, je vais prendre deux ou trois lignes pour vous montrer comment on peut renommer une table (ça peut servir). La requête générique :

ALTER TABLE nom_table
RENAME TO nom_nouvelle_table

Et un exemple pour créer une table dev_test, la renommer en dev_trash et enfin la supprimer :

SHOW TABLES;
CREATE TABLE dev_test (test TEXT);
SHOW TABLES;
ALTER TABLE dev_test
RENAME TO dev_trash;
SHOW TABLES;
DROP TABLE dev_trash;
SHOW TABLES;

Et voilà, on en a vraiment fini avec la gestion des tables (enfin, pour le moment du moins...) ! :)

Alors, qu'en dites-vous ? :p
Ça commence à devenir intéressant ; dès que je vous aurai appris à insérer des données, les mettre à jour, les supprimer et les sélectionner, on parlera d'un couple qui a du chien : le PHP et MySQL.
Et une fois que vous serez capables d'utiliser ces deux tourtereaux ensemble, on passera aux choses sérieuses avec MySQL. :D

Example of certificate of achievement
Example of certificate of achievement