Bien choisir son type numérique en SQL — INT, BIGINT, DECIMAL et FLOAT expliqués [Guide de conception BD]

Quand vous concevez une table de base de données, comment choisissez-vous le type numérique de chaque colonne ?

« Mets INT pour les entiers. » « Prends BIGINT, on ne sait jamais. » « Il y a des décimales, donc FLOAT. » Si ces phrases vous sont familières, vous n’êtes pas seul. Mais ce type de réflexe peut engendrer des problèmes de performance, du gaspillage de stockage, et même des bugs critiques dans les calculs financiers à terme.

Exemple concret : remplacer INT par BIGINT sur une seule colonne d’une table de 100 millions de lignes ajoute environ 400 Mo de stockage. Ajoutez deux index, et l’écart dépasse 1 Go. À l’autre extrême, choisir INT pour une table de logs à forte volumétrie qui grandit de plusieurs millions de lignes par jour peut provoquer un crash par dépassement quelques années plus tard, paralysant toute votre application.

Et puis il y a FLOAT. La plupart des développeurs savent que 0.1 + 0.2 donne 0.30000000000000004 au lieu de 0.3. Pourtant, des colonnes FLOAT se retrouvent encore dans des tables de paiement en production, accumulant silencieusement des erreurs d’arrondi jusqu’à ce que les rapports mensuels de chiffre d’affaires ne correspondent plus.

Cet article est un guide complet des quatre types numériques SQL les plus importants — INT, BIGINT, DECIMAL et FLOAT — couvrant leurs différences, leurs compromis, et des règles de décision pratiques que vous pouvez appliquer immédiatement.

💡 Astuce

La conception de base de données est le socle de tout système logiciel. Pour les fondamentaux de la conception orientée objet, consultez le guide des principes SOLID. Pour choisir un langage de programmation, consultez le guide de comparaison des langages.

Aperçu des types numériques SQL

Commençons par la vue d’ensemble. Le tableau ci-dessous résume les principaux types numériques. Chaque section suivante approfondit le sujet.

TypeTaillePlage (approx.)PrécisionUsage typique
TINYINT1 octet0 – 255 / -128 – 127ExacteDrapeaux, codes statut
SMALLINT2 octets0 – 65 535ExactePetits compteurs
INT4 octets~2,1 milliards / ~4,2 milliardsExacteIDs, quantités, comptages
BIGINT8 octets~9,2 × 10¹⁸ExacteIDs de logs, clés primaires volumineuses
DECIMAL(M,D)VariableM chiffres (D décimales)ExacteArgent, taux de TVA, ratios
FLOAT4 octets±3,4 × 10³⁸ApproximativeTempérature, données capteurs
DOUBLE8 octets±1,7 × 10³⁰⁸ApproximativeCoordonnées GPS, statistiques

Les quatre types qui comptent le plus au quotidien sont INT, BIGINT, DECIMAL et FLOAT. Maîtrisez ces quatre-là et vous gérerez la grande majorité des conceptions de bases de données sans problème.

Les types entiers (famille INT) — Le point de départ par défaut

Les entiers sont le type numérique le plus rapide, le plus économe en stockage et le plus fiable en SQL. Ils surpassent les autres en vitesse de calcul, efficacité des index et empreinte disque. Si une colonne n’a pas besoin de décimales, un type entier est toujours le bon choix.

MySQL propose cinq tailles d’entiers :

TypeTaillePlage SIGNEDPlage UNSIGNED
TINYINT1 octet-128 à 1270 à 255
SMALLINT2 octets-32 768 à 32 7670 à 65 535
MEDIUMINT3 octets-8 388 608 à 8 388 6070 à 16 777 215
INT4 octets-2 147 483 648 à 2 147 483 6470 à 4 294 967 295
BIGINT8 octets-9,2 × 10¹⁸ à 9,2 × 10¹⁸0 à ~1,84 × 10¹⁹

La règle d’or : si la valeur peut être représentée comme un entier, utilisez un type entier. Par exemple, si votre système gère les prix en centimes d’euros, price_cents INT fonctionne parfaitement. INT plafonne à environ 2,1 milliards, ce qui permet de gérer des montants jusqu’à 21 millions d’euros en centimes — largement suffisant pour la plupart des produits e-commerce.

Cas d’usage courants des entiers :

  • IDs (clés primaires) : user_id, product_id, order_id
  • Quantités : stock_quantity, cart_count
  • Compteurs : login_count, view_count, retry_count
  • Codes statut : order_status (0 = en attente, 1 = payé, 2 = expédié…)
  • Drapeaux booléens : is_active, is_deleted (TINYINT avec 0/1)

Il n’y a aucune raison d’utiliser DECIMAL ou FLOAT pour l’un de ces cas. Les entiers sont le choix le plus rapide et le plus sûr.

INT vs. BIGINT — « Mieux vaut prévenir que guérir » est-il vraiment prudent ?

Le dilemme le plus courant dans le choix du type entier est INT contre BIGINT. La réponse courte : INT suffit dans la grande majorité des cas. La réponse longue montre pourquoi tout passer en BIGINT à l’aveugle est un anti-pattern coûteux.

Prenons d’abord conscience de l’échelle. INT UNSIGNED plafonne à environ 4,2 milliards. La France compte environ 68 millions d’habitants — à peine 1,6 % de la capacité d’un INT. Un service web avec 1 million d’utilisateurs pourrait stocker 4 000 entrées de logs par utilisateur et rester dans la plage d’un INT. Pour les IDs utilisateurs, produits et commandes, INT est presque toujours largement suffisant.

Alors quand BIGINT devient-il nécessaire ?

  • Logs d’accès : Un site gérant 100 millions de pages vues par mois accumule 1,2 milliard de lignes par an. En 3–4 ans, le plafond d’INT est en vue
  • Données IoT : 10 000 capteurs envoyant des données chaque seconde génèrent environ 315 milliards de lignes par an — bien au-delà de la capacité d’INT
  • IDs distribués (Snowflake, etc.) : Ils encodent un horodatage, un ID de worker et un numéro de séquence en une seule valeur potentiellement très grande
  • IDs de transactions : Un système de paiement traitant 1 million de transactions par jour atteint 3,65 milliards en 10 ans — dangereusement proche de la limite d’INT

Quantifions maintenant le coût de « mettre BIGINT partout » :

ScénarioINT (4 octets)BIGINT (8 octets)Différence
100M lignes × 1 colonne381 Mo762 Mo+381 Mo
100M lignes × 1 col + 2 index1,14 Go2,29 Go+1,14 Go
Mémoire JOIN (estimation)Référence~1,5–2×Efficacité cache réduite

Sur une table de 100 millions de lignes, passer une seule colonne plus deux index d’INT à BIGINT gaspille plus de 1,1 Go. Multipliez cela sur plusieurs colonnes et tables, et le total peut atteindre des dizaines de gigaoctets — augmentant les I/O disque, réduisant l’efficacité du buffer pool et ralentissant les requêtes.

Un guide de décision pratique :

Rôle de la colonneType recommandéJustification
ID utilisateurINT UNSIGNEDTrès peu de services dépassent 4,2 milliards d’utilisateurs
ID produitINT UNSIGNEDMême raisonnement
ID commandeINT UNSIGNED ou BIGINTDépend du volume et de la durée de vie
ID log d’accèsBIGINTDes milliards de lignes attendues par an
Snowflake / UUID numériqueBIGINTValeurs intrinsèquement grandes
⚠️ Piège courant

Ne fondez pas votre choix uniquement sur le nombre actuel de lignes. Ce qui compte, c’est le taux de croissance sur toute la durée de vie opérationnelle. Estimez les insertions annuelles, projetez sur 10 ans, et vérifiez si INT UNSIGNED (4,2 milliards) tiendra. Si ce n’est pas le cas, partez directement sur BIGINT.

UNSIGNED — Doubler la plage gratuitement

Dans MySQL et MariaDB, ajouter UNSIGNED à une colonne entière supprime la plage négative et double la plage positive sans coût de stockage supplémentaire. Un INT classique va d’environ -2,1 milliards à +2,1 milliards ; INT UNSIGNED va de 0 à 4,2 milliards — toujours 4 octets.

Les colonnes comme les IDs, quantités et compteurs ne sont jamais négatives. Il n’y a aucune raison de ne pas utiliser UNSIGNED pour elles.

Exemple du0027utilisation UNSIGNED
CREATE TABLE users (n  id          INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,n  age         TINYINT UNSIGNED,          u002du002d 0 u00e0 255, cu0027est largement suffisantn  login_count INT UNSIGNED DEFAULT 0,n  point       INT UNSIGNED DEFAULT 0n);
⚠️ Piège courant

La soustraction entre deux colonnes UNSIGNED peut provoquer un dépassement par le bas (underflow). Dans MySQL, SELECT a - ba < b produit une valeur énorme (ou une erreur) car le résultat fait un « wrap around ». Si la soustraction est possible, utilisez CAST(a AS SIGNED) - CAST(b AS SIGNED) ou envisagez de garder la colonne en SIGNED.

Note : PostgreSQL ne supporte pas UNSIGNED. L’alternative classique est une contrainte CHECK (CHECK (id >= 0)) pour garantir des valeurs non négatives au niveau applicatif.

DECIMAL (NUMERIC) — Le seul choix correct pour l’argent

DECIMAL stocke les nombres comme des valeurs exactes en base 10. Contrairement à FLOAT, il ne convertit pas en binaire en interne : 0,1 est stocké exactement comme 0,1. Pour toute colonne où même une fraction de centime compte — prix, factures, TVA, soldes de comptes — DECIMAL est le seul type acceptable.

Pourquoi pas FLOAT ? Voyons le problème en action :

Comparaison de pru00e9cision FLOAT vs DECIMAL
u002du002d Ce qui se passe avec FLOATnSELECT CAST(0.1 AS FLOAT) + CAST(0.2 AS FLOAT);nu002du002d Ru00e9sultat : 0.30000001192092896 (pas 0.3)nnu002du002d DECIMAL donne le ru00e9sultat justenSELECT CAST(0.1 AS DECIMAL(10,2)) + CAST(0.2 AS DECIMAL(10,2));nu002du002d Ru00e9sultat : 0.30 (exactement 0.30)

En quoi cette infime erreur est-elle importante en pratique ? Imaginez une boutique en ligne vendant un article à 11,99 €, traitant 50 000 commandes par mois :

  • Avec FLOAT : Chaque ligne peut porter une erreur aussi minime que +0,000001, mais sur 50 000 lignes et de multiples calculs de TVA, les écarts d’arrondi s’accumulent. Multipliez par des centaines de références sur un an, et le grand livre dérive de plusieurs euros — suffisamment pour déclencher un contrôle fiscal
  • Avec DECIMAL : Zéro dérive. Chaque agrégation est juste au centime près, à chaque fois

« Ce n’est qu’un millionième d’euro. » C’est vrai — mais en comptabilité, si les comptes ne tombent pas juste au centime, quelqu’un doit expliquer pourquoi. « On a utilisé le mauvais type de colonne » n’est pas une réponse qu’un commissaire aux comptes acceptera.

DECIMAL se déclare DECIMAL(M, D) où M est le nombre total de chiffres et D le nombre de décimales :

DECIMAL en pratique
u002du002d DECIMAL(10,2) : 10 chiffres au total, 2 du00e9cimalesnu002du002d Valeur max : 99 999 999,99nnCREATE TABLE orders (n  id         INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,n  subtotal   DECIMAL(10,2) NOT NULL,  u002du002d Montant HTn  tax_rate   DECIMAL(5,4)  NOT NULL,  u002du002d ex. 0.2000 (20 % TVA)n  tax_amount DECIMAL(10,2) NOT NULL,  u002du002d Montant TVAn  total      DECIMAL(10,2) NOT NULL   u002du002d Total TTCn);
💡 Astuce

DECIMAL et NUMERIC sont synonymes dans le standard SQL. MySQL, PostgreSQL et SQL Server les traitent de manière identique. Choisissez-en un et restez cohérent dans tout votre code.

Dimensionner DECIMAL — Pourquoi DECIMAL(18,10) est presque toujours surdimensionné

Une autre erreur courante consiste à spécifier une précision excessive : DECIMAL(18,10) voire DECIMAL(30,15) « au cas où ». Cela gaspille du stockage et ralentit les agrégations.

La taille de stockage de DECIMAL est proportionnelle au nombre de chiffres. Dans MySQL, chaque groupe de 9 chiffres consomme 4 octets, avec des octets supplémentaires pour les restes :

TypeStockage (MySQL)Exemple d’usage
DECIMAL(5,2)3 octetsPourcentages (jusqu’à 99,99 %)
DECIMAL(10,2)5 octetsPrix (jusqu’à 99 999 999,99 €)
DECIMAL(12,4)6 octetsTaux de change (ex. 1,3456)
DECIMAL(18,10)9 octetsSurdimensionné pour la plupart des applications

La bonne approche consiste à partir de la valeur maximale :

  • Prix e-commerce : Si le prix le plus élevé est de quelques millions d’euros, DECIMAL(10,2) couvre jusqu’à 99 999 999,99 €
  • Taux de TVA : En France, le taux normal est de 20 %, le taux réduit de 5,5 %. DECIMAL(5,4) couvre jusqu’à 99,9999 %
  • Pourcentages de remise : 0–100 % tient dans DECIMAL(5,2)
  • Taux de change : EUR/USD à 1,0845 — DECIMAL(12,4) offre une marge confortable
  • Cryptomonnaies : La plus petite unité d’Ethereum (wei = 10⁻¹⁸ ETH) nécessite réellement DECIMAL(36,18) — un cas rare où une précision extrême est justifiée

Utiliser DECIMAL(18,10) pour une colonne de prix, c’est comme imprimer une note personnelle sur du papier A0. Dimensionnez la précision correctement, et vous économiserez du stockage et accélérerez vos requêtes.

FLOAT / DOUBLE — La vitesse au prix de l’exactitude

FLOAT et DOUBLE sont des types à virgule flottante qui représentent les nombres décimaux au format binaire IEEE 754. Cela leur confère un avantage majeur et une limitation intrinsèque.

L’avantage est clair : 4 octets fixes (FLOAT) ou 8 octets (DOUBLE) peuvent représenter une plage de valeurs énorme. FLOAT seul couvre ±3,4 × 10³⁸, et le matériel de calcul flottant du CPU rend l’arithmétique extrêmement rapide.

La limitation est qu’ils stockent des approximations, pas des valeurs exactes. Le décimal 0,1 devient le binaire périodique infini 0,000110011001100… qui doit être arrondi pour tenir dans un nombre fini de bits. C’est la cause fondamentale du fameux problème « 0,1 + 0,2 ≠ 0,3 ».

FLOAT est le bon choix quand de petites erreurs d’arrondi n’affectent pas le résultat :

  • Relevés de température : Un capteur industriel indique 23,45 °C avec une précision intrinsèque de ±0,1 °C. Une erreur de stockage de ±0,0001 °C n’a aucune signification
  • Coordonnées GPS : Six décimales en latitude/longitude correspondent à ~11 cm de précision. DOUBLE préserve jusqu’à 15 chiffres significatifs — une précision sub-millimétrique qui dépasse largement tout besoin réel
  • Features de machine learning : Les modèles ML ont des millions voire des milliards de paramètres ; un micro-arrondi sur un poids individuel a un impact négligeable sur la précision globale
  • Simulations physiques : La dynamique des fluides et l’analyse structurelle tirent parti de la vitesse de FLOAT, avec un contrôle de l’erreur au niveau algorithmique
  • Agrégats statistiques : Moyennes, écarts-types et corrélations sont calculés à partir de données qui contiennent déjà du bruit statistique

Le choix entre FLOAT et DOUBLE se résume à la précision et au stockage :

TypeTailleChiffres significatifsQuand le choisir
FLOAT4 octets~7Données capteurs, stockage optimisé
DOUBLE8 octets~15Haute précision requise : GPS, calcul scientifique

Stocker des coordonnées GPS en FLOAT ne donne que ~7 chiffres significatifs — environ 11 m de précision. Pour une application de cartographie, DOUBLE (~15 chiffres, sub-millimétrique) est le choix évident. Inversement, stocker des relevés de capteurs de température en DOUBLE est inutile quand le capteur lui-même n’est précis qu’à ±0,5 °C — FLOAT est amplement suffisant.

FLOAT vs. DECIMAL — Guide de décision rapide

En pratique, vous devez faire ce choix rapidement et avec assurance. Voici un tableau de référence :

Cas d’usageDECIMALFLOAT / DOUBLE
Prix, factures, facturation✗ (jamais)
Taux de TVA, remises
Points fidélité / miles✓ (si fractionnaire)
Poids d’inventaire (kg)
Température / humidité
Coordonnées GPS✓ (DOUBLE)
Données capteurs
Features ML / scores
Valeurs statistiques (moyenne, etc.)

La règle de base tient en trois lignes :

  • De l’argent est en jeu → DECIMAL
  • Mesure ou science → FLOAT / DOUBLE
  • Pas sûr → DECIMAL (par précaution)

Retenez ces trois règles et vous vous tromperez rarement.

Cinq erreurs de conception courantes

Les erreurs de types numériques ont tendance à être invisibles en développement et ne se révèlent qu’en production. Voici les cinq plus fréquentes.

Erreur n°1 : Mettre BIGINT partout

L’esprit « plus gros, plus sûr » pousse les équipes à mettre BIGINT sur toutes les colonnes entières par défaut. Comme montré plus haut, cela peut gaspiller plus de 1 Go pour 100 millions de lignes sur une seule colonne plus ses index. Sur 10 tables avec 3 colonnes BIGINT chacune, cela représente environ 12 Go de stockage gaspillé — impactant directement les coûts d’hébergement cloud et l’efficacité du buffer pool.

Erreur n°2 : Utiliser FLOAT pour l’argent

C’est l’erreur la plus dangereuse de cette liste. Elle passe souvent tous les tests unitaires car les erreurs d’arrondi sont invisibles à petite échelle. Le problème émerge en production quand le volume de transactions augmente : « Le chiffre d’affaires mensuel ne correspond pas aux dépôts bancaires réels. » L’analyse de la cause racine prend des jours, et corriger rétroactivement des données financières stockées en FLOAT est extrêmement difficile.

Erreur n°3 : Surdimensionner la précision DECIMAL

Définir DECIMAL(30,15) « au cas où » gaspille du stockage et ralentit les requêtes d’agrégation. En dehors des cryptomonnaies (où 18 décimales sont réellement nécessaires), très peu de domaines métier nécessitent plus de 4 décimales.

Erreur n°4 : Ne pas anticiper le dépassement INT

Une table peut commencer avec quelques centaines d’insertions par jour, mais la croissance peut être exponentielle. INT SIGNED plafonne à ~2,1 milliards. Avec un AUTO_INCREMENT à 50 000 insertions/jour, cela laisse 117 ans de marge — mais les dumps de données de test, les trous d’ID et la croissance inattendue peuvent consommer cette marge plus vite que prévu. Surveillez régulièrement vos « high-water marks » d’AUTO_INCREMENT.

Erreur n°5 : Types incompatibles dans les JOINs

Si orders.user_id est INT mais users.id est BIGINT, chaque JOIN déclenche une conversion de type implicite. Dans MySQL, cela peut empêcher l’optimiseur d’utiliser les index, transformant une requête d’une milliseconde en un scan complet de table de plusieurs secondes. Assurez-vous toujours que les colonnes utilisées dans les JOINs partagent exactement le même type.

Types recommandés par cas d’usage

Utilisez ce tableau de référence rapide lors de la conception de nouvelles tables :

Rôle de la colonneType recommandéNotes
ID utilisateurINT UNSIGNED4,2 milliards, c’est largement suffisant
ID produitINT UNSIGNEDMême raisonnement
ID log / événementBIGINT UNSIGNEDDes milliards de lignes par an
ID SnowflakeBIGINTValeurs intrinsèquement grandes
Prix produitDECIMAL(10,2)Max 99 999 999,99 €
Taux de TVADECIMAL(5,4)ex. 0.2000 (20 %)
Taux de remiseDECIMAL(5,2)ex. 15,50 %
Taux de changeDECIMAL(12,4)ex. 1,0845
Quantité en stock (entier)INT UNSIGNEDPas de décimales nécessaires
Poids (kg)DECIMAL(8,3)ex. 12345,678
TempératureFLOATLa précision du capteur suffit
Latitude / Longitude GPSDOUBLEHaute précision requise
Feature MLFLOATVitesse plutôt que précision
Points (entier)INT UNSIGNEDPas de fractions
Points (fractionnaire)DECIMAL(10,2)Miles aériens, etc.
Position au classementINT UNSIGNEDLes classements ne sont jamais négatifs
Drapeau booléen (0/1)TINYINT UNSIGNEDLe BOOLEAN de MySQL en interne
Code statutTINYINT ou SMALLINTDimensionner selon la plage de valeurs

Partager un tel tableau au sein de votre équipe élimine la plupart des débats de choix de types lors des revues de code.

CREATE TABLE — Exemples concrets

Pour finir, voici trois définitions de tables prêtes pour la production. Remarquez comment chaque colonne utilise le type le plus petit adapté.

Exemple 1 : Produits e-commerce

products.sql
CREATE TABLE products (n  id          INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,n  name        VARCHAR(255) NOT NULL,n  price       DECIMAL(10,2) NOT NULL DEFAULT 0.00,  u002du002d Argent = DECIMALn  tax_rate    DECIMAL(5,4) NOT NULL DEFAULT 0.2000, u002du002d 20 % TVA = 0.2000n  stock       INT UNSIGNED NOT NULL DEFAULT 0,       u002du002d Quantitu00e9 entiu00e8ren  weight_kg   DECIMAL(8,3),                          u002du002d Poids du0027expu00e9ditionn  rating      FLOAT,                                 u002du002d Note moyenne utilisateurn  is_active   TINYINT UNSIGNED NOT NULL DEFAULT 1,   u002du002d Drapeau boolu00e9enn  created_at  DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMPn) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

Exemple 2 : Logs d’accès

access_logs.sql
CREATE TABLE access_logs (n  id          BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, u002du002d Fort volumen  user_id     INT UNSIGNED,               u002du002d Mu00eame type que users.idn  status_code SMALLINT UNSIGNED NOT NULL,  u002du002d HTTP 200, 404, 500...n  response_ms INT UNSIGNED,                u002du002d Temps de ru00e9ponse en msn  created_at  DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,n  INDEX idx_user (user_id),n  INDEX idx_created (created_at)n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

Exemple 3 : Relevés de capteurs IoT

sensor_readings.sql
CREATE TABLE sensor_readings (n  id            BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,n  device_id     INT UNSIGNED NOT NULL,n  temperature   FLOAT,          u002du002d La pru00e9cision du capteur suffitn  humidity      FLOAT,          u002du002d Idemn  latitude      DOUBLE,         u002du002d Le GPS nu00e9cessite haute pru00e9cisionn  longitude     DOUBLE,         u002du002d Idemn  battery_pct   TINYINT UNSIGNED, u002du002d Batterie 0-100 %n  recorded_at   DATETIME(3) NOT NULL, u002du002d Pru00e9cision u00e0 la milliseconden  INDEX idx_device_time (device_id, recorded_at)n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

Les trois tables partagent un point commun : chaque colonne est définie avec le plus petit type adapté à son usage. Les IDs s’adaptent avec INT ou BIGINT selon les besoins, l’argent utilise DECIMAL, les mesures utilisent FLOAT/DOUBLE, et les drapeaux utilisent TINYINT. C’est à cela que ressemble un schéma bien conçu.

Résumé — Le choix du type est de l’ingénierie de performance

Choisir un type numérique SQL n’est pas qu’une décision de formatage. Cela affecte l’efficacité du stockage, la performance des index, la vitesse des requêtes, la précision des données et la scalabilité future — tout à la fois.

L’essentiel en quatre lignes :

  • Si ça tient dans un entier, utilisez un type entier (le plus rapide, le plus petit, zéro erreur)
  • INT pour la plupart des colonnes, BIGINT pour les logs à fort volume (le stockage double)
  • DECIMAL pour l’argent — sans exception (les erreurs FLOAT sont dévastatrices en finance)
  • FLOAT / DOUBLE pour la science et les mesures (vitesse et plage quand l’approximation convient)

Par-dessus tout, le principe directeur est : choisissez le plus petit type qui répond à vos besoins. Les types surdimensionnés gaspillent du stockage, réduisent l’efficacité du cache et ralentissent les requêtes. Les types sous-dimensionnés risquent le dépassement. Bien choisir implique d’estimer la nature de vos données (entier vs. décimal), la plage de valeurs, la tolérance aux erreurs et le taux de croissance sur la durée de vie du système.

La conception des types numériques est un travail ingrat, mais bien le faire dès le premier jour vous épargnera la dégradation des performances, le gonflement du stockage et les incidents de production à venir. Chaque fois que vous écrivez un CREATE TABLE, demandez-vous : « Ce type est-il vraiment le bon ? » Cette seule habitude élèvera la qualité de votre conception de base de données.

FAQ

Q. Quelle est la première question à se poser quand on hésite sur le type ?

R. Demandez-vous d’abord : « Cette valeur peut-elle être représentée comme un entier ? » Si oui, optez pour un type INT. Ensuite : « Est-ce que cela concerne de l’argent ? » Si oui, DECIMAL est la seule réponse. Tout le reste avec des décimales — températures, coordonnées, scores — oriente vers FLOAT ou DOUBLE. Suivez cette séquence et 95 % des décisions sont instantanées.

Q. Est-il difficile de migrer d’INT vers BIGINT après coup ?

R. La commande ALTER TABLE ... MODIFY COLUMN de MySQL peut changer le type, mais sur les grandes tables, elle verrouille la table pendant des minutes, voire des heures. Des outils comme pt-online-schema-change ou gh-ost effectuent la migration avec un temps d’arrêt quasi nul, mais ils nécessitent tout de même une planification soigneuse. Bien choisir le type dès le départ est toujours moins coûteux que de le corriger après coup.

Q. PostgreSQL ne supporte pas UNSIGNED — que faire ?

R. C’est exact. L’approche standard sous PostgreSQL est d’utiliser une contrainte CHECK (CHECK (id >= 0)) pour garantir des valeurs non négatives. Comme l’INT de PostgreSQL monte tout de même à ~2,1 milliards, c’est suffisant pour la plupart des charges de travail. Si vous avez réellement besoin de la plage de 4,2 milliards, passez à BIGINT.

Q. Quelle est la gravité réelle des erreurs d’arrondi de FLOAT ?

R. FLOAT (4 octets) offre environ 7 chiffres significatifs. Stockez 123456,789 en FLOAT et vous pourriez récupérer 123456,7890625. Pour les données de capteurs ou les mesures scientifiques — où l’instrument lui-même a une précision limitée — c’est négligeable. Pour les calculs financiers, cela signifie des factures décalées d’un centime et des totaux mensuels qui ne correspondent plus. La règle est simple : n’utilisez jamais FLOAT pour l’argent.

Q. DECIMAL est-il vraiment plus lent qu’INT ? De combien ?

R. Pour les requêtes lourdes en agrégation (SUM, AVG sur des millions de lignes), DECIMAL peut être 1,2 à 2 fois plus lent qu’INT. Pour les charges OLTP classiques — des SELECT et INSERT individuels — la différence est négligeable. Certaines équipes stockent les prix en centimes entiers (ex. 19,99 € → 1999) pour bénéficier de la vitesse d’INT, mais cela pose problème dès qu’il faut gérer le multi-devises ou des calculs en sous-centimes. Commencer avec DECIMAL est le pari le plus sûr à long terme.

Comments

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *