Académique Documents
Professionnel Documents
Culture Documents
www.openclassrooms.com
2/17
Sommaire
Sommaire ........................................................................................................................................... 2
Lire aussi ............................................................................................................................................ 1
Choisir les bons types de colonne SQL ............................................................................................. 3
Comment choisir ? ............................................................................................................................................................ 3
Les formats numriques .................................................................................................................................................... 4
Pourquoi prfrer les types numriques aux textuels ? ..............................................................................................................................................
Comment choisir le bon INT ? .....................................................................................................................................................................................
Le nombre virgule ....................................................................................................................................................................................................
Les attributs des types numriques ............................................................................................................................................................................
Prcision de calcul ......................................................................................................................................................................................................
4
5
5
5
7
Rcapitulons .................................................................................................................................................................... 12
id SMALLINT(4) au lieu de INT(4) .............................................................................................................................................................................
pseudo VARCHAR(40) au lieu de TEXT ...................................................................................................................................................................
date DATE au lieu de VARCHAR(10) ........................................................................................................................................................................
design_choisi SET au lieu de VARCHAR(16) ...........................................................................................................................................................
telephone INT(10) au lieu de VARCHAR(10) ............................................................................................................................................................
13
13
13
13
13
Q.C.M. ............................................................................................................................................................................. 14
Partager ..................................................................................................................................................................................................................... 16
www.openclassrooms.com
Sommaire
3/17
Par
Kyle Katarn
Alors ce tuto est pour vous, vous tes sur le point de diviser par 2 la taille des donnes stockes dans votre BDD.
Dans ce tutoriel, je parlerai des bases de donnes MySQL (je me base sur la version que je connais le mieux, la 5.0). Si
vous ne connaissez pas votre configuration SQL, alors vous avez certainement celle-l, elle est trs rpandue. Et dans
le cas o vous auriez une base diffrente, vous devriez trouver dans votre documentation des types quivalents pour
les rares colonnes dont je pourrais parler et qui ne seraient pas dans votre liste.
Ce tutoriel sera compos de deux types de parties. Lorsque vous voyez droite le logo
vert ci-contre, vous tes dans une partie principale, aucune connaissance outre les bases
en SQL n'est ncessaire. En suivant toutes les parties vertes, vous pourrez dj
grandement optimiser vos tables.
Les parties arborant un logo orange permettent d'approfondir. Si vous tes curieux, si
vous voulez savoir le pourquoi du comment, lisez-les. Et n'oubliez pas qu'en comprenant
MySQL en profondeur, vous serez d'autant plus efficace dans la pratique et pourrez
vraiment choisir vos structures en connaissance de cause. Notez que ces parties vous
demanderont quelques notions de mathmatique, de binaire ou d'informatique. Si vous dbutez ou que vous souhaitez aller
l'essentiel, vous pouvez sauter ces parties et descendre jusqu'au logo vert suivant.
Sommaire du tutoriel :
Comment choisir ?
Les formats numriques
Date et Heure
Colonnes choix multiples
Colonnes de texte
Les rgles retenir
Rcapitulons
Q.C.M.
Comment choisir ?
Commenons par un exemple de table mal optimise (cre avec phpMyAdmin) :
www.openclassrooms.com
4/17
Et ensuite, je regarde le poids de cette ligne ("Espace utilis" dans phpMyAdmin) : 52 octets.
Essayons maintenant avec cette configuration :
Les donnes restent exactement les mmes sauf que le poids, lui, passe 28 octets.
Bref sur une table aussi simple que celle-l contenant 1000 lignes, on peut conomiser 23 Ko !
Optimiser ses structures de table SQL consiste choisir les formats les plus petits possibles pour stocker ses donnes.
En gros, c'est comme si vous deviez envoyer 1000 personnes :
un courrier
un outil
un mp3
Et que vous deviez commander vos enveloppes et cartons en lots.
Si vous n'envoyez que des petits courriers vous prenez un lot de 1000 petites enveloppes, pas des enveloppes A3, vous allez
perdre des sous.
L'outil peut tre gros, il vous faut un carton extensible
Et les mp3, c'est fragile, si vous ne mettez pas de papier-bulle, ils vont se casser.
En SQL, il faut aussi adapter le conteneur au contenu. Voyons maintenant les formats disponibles.
www.openclassrooms.com
5/17
Parce qu'au final, tout sera enregistr en binaire dans des petits octets.
Un octet peut prendre 256 formes. Pour une valeur numrique, a revient pouvoir stocker un nombre entre 0 et 255, et pour un
texte, c'est une lettre ou un symbole ou un chiffre. Ce qui implique que si vous prenez un type texte limit 1 octet pour stocker
un nombre, vous irez de 0 9 et c'est tout ! On est loin des 255.
Poids en octets
Minimum
Maximum
TINYINT
-128
127
SMALLINT
-32 768
32 767
MEDIUMINT 3
-8 388 608
8 388 607
INT
BIGINT
-9 223 372 036 854 775 808 9 223 372 036 854 775 807
Il faut donc choisir le type dont les bornes encadrent vos nombres au plus prs.
Le nombre virgule
Pour les nombres virgule, c'est moins compliqu, vous avez FLOAT (occupe 4 octets) et DOUBLE (8 octets).
La seule chose qui diffrencie les deux types, c'est la prcision :
Supposons qu'on veuille stocker : 3.1415926535897931159979634685441851615905761718753236...
En DOUBLE, on a : 3.141592653589793115997963468544185161590576171875
En FLOAT, on a : 3.1415926535897931159979634685442
Vous pouvez voir que DOUBLE est plus prcis que FLOAT mais qu'aucun des deux types ne permet de stocker une prcision
infinie. Le stockage binaire est dit discret. Ce qui signifie qu'au del d'une prcision donne, les valeurs et calculs de nombres
virgule ne sont que des approximations.
Le stockage des nombres flottants se fait en deux parties, l'une est appele
mantisse et l'autre exposant . Le nombre est le rsultat de mantisse x 2 exposant .
La mantisse et l'exposant sont des nombre entiers convertis en binaires. Par
exemple, on peut stocker 1,25 de la faon suivante : 5x2 -2 . Avec FLOAT, la
mantisse est code sur 24 bits et l'exposant sur 8, avec DOUBLE, ils sont cods respectivement sur 53 bits et 11 bits.
Enfin, il y a DECIMAL, c'est un type pour des nombres entiers ou virgule de prcision
exacte dont on peut dfinir les limites. Par exemple DECIMAL(5,3) autorise au maximum 5
chiffres dont 3 sont situs aprs la virgule (exemple 12,345). Ce type est un peu moins
optimis que les prcdents puisqu'il occupe M+2 octets si D>0 et M+1 octets si D=0
avec M et D les paramtres de DECIMAL : DECIMAL(M,D). Donc avec notre exemple DECIMAL(5,3) D=3 et M=5 ; la colonne
occupe alors 5+2=7 octets. Notez qu'un nombre entier ou virgule prend autant de place dans un VARCHAR que dans un type
DECIMAL. Il est plus que probable que DECIMAL convertisse les nombres en chanes de caractres pour les stocker la
diffrence que l'utilisation de DECIMAL vous garantit qu'il n'y aura que des nombres dans la colonne.
Rappel : MEDIUMINT occupe seulement 3 octets et peut y stocker 5 chiffres sans problme. Pour stocker un nombre
dcimal du type 12,345 vous pouvez le multiplier par 1000 et l'enregistrer dans un MEDIUMINT puis le diviser par 1000
lorsque vous le rcuprer, vous conomisez ainsi 4 octets.
www.openclassrooms.com
6/17
Poids en octets
Maximum
TINYINT
255
SMALLINT
65 535
MEDIUMINT 3
16 777 215
INT
BIGINT
00101110
11010010
Vous constatez que les 7 derniers bits sont les mmes dans les trois dernires lignes et que -46 ainsi que 210 (256-46) s'crivent
de la mme faon dans un octet. Et le premier octet suit cette rgle :
De -128 -1 : 1
De 0 127 : 0
De 128 255 : 1
Donc si le premier bit est gal 0, SQL convertit simplement ce nombre en dcimal.
S'il est gal 1 :
il renvoie un nombre ngatif de valeur gale 128 moins les 7 autres bits convertis en dcimal.
Sauf si l'on active l'attribut UNSIGNED, l il convertit les 8 bits en dcimal.
Donc en librant le bit qui s'occupe du signe, on multiplie par deux la capacit de stockage pour la valeur absolue du nombre.
Peut importe le nombre de bits total utilis, il n'y a jamais besoin que d'un seul bit pour coder le signe. On peut donc obtenir le
nombre maximal stockable dans un type de colonne en fonction de la taille de stockage en octets (note n) comme a :
Sans attribut : 2(n*8)-1 -1
Avec UNSIGNED : 2(n*8)-1
Et le deuxime attribut qui s'avre utile moins souvent mais quelques fois tout de mme :
ZEROFILL. Comme son nom l'indique, il remplit les valeurs entres avec des zros.
N'ayez crainte, aucun mal ne sera fait aucun d'entre nous, il s'agit du chiffre zro et non
des utilisateurs de ce site. (Comment a, c'est pas drle
)
Donc si j'enregistre 23 dans un TINYINT UNSIGNED ZEROFILL (ZEROFILL implique l'attribut UNSIGNED), SQL enregistrera
023. Ou encore dans un SMALLINT UNSIGNED ZEROFILL : 00023.
Ha c'est bien mais si je veux stocker un nombre 4 chiffres complt par des zros (comme par exemple un CHMOD
0755, 0664...), hein ?
www.openclassrooms.com
7/17
Ou sur phpMyAdmin :
Prcision de calcul
On a vu plus haut que les nombres virgules taient stocks sous la forme de deux
nombres entiers. En comprenant que seul des nombres entiers sont enregistrs et qu'ils
sont cods sur un nombre fini de bits, certains nombres ou rsultats seront obligatoirement approxims.
Tout d'abord, sachez que si vous faites la somme de plusieurs nombres entiers, il n'y a pas de perte de prcision. Ce n'est pas
parce que votre colonne est un TINYINT que SQL ne peut pas calculer au-del de 256, en additionnant deux TINYINT de 250, on
obtient bien 500. Les rsultats sont fiables tant qu'on ne dpasse pas 64 bits de prcision. En BIGINT, certaines fonctions telles
que SMU() permettent d'obtenir des valeurs exactes mme avec de grands nombre. Par exemple la somme de deux entes :
18446744073709551615 et 18446744073709551614, le rsultat retourn est 36893488147419103229. La valeur est exacte malgr le
dpassement des 64 bits. Attention cependant au logiciel qui rcuprera ce rsultat. Par exemple PHP a une prcision de 14 bits
par dfaut, ce qui est bien en de, on perd donc dans le cas prsent 8 dcimales. En faisant
ini_set('precision',32);), on rduit la perte une seule dcimale. Et la prcision du logiciel ne peut excder celle du
systme (gnralement 32 ou 64 bits). Il y a donc toujours une limite. Notez tout de mme que vous pouvez restituer le nombre
sous forme de texte sans perte et utiliser la bibliothque GMP pour faire des calculs sur de grands nombres. Cette bibliothque
est disponible dans de nombreux langages (y compris PHP : fonctions GMP).
En revanche, certains calculs vont donner des rsultats trs inattendus si la prcision est dpasse : 18446744073709551615 +
18446744073709551614 = 18446744073709551613 (Ici, 18446744073709551615 a t compris comme -1)
Autre calcul : 18446744073709551615 * 2 = 18446744073709551614 (MySQL est incapable de dpasser 18446744073709551614 en
calculant directement avec des nombres entiers)
Le raisonnement est identique avec les nombres virgule. Ds lors que vous faites une division ou un calcul incluant un nombre
virgule (moyenne, racine...), vos nombres entiers sont convertis en nombres virgule. Par exemple, si on reprend le prcdent
calcul en rajoutant une dcimale 2 pour en faire un nombre virgule, on obtient alors le bon rsultat :
18446744073709551615 * 2.0 = 36893488147419103230.0 (Ici, MySQL convertit l'entier en nombre virgule et renvoie un rsultat
de mme prcision)
D'autres exemples de calcul en SQL :
18446744073709551615 / 0.5 = 36893488147419103230.0000
5 / 3 = 1.6667
5.00 / 3 = 1.666667
5.00000 / 3 = 1.666666667
5.00000 / 3.00000 = 1.666666667
5.00[...]00 / 3 = 1.666666666666666666666666666667
(5 / 3) * 1.00000000 = 1.666666666000
On constate que l'on peut forcer la prcision de MySQL en rajoutant des 0 aprs la virgule. Toute fois la prcision ne pourra
jamais excder 64 bits et le rsultat du division portera au moins 4 chiffres aprs la virgule.
Grce au dernier exemple, on voit que MySQL ne conserve pas la prcision de calcul d'une opration la suivante.
Enfin, DECIMAL possde deux paramtres, la prcision totale M et la prcision aprs la virgule D exprimes en nombres de
chiffres dcimaux (et non en bits comme c'est le cas si on dfinit une prcision un type FLOAT par exemple). La valeur maximale
de M est 65 et D ne peut excder ni M ni 30. DECIMAL vous permet donc de stocker soit trs grand (plus que BIGINT) soit trs
prcis et la prcision est restitue avec exactitude. Ainsi MySQL conseille d'utiliser DECIMAL plutt que DOUBLE pour des
valeurs montaires afin d'viter les erreurs d'approximation. Considrez tout de mme la consommation gourmande de capacits
du type DECIMAL. Si vote systme vous permet de traiter les donnes l'insertion et la rcupration, il es possible de convertir
vos nombres virgules en nombre entier, par exemple en convertissant vos valeurs montaires en centimes. Dans beaucoup de
cas, la capacit de BIGINT (voire de types plus petits) est largement suffisante et donc ne pose pas de problme de prcision et
sont plus optimiss.
Dernire subtilit aborder pour en finir avec les types numriques : les paramtres optionnels de FLOAT. FLOAT(P) permet de
dfinir une autre prcision que celle par dfaut (24), elle correspond au nombre de bits sur lesquels sont cods la mantisse. Si P
<= 24, FLOAT occupe 4 octets, si P > 24, il occupe 8 octets. La valeur maximal de P est 53.
www.openclassrooms.com
8/17
FLOAT peut galement prendre 2 paramtres. Dans ce cas, le premier paramtre reste la prcision exprime en bits et le second
paramtre permet de dfinir le nombres de chiffres aprs la virgule stocker et afficher. Les valeurs maximum sont alors 255
pour le premier paramtre et 30 pour le second.
Date et Heure
Il existe 5 types temporels.
Attention, utilisateurs de PHP,
Aller l'essentiel
Type de colonne
Numrique
ou chane
Format
TIME
Chane
HH:MM:SS
TIMESTAMP
Numrique
AAAAMMJJHHMMSS
DATETIME
AAAA-MM-JJ HH:MM:SS
DATE
Chane
AAAA-MM-JJ
YEAR
Numrique
AAAA
Les donnes ont des limites logiques, les minutes et secondes sont comprises entre 0 et 59, les heures entre 0 et 23, les jours
entre 1 et 28 31 selon le mois, les mois entre 1 et 12.
Seules les annes sont un peu spciales. En gros, elles prennent la place qu'il reste donc a varie selon le type de colonne.
DATE et DATETIME : La documentation MySQL donne pour intervalle de validit : 1000 9999. En pratique, on peut
mme aller de 0 9999 tout comme on peut insrer 0 pour le jour ou le mois. Mais cela est vivement dconseill car les
fonctions de date pourraient avoir des comportement imprvus.
TIMESTAMP va de 19700101000000 20380119041407 (du 1er janvier 1970 au 19 janvier 2038 4h14 07). Il est donc
conseill de vrifier que l'anne soit comprise entre 1970 et 2038 avant d'insrer une valeur dans ce type de colonne.
YEAR est limit 1 octet et donc ses bornes sont 1901 et 2155. Si vous insrez un nombre compris entre 0 et 69, il lui sera
automatiquement ajout 2000, si vous insrez un nombre compris entre 70 et 99, il lui sera ajout 1900.
Attention, toute valeur non inclue dans les intervales cits ci-avant sera remplac par un "zro" dont le format et le
type (numrique ou texte) suit le format de la colonne (voire tableau ci-dessus).
Voil un peu tout ce que vous pouvez faire avec des colonnes de type temporel.
CURRENT_DATE() ou CURDATE() pour obtenir la date courante (exemple : 2009-05-21)
CURRENT_TIME() ou CURTIME() pour obtenir l'heure (exemple : 19:02:43)
CURRENT_TIMESTAMP() ou NOW() pour obtenir la date et l'heure (exemple : 2009-05-21 19:02:43)
Les types ci-dessus peuvent tre convertis en entier en faisant CURTIME()+0 qui donne 190243
YEAR() rcupre l'anne dans une date (exemple : YEAR(`date`) donne 2007)
MONTH() rcupre le mois
DAYOFMONTH() rcupre le jour du mois
HOUR() rcupre l'heure
MINUTE() rcupre la minute
SECOND() rcupre la seconde
www.openclassrooms.com
9/17
DATE_FORMAT est adapte la mise en forme d'une date que l'on souhaite ensuite afficher. Les autres fonctions quand elle
sont intressante lorsque l'on veut faire des traitements numriques ou de recherche avec l'une ou l'autre donne de date.
Vous pouvez enfin comparer tous les types de colonne temporels avec >, <, =...
Le type SET
Les valeurs possibles de `piece` sont donc 'pile', 'face' mais aussi 'pile' et 'face' (not 'pile,face' dans une requte SQL)
et aucune valeur (not ''). Et tout ceci ne prend qu'un quart d'octet alors qu'il faudrait 4 octets pour stocker le texte dans un
VARCHAR. Bien sr on ne peut pas couper un octet en 4, mais je signifiais par l qu'il y a encore de la place pour 6 autres
valeurs au choix dans ce type de colonne SET.
Voil comment est stock en binaire les 4 valeurs possibles pour un type SET qui contient 2 valeurs prdfinies :
Valeur SQL
''
Valeur binaire
00000000
www.openclassrooms.com
10/17
'pile'
00000001
'face'
00000010
'pile,face' 00000011
Donc pour chaque bit de l'octet, une valeur peut tre slectionne ou non (1 ou 0). Les SET stockent ensuite ce nombre binaire
comme les types numriques. Il peut donc peser 1, 2, 3, 4 ou 8 octets selon le nombre de valeurs prdfinies :
Nombre de valeurs Taille en octets
18
9 16
17 24
25 32
33 64
Le type ENUM
Le type ENUM lui ne peut pas prendre plusieurs valeurs. C'est pile ou face... Ou tranche la limite mais pas de mlange. Cela
permet en revanche de prendre beaucoup moins de place. chaque valeur est associe un nombre converti en binaire et stock
dans un octet. Donc de 2 255 valeurs prdfinies, le ENUM ne prend qu'un seul octet. Et bien que sa taille maximale soit de 2
octets, cela permet tout de mme d'aller jusqu' 65 535 valeurs.
Colonnes de texte
Bon, un tableau de plus ou de moins ne pourra faire de diffrence, je vais donc simplement rsumer les possibilits directement
tires de la doc en essayant de trier un peu les informations et de les vulgariser.
Vulgariser, c'est expliquer avec des phrases simples quelque chose de tordu de faon ce que ce soit comprhensible
pour la plupart des humains. Et paradoxalement, il faut souvent commencer par vulgariser le mot "vulgariser" pour que
ce soit clair.
Voil c'tait juste pour viter de faire fuir ceux qui croyaient que j'allais parler de faon grossire.
La taille minimale de tous les types textuels est de 1 caractre. Dans le tableau suivant, je considrerai que M est la taille maximale
(choisie dans la colonne Taille/Valeurs de phpMyAdmin ou entre parenthses dans une requte SQL). Et L sera la longueur du
texte enregistr l'insertion (elle est donc variable dans une mme table)
Type
Taille maximale
Espace requis
CHAR
255
VARCHAR
TINYBLOB, TINYTEXT
255
L+1
BLOB, TEXT
65 535
L+2
L+3
LONGBLOB, LONGTEXT
L+4
Les +1, +2, +3 et +4 servent tout simplement stocker la longueur du texte enregistr. La taille de CHAR n'est pas
variable contrairement aux autres.
R0ro3lectr0 m'a fait remarquer qu' partir de MySQL 5.5, le type VARCHAR autorise une longueur de texte maximale de
65 535 caractres. Si vous ne connaissez pas votre version ou que vous voulez dvelopper un systme compatible avec
MySQL 5.0, considrez simplement que la limite est 255 et "qui peut le plus peut le moins", votre systme fonctionnera
aussi avec MySQL 5.5. Notez bien que si vous utilisez cette version ou une suprieure, les textes de plus de 255
www.openclassrooms.com
11/17
caractres occuperont alors Longueur+2 octets. Enfin remarquez que les proprits de TINYTEXT restent les mmes
dans les nouvelles versions.
blob
Voiture
voiture
Quelques autres rgles pour obtenir une structure globale de base de donnes
fonctionnelle et optimise :
www.openclassrooms.com
12/17
L'index de table
Pour terminer, je vais vous parler de l'index de table. Rappelez-vous nous avions pris cette table mal optimise en exemple au
dbut :
www.openclassrooms.com
13/17
Rcapitulons
Reprenons donc maintenant la table que je vous avais prsente au dpart comme plus
optimise :
Et voici sous forme de tableau la liste des types de colonne que nous avons tudis dans ce tutoriel et leurs proprits les plus
importantes. Je vous invite vous y rfrer aussi souvent que ncessaire :
Type
de colonne
Poids
(en octets)
Type de valeur
retourne
Limite
Types numriques
TINYINT
Nombre entier
SMALLINT
Nombre entier
MEDIUMINT
Nombre entier
www.openclassrooms.com
14/17
INT
Nombre entier
[-2 147 483 648 ; 2 147 483 647] ou [0 ; 4 294 967 295]
BIGINT
Nombre entier
FLOAT
DOUBLE
DECIMAL
TIMESTAMP
Nombre entier
[19700101000000 ; 20380119041407]
YEAR
Nombre entier
[1901 ; 2155]
DATE
Chane
[1000-01-01 ; 9999-12-31]
DATETIME
Chane
TIME
Chane
[00:00:00 ; 23:59:59]
Types chanes
CHAR
Chane
VARCHAR
L+1
Chane
TINYTEXT
L+1
Chane
255 caractres
TEXT
L+2
Chane
65 535 caractres
MEDIUMTEXT L+3
Chane
LONGTEXT
Chane
L+4
Types binaires
TINYBLOB
L+1
Chane binaire
255 octets
BLOB
L+2
Chane binaire
65 535 octets
MEDIUMBLOB L+3
Chane binaire
LONGBLOB
Chane binaire
L+4
Chane
8 choix
SET
Chane
16 choix
SET
Chane
24 choix
SET
Chane
32 choix
SET
Chane
64 choix
ENUM
Chane
255 choix
ENUM
Chane
65 535 choix
Q.C.M.
Le premier QCM de ce cours vous est offert en libre accs.
Pour accder aux suivants
Connectez-vous Inscrivez-vous
On souhaite stocker la dure de films dans une seule colonne de faon optimise.
Le film le plus long sera King Kong de Peter Jackson : 3h 00min.
Le film le plus court sera The Big Shave de Martin Scorsese : 06 min.
www.openclassrooms.com
15/17
Pour stocker l'extension de fichiers afin de pouvoir afficher ensuite sparment chaque type de fichier, quel type de
colonne dois-je utiliser ?
TEXT
BLOB
TINYTEXT
TINYBLOB
Je dois stocker la valeur retourne par la fonction time() de PHP. Quel type de colonne utiliser ? (Attention, pige
!)
date correspondante
Point de dpart 0
Maximum
19 janvier 2038
BIGINT
INT
M EDIUM INT
TIM ESTAM P
TIM E
www.openclassrooms.com
16/17
Correction !
Statistiques de rponses au Q CM
J'espre que ce tuto vous a t utile. Mon niveau de SQL reste toutefois lacunaire, n'hsitez donc pas apporter des prcisions
ce tuto en m'envoyant des MP, je complterai ce tuto si ncessaire.
Je n'ai pas fait le tour de tous les types SQL, chaque version et type de base de donnes a ses types et ses alias de types, pour
un listing complet des types de MySQL, je vous conseille :
le tuto de Bouv
La doc MySQL (voyez notamment cette page)
Partager
www.openclassrooms.com