Types de données SQL : types numériques, de caractères, de date/heure et binaires. Maîtrisez l'optimisation du stockage, les performances des requêtes, les meilleures pratiques en matière d'intégrité des données et les différences entre les fournisseurs.
Un type de données SQL est une spécification fondamentale qui définit les valeurs qu'une colonne peut contenir et l'espace de stockage que ces valeurs requièrent dans une table de base de données. Comprendre les types de données SQL est essentiel pour toute personne qui conçoit des pipelines de données, écrit des requêtes ou conçoit des schémas de base de données, car ces types contrôlent directement l'intégrité des données, l'efficacité du stockage et les performances des requêtes. Lorsque vous définissez une colonne dans une table de base de données, vous ne spécifiez pas seulement un nom : vous établissez un contrat sur le type d'informations qui résideront dans cette colonne et sur la manière dont la base de données doit les traiter.
On ne saurait trop insister sur l'importance de choisir le bon type de données. Les types de données SQL imposent des règles logiques sur les valeurs qui peuvent être stockées, empêchant ainsi la saisie de données non valides dès le départ. Ils ont également un impact considérable sur la rapidité d'exécution de vos requêtes et sur l'espace disque consommé par vos tables. Un type de données mal choisi peut ralentir les requêtes, gaspiller de l'espace de stockage et créer des bugs subtils dans vos pipelines de données. À l'inverse, la sélection de types appropriés peut améliorer l'évolutivité à long terme et optimiser considérablement les performances de la base de données pour les charges de travail analytiques, les applications en temps réel et les pipelines de caractéristiques de machine learning.
Les types de données SQL sont généralement classés en quatre grands groupes : les types de données numériques pour les calculs mathématiques, les types de données de caractères et de chaînes pour le texte, les types de données de date et d'heure pour enregistrer le moment où les événements se produisent, et les types de données spécialisés pour les données binaires et d'autres formats. Les différents systèmes de bases de données (MySQL, PostgreSQL, SQL Server et Oracle) implémentent chacun ces catégories avec de légères variations de dénomination, de précision et d'exigences de stockage. Ce guide fournit une référence pratique pour comprendre les types de données SQL dans les systèmes de bases de données courants, ainsi que les meilleures pratiques pour choisir le bon type pour votre cas d'usage.
Un type de données est bien plus qu'une simple étiquette. Lorsque vous déclarez qu'une colonne est de type INTEGER ou VARCHAR, vous indiquez précisément à votre système de gestion de base de données le type de valeurs qui doivent figurer dans cette colonne et comment les traiter lors des requêtes et du stockage. La base de données utilise ces informations pour valider les données au moment de l'insertion, empêchant ainsi les entrées qui violent les contraintes du type. Les systèmes de bases de données modernes, comme ceux basés sur les transactions ACID, garantissent que cette validation s'effectue de manière fiable, même lors d'accès concurrents.
Prenons un exemple simple : si vous définissez une colonne comme INTEGER, la base de données rejettera toute tentative d'insertion de texte comme « hello » ou de valeurs non entières comme 3.14. Cette validation se fait automatiquement, garantissant l'intégrité des données en refusant de stocker des formats de données incorrects. Sans cette validation, les requêtes et les analyses en aval se heurteraient à des données corrompues ou incohérentes, ce qui entraînerait des résultats incorrects et une perte de temps en débogage.
Les types de données communiquent également une intention aux autres développeurs et ingénieurs de données qui travaillent avec votre schéma. Lorsque quelqu'un voit qu'une colonne est définie comme DECIMAL plutôt que FLOAT, il comprend immédiatement que cette colonne stocke des valeurs monétaires précises qui ne peuvent tolérer d'erreurs d'arrondi. Cette documentation implicite réduit les malentendus et rend les schémas plus faciles à maintenir au fil du temps.
Le choix du type de données a des conséquences directes sur l'espace disque consommé par vos tables et sur la rapidité d'exécution des requêtes. L'efficacité du stockage a un impact sur vos factures cloud, sur les temps de sauvegarde et sur le nombre de lignes que vous pouvez charger en mémoire pour le traitement. Les performances des requêtes dépendent en partie de la taille du type de données : les types plus petits peuvent être traités plus rapidement car un plus grand nombre de lignes tient dans le cache CPU et moins de données doivent être transférées entre le stockage et le calcul. Pour les équipes qui conçoivent des pipelines ETL traitant des millions de lignes par jour, ces optimisations se traduisent par des améliorations mesurables des coûts et de la latence.
Les types de données de chaînes de caractères varient considérablement en termes d'empreinte de stockage. Une colonne CHAR réserve toujours sa longueur totale déclarée, en la complétant par des espaces même si vous stockez une valeur courte. En revanche, une colonne VARCHAR n'utilise que l'espace nécessaire pour la valeur réellement stockée. Si la plupart des noms de vos clients comptent moins de 30 caractères, les stocker sous la forme VARCHAR(50) permet d'économiser un espace considérable par rapport à CHAR(50). Cette économie d'espace s'accumule sur des millions de lignes et peut réduire la latence des requêtes car davantage de données s'intègrent dans la mémoire disponible.
Les types numériques influencent également les performances. Utiliser BIGINT alors que INT suffirait gaspille du stockage et du calcul. À l'inverse, utiliser SMALLINT pour une colonne qui doit stocker des valeurs supérieures à 32 000 provoque des erreurs de dépassement de capacité (overflow). Comprendre les exigences de plage et de précision de vos données vous permet de choisir le type de données le plus petit qui contient vos valeurs en toute sécurité, ce qui permet de garder votre base de données rapide et légère.
Les index, qui accélèrent considérablement les performances des requêtes, sont plus rapides lorsqu'ils sont définis sur des types de données appropriés. Un index sur une colonne TINYINT est plus efficace qu'un index sur une colonne TEXT. En choisissant des types numériques de taille appropriée et en évitant les index sur de très grandes colonnes de texte, vous multipliez les avantages de l'indexation en termes de performances sur l'ensemble de votre charge de travail. Les moteurs de requêtes distribués comme Apache Spark bénéficient particulièrement de types de données de taille appropriée, car les types plus petits réduisent les transferts réseau lors des opérations de mélange (shuffle).
La règle d'or pour la sélection du type de données est d'utiliser le type le plus petit qui stocke vos données en toute sécurité. Ce principe, appliqué de manière cohérente lors de la conception du schéma, porte ses fruits en termes d'efficacité de stockage, de rapidité des requêtes et d'évolutivité du système. Avant de sélectionner un type, posez-vous les questions suivantes : Quelle est la valeur maximale que cette colonne pourrait contenir ? De quel niveau de précision ai-je besoin ? Cette valeur sera-t-elle un jour NULL ?
Pour les données numériques, examinez la distribution réelle de vos données. Si une colonne contient des valeurs comprises entre 0 et 100, TINYINT est parfait. Si vous stockez des ID clients qui pourraient dépasser 2 milliards, INT suffit ; n'utilisez BIGINT que si vous avez réellement besoin de stocker des valeurs supérieures à 2 milliards. Faire cette distinction sur des dizaines de colonnes de votre schéma peut réduire la taille totale de la table de 20 à 30 %, améliorant ainsi directement les performances des requêtes.
Lorsque vous travaillez avec des chaînes de caractères, tenez compte du compromis entre le stockage et la flexibilité. CHAR vous oblige à choisir une longueur maximale et utilise toujours cet espace. VARCHAR vous permet de stocker efficacement des données de longueur variable, mais vous oblige à choisir un maximum qui n'entraînera pas de troncature. VARCHAR(50) pour les noms offre un bon équilibre : il est assez grand pour pratiquement tous les noms, mais empêche le stockage accidentel de valeurs extrêmement longues qui pourraient poser des problèmes de qualité des données. Pour les blocs de texte très volumineux, comme les corps d'articles ou les messages de journal (logs), utilisez les types TEXT ou CLOB qui ne nécessitent pas de spécification de longueur préalable.
Validez vos choix avec des échantillons de données avant de les déployer en production. Insérez des données réelles dans une table de test avec le schéma proposé et observez l'utilisation réelle du stockage. Exécutez les requêtes prévues et mesurez les performances. Cette approche empirique permet de vérifier si vos choix prennent en charge la charge de travail que vous exécutez réellement. Les plateformes de bases de données proposent généralement des outils pour analyser les plans d'exécution des requêtes et identifier les opérations lentes causées par des types de données sous-optimaux.
Les types de données numériques stockent des nombres et se divisent en deux grandes familles : les types d'entiers pour les nombres entiers, et les types décimaux ou à virgule flottante pour les nombres avec des parties fractionnaires.
Les types d'entiers représentent des nombres entiers sans décimales. Le type de données INTEGER, également appelé INT, est le choix le plus courant pour les valeurs entières et stocke un nombre de 4 octets pouvant représenter des valeurs allant d'environ -2 milliards à +2 milliards. Lorsque vous avez besoin d'une plage plus petite (par exemple, pour stocker des valeurs d'âge qui ne dépasseront pas 127), TINYINT n'utilise qu'un seul octet et s'avère parfait. SMALLINT occupe deux octets et gère des valeurs allant jusqu'à environ 32 000, ce qui est utile pour les colonnes telles que les quantités ou les totaux qui restent relativement petits. BIGINT, un entier de 8 octets, s'adapte aux nombres astronomiques et est nécessaire pour stocker des ID générés à partir de systèmes distribués ou des horodatages mesurés en millisecondes.
Le type de données DECIMAL, parfois appelé NUMERIC dans la documentation standard SQL, stocke des nombres à précision fixe adaptés aux calculs financiers et à d'autres contextes où les erreurs d'arrondi sont inacceptables. DECIMAL stocke des valeurs exactes sans l'approximation inhérente à l'arithmétique en virgule flottante. Lorsque vous définissez DECIMAL(10,2), vous dites : « Je veux stocker des nombres contenant jusqu'à 10 chiffres au total, dont exactement 2 chiffres se trouvent à droite de la virgule décimale. » Cette précision signifie que DECIMAL(10,2) stocke en toute sécurité des valeurs telles que 99999999.99 mais rejettera tout ce qui comporte plus de deux décimales. Les banques et les systèmes comptables s'appuient sur DECIMAL car les réglementations financières exigent des calculs exacts et vérifiables sans erreurs d'arrondi.
NUMERIC sert de nom standard SQL pour les données décimales à précision fixe et se comporte de manière identique à DECIMAL dans la plupart des systèmes de bases de données. Certaines bases de données utilisent NUMERIC et DECIMAL de manière interchangeable, tandis que d'autres les documentent séparément pour des raisons historiques. Consultez la documentation de votre base de données pour confirmer le comportement exact, mais considérez-les comme fonctionnellement équivalents dans la pratique.
La création d'une table avec des colonnes numériques illustre ces types en contexte. Une table de ventes typique pourrait ressembler à ceci :
Ici, employee_id utilise INT car les identifiants d'employés se comptent généralement en millions. Age utilise TINYINT car l'âge d'un être humain ne dépasse jamais 127 ans. Salary et bonus_percentage utilisent DECIMAL pour garantir des calculs précis lors du traitement de la paie, où même d'infimes erreurs d'arrondi s'accumulent à l'échelle d'une entreprise. Les plateformes de données modernes comme Delta Lake appliquent ces types de manière stricte, garantissant que les données dont le type est incorrect ne peuvent pas être insérées dans les tables de production.
Les types à virgule flottante stockent des valeurs numériques approximatives avec une précision spécifiée. FLOAT et DOUBLE utilisent la représentation binaire IEEE 754, qui sacrifie l'exactitude au profit de la vitesse et de la plage de valeurs. Un FLOAT occupe généralement 4 octets et stocke des valeurs approximatives, tandis que DOUBLE occupe 8 octets et offre une plus grande précision.
La représentation à virgule flottante introduit des artefacts d'arrondi car de nombreuses valeurs décimales ne peuvent pas être représentées exactement en binaire. Par exemple, 0,1 ne peut pas être représenté exactement en binaire à virgule flottante, de sorte que tout calcul impliquant 0,1 peut être légèrement faussé. Ces infimes erreurs s'accumulent dans de longues chaînes de calculs, finissant par produire des résultats visiblement incorrects. Pour cette raison, vous ne devriez jamais utiliser FLOAT ou DOUBLE pour des données monétaires ou d'autres valeurs pour lesquelles l'exactitude est essentielle.
Le choix approprié entre DECIMAL et FLOAT dépend de votre cas d'usage. Utilisez DECIMAL pour toutes les données financières, les mesures scientifiques précises ou les calculs dont l'exactitude doit être vérifiable. Utilisez FLOAT pour les approximations, le calcul scientifique où de petites erreurs sont acceptables, ou les caractéristiques de machine learning (features) où la légère imprécision n'affecte pas la qualité du modèle. Les performances des requêtes s'améliorent avec l'utilisation de types de données de taille appropriée, et les opérations sur les FLOAT sont plus rapides que celles sur les DECIMAL car le calcul en virgule flottante bénéficie d'une accélération matérielle sur tous les processeurs modernes.
Comparez ces deux approches pour stocker les prix des produits :
La seconde version garantit que les prix comme 19,99 sont stockés de manière exacte, sans jamais subir d'erreurs d'arrondi lors des calculs ou de l'affichage. La première version pourrait représenter 19,99 sous la forme 19,989999... en interne, ce qui provoquerait de subtiles divergences dans les calculs totaux et les prix affichés aux clients.
Les types de date et d'heure stockent des informations temporelles : le moment où les événements se sont produits ou le moment où les données doivent être considérées comme pertinentes. Ces types sont essentiels pour l'analyse de séries temporelles, la journalisation d'événements et les processus métier qui suivent le moment où les choses se produisent.
Le type DATE stocke uniquement la partie date (année, mois et jour) au format YYYY-MM-DD, sans aucun composant horaire. Utilisez DATE lorsqu'uniquement le jour où un événement s'est produit vous intéresse, comme la date de naissance d'un client ou la date d'une transaction, sans vous soucier de l'heure ou de la minute exacte. DATE occupe un espace de stockage minimal (généralement 3 octets) et simplifie les requêtes qui regroupent les événements par jour civil.
Le type TIME stocke uniquement la partie heure (heures, minutes et secondes), sans date. TIME est moins courant que DATE ou TIMESTAMP, mais apparaît dans les schémas qui enregistrent des horaires récurrents, comme les heures d'ouverture ou les heures de rendez-vous au cours d'une journée.
Le type TIMESTAMP (appelé DATETIME dans certains systèmes comme MySQL et SQL Server) stocke à la fois les informations de date et d'heure au format YYYY-MM-DD HH:MM:SS. TIMESTAMP capture le moment complet où un événement s'est produit, avec une précision à la seconde (ou plus fine, selon votre base de données). La plupart des systèmes événementiels utilisent TIMESTAMP pour enregistrer précisément le moment où les entrées de journal ont été créées, les commandes passées ou les lectures de capteurs reçues. De nombreux systèmes analytiques conçus avec des modèles de schéma en étoile utilisent des clés TIMESTAMP pour une analyse temporelle efficace et le suivi des faits historiques.
Choisissez entre DATE et TIMESTAMP en fonction de vos modèles de requête. Si votre logique métier regroupe les événements par date civile et n'a jamais besoin d'une précision infra-journalière, DATE est plus propre et plus efficace. Si vous devez calculer le temps écoulé entre des événements, détecter des tendances au cours d'une même heure ou maintenir un ordre chronologique précis, TIMESTAMP est nécessaire.
Exemples de définitions de colonnes de date et d'heure :
Ici, birthdate utilise DATE car seule la date de naissance de la personne vous intéresse, pas l'heure à laquelle elle est née. account_creation_date utilise TIMESTAMP car vous devez savoir précisément quand le compte a été créé, potentiellement pour détecter des modèles de fraude ou calculer l'âge du compte en jours. preferred_contact_time utilise TIME car vous stockez une heure récurrente comme « m'appeler à 14 h » sans date spécifique.
La gestion des fuseaux horaires est un problème subtil mais critique dans les données temporelles. Lorsque vous enregistrez qu'un événement s'est produit à « 2024-03-15 14:30:00 », cela signifie-t-il 14 h 30 à New York, à Tokyo ou en UTC ? La réponse est importante car une même heure locale signifie des choses différentes selon les fuseaux horaires.
La bonne pratique consiste à stocker tous les horodatages en UTC (Coordinated Universal Time), une référence temporelle indépendante du fuseau horaire. Lorsque votre application reçoit un événement de la part d'un utilisateur dans n'importe quel fuseau horaire, convertissez-le en UTC avant de le stocker dans votre base de données. Cette approche garantit que tous les horodatages sont comparables et que vous pouvez répondre de manière univoque à des questions telles que « quels événements se sont produits en premier ? » ou « combien de temps s'est écoulé entre ces événements ? ».
Certaines bases de données comme PostgreSQL prennent en charge TIMESTAMPTZ (timestamp with time zone), qui stocke à la fois l'horodatage et les informations de fuseau horaire associées. Lorsque vous récupérez des données, la base de données convertit l'horodatage UTC vers le fuseau horaire d'origine si nécessaire. Cette approche préserve le contexte du fuseau horaire d'origine tout en garantissant la cohérence interne.
Le type DATETIME de SQL Server et le type DATETIME de MySQL n'incluent pas d'informations de fuseau horaire. Convertissez donc les heures en UTC avant de les stocker, puis effectuez la conversion inverse lors de l'affichage aux utilisateurs. Les paramètres de session affectent la façon dont les horodatages sont interprétés dans certaines bases de données, alors documentez clairement vos hypothèses.
Les types de données de caractères stockent du texte et se déclinent en variantes de longueur fixe et de longueur variable, chacune étant adaptée à différents scénarios.
CHAR stocke des chaînes de longueur fixe et utilise toujours la totalité de la longueur déclarée, en complétant par des espaces si la valeur réelle est plus courte. CHAR(10) occupe toujours exactement 10 octets par ligne, même si vous insérez « hello » (5 caractères). CHAR excelle lorsque presque toutes les valeurs ont la même longueur, comme les codes postaux américains (5 chiffres) ou les codes pays (2 lettres). Le stockage de longueur fixe simplifie l'indexation et rend la taille des analyses de table prévisible.
VARCHAR stocke des chaînes de longueur variable et n'utilise que l'espace nécessaire pour les données réelles, plus un léger surcoût pour enregistrer la longueur. VARCHAR(100) stockant « hello » occupe environ 7 octets (5 pour « hello » plus 2 pour le codage de la longueur), ce qui permet d'économiser 93 octets par rapport à CHAR(100) pour la même valeur. Le dimensionnement de VARCHAR doit être pensé en fonction des données réelles : choisissez VARCHAR(50) pour les noms uniquement si vous êtes sûr qu'ils ne dépasseront pas 50 caractères. Si les noms font généralement 30 caractères mais peuvent parfois atteindre 50, VARCHAR(50) est prudent.
TEXT accueille de grands blocs de texte non structuré sans longueur maximale déclarée. Utilisez TEXT pour les articles, les commentaires ou les documents dont la taille varie considérablement. Certaines bases de données font la distinction entre TEXT et des types plus spécialisés comme CLOB (Character Large Object), mais la plupart des systèmes modernes gèrent TEXT de manière efficace grâce à la compression interne et au streaming.
Pour le texte international contenant des caractères de plusieurs langues, utilisez des types compatibles Unicode : les variantes NVARCHAR ou UTF8 selon votre base de données. NVARCHAR (national VARCHAR) dans SQL Server stocke du texte encodé en UTF-16 prenant en charge n'importe quel caractère Unicode. PostgreSQL et MySQL prennent en charge les jeux de caractères UTF-8 directement dans VARCHAR avec les paramètres de collation appropriés. Définissez toujours explicitement l'encodage des caractères lors de la création de tables afin d'éviter tout comportement inattendu si la valeur par défaut de la base de données change.
Exemples de définitions de colonnes de chaînes :
Ici, first_name et last_name utilisent VARCHAR car les noms sont généralement courts mais variables, ce qui permet d'économiser de l'espace par rapport à CHAR. biography utilise TEXT car les biographies des clients peuvent aller d'une simple phrase à un paragraphe entier. country_code utilise CHAR(2) car tous les codes pays font exactement 2 lettres, ce qui rend le stockage de longueur fixe approprié.
Les types de données binaires stockent des données binaires brutes (des séquences d'octets) plutôt que du texte. Ces types sont utiles pour stocker des images, des fichiers, des hachages cryptographiques et d'autres contenus non textuels.
BLOB (Binary Large Object) stocke des données binaires arbitraires sans limite de taille maximale. Utilisez BLOB pour les images, les documents PDF, les vidéos ou tout contenu binaire non structuré qui ne correspond pas aux types standards. BLOB est approprié lorsque vous devez stocker des fichiers dans votre base de données, bien que de nombreux systèmes de production préfèrent stocker les fichiers volumineux dans des systèmes de stockage d'objets comme Amazon S3 et ne conserver que les références de fichiers dans la base de données.
VARBINARY stocke des données binaires de longueur variable avec une taille maximale explicite. VARBINARY(256) stocke jusqu'à 256 octets de données binaires, n'occupant que l'espace nécessaire au contenu réel. VARBINARY fonctionne bien pour les données binaires de taille fixe telles que les signatures cryptographiques, les sommes de contrôle (checksums) ou les UUID.
Le type BINARY stocke des données binaires de longueur fixe, en les complétant par des octets nuls si nécessaire. BINARY(16) occupe toujours exactement 16 octets, ce qui est utile pour stocker des identifiants de taille fixe comme les UUID de 128 bits. Le type BINARY doit être dimensionné avec soin, car le gaspillage d'espace dû à des déclarations trop volumineuses nuit aux performances.
En pratique, il est généralement préférable de stocker les fichiers volumineux dans un stockage d'objets plutôt que dans des bases de données. Le stockage d'objets est moins cher, plus rapide pour les fichiers volumineux et évolue plus facilement que le stockage en base de données. Conservez la référence du fichier et les métadonnées dans la base de données, et non le fichier lui-même.
Exemples de définitions de colonnes binaires :
Ici, content utilise BLOB pour stocker les données réelles du document. checksum utilise VARBINARY pour stocker un hachage SHA-256 (32 octets) qui vérifie que le document n'a pas été corrompu. uuid utilise BINARY(16) pour stocker un identifiant UUID de taille fixe.
L'indexation des colonnes binaires est délicate car les index B-tree traditionnels supposent que les valeurs sont triables et comparables. Vous pouvez indexer les colonnes BINARY sur des correspondances exactes, mais pas sur des requêtes de plage. Évitez d'indexer les colonnes BLOB à moins que votre base de données ne dispose d'index bitmap ou de hachage spécialisés conçus pour les données binaires.
Pour vérifier l'intégrité des données d'un contenu binaire, gérez une colonne checksum distincte stockant un hachage des données binaires. Si vous soupçonnez une corruption, recalculez le hachage et comparez-le à la valeur stockée. Cette approche est beaucoup plus rapide que de réexaminer l'intégralité du contenu binaire.
Les types de données booléens stockent des valeurs vrai/faux, essentielles pour les indicateurs, les états et les décisions oui/non. Les valeurs vrai et faux simplifient la modélisation des données et évitent les états non valides comme NULL ou les chaînes ambiguës comme "yes" ou "1".
Différentes bases de données implémentent les booléens différemment. PostgreSQL dispose d'un type BOOLEAN natif acceptant true/false, yes/no, on/off, 1/0 sous différents formats. MySQL traite BOOLEAN comme un petit entier, en lui attribuant l'alias TINYINT(1), où 1 représente vrai et 0 représente faux. SQL Server utilise BIT pour les données de type booléen, stockant 1 pour vrai et 0 pour faux à l'aide d'un seul bit par valeur (bien que le stockage réel varie).
Il est important de comprendre les différences entre les fournisseurs lors de la migration de schémas entre bases de données. Un type BOOLEAN PostgreSQL n'a pas d'équivalent direct dans SQL Server — vous utiliseriez plutôt BIT. Le code d'application qui suppose que l'entrée vrai/faux de PostgreSQL est flexible (elle accepte "yes", "on", "1") pourrait ne pas fonctionner avec les exigences strictes de 0/1 de SQL Server.
Exemples de définitions de booléens :
Tous trois sont fonctionnellement identiques pour stocker des valeurs vrai/faux, mais les noms des types sous-jacents diffèrent et le comportement d'entrée/sortie varie subtilement.
Le transtypage convertit une valeur d'un type de données à un autre, ce qui est essentiel lorsque des données provenant de différentes sources doivent être combinées ou lorsque vous devez modifier la façon dont une valeur est interprétée.
La conversion implicite se produit automatiquement lorsque la base de données convertit les types pour rendre une opération possible. INSERT INTO table_name (int_column) VALUES ('123') peut convertir implicitement la chaîne '123' en entier 123. La conversion implicite est pratique mais risquée — la base de données peut effectuer des conversions que vous n'aviez pas prévues, ou la conversion peut échouer silencieusement, produisant des résultats inattendus.
La conversion explicite à l'aide de CAST ou CONVERT vous offre un contrôle précis et clarifie vos intentions pour les autres développeurs. Le transtypage explicite évite les surprises silencieuses et rend les performances des requêtes plus prévisibles.
Les conversions courantes incluent le transtypage de chaînes en nombres pour les calculs, le transtypage de nombres en chaînes pour la concaténation, et le transtypage en DATE ou TIMESTAMP pour filtrer par plages temporelles.
Exemple d'utilisation de CAST :
Ces conversions explicites rendent le code clair : quiconque lit la requête comprend immédiatement qu'une conversion a lieu et sait exactement quel type est produit.
Les types de données SQL varient entre MySQL, PostgreSQL, SQL Server et Oracle. Bien que les concepts fondamentaux (numérique, caractère, date/heure, binaire) soient universels, les noms de types spécifiques, la précision et les caractéristiques de stockage diffèrent.
MySQL utilise TINYINT pour les valeurs booléennes (en attribuant l'alias BOOLEAN à TINYINT(1)), VARCHAR pour les chaînes variables et BLOB pour les données binaires. PostgreSQL prend en charge BOOLEAN de manière native, TEXT pour le texte volumineux sans limite de taille et BYTEA pour les données binaires. SQL Server utilise INT et BIGINT comme la plupart des bases de données, VARCHAR pour les chaînes et IMAGE pour les données binaires volumineuses. Oracle utilise NUMBER pour les valeurs numériques, VARCHAR2 pour les chaînes (et non VARCHAR) et BLOB pour les données binaires.
Ces différences sont importantes lors de la migration de schémas. Une colonne TEXT PostgreSQL peut contenir n'importe quelle quantité de données, mais le type TEXT MySQL a une limite de 64 Ko et nécessite LONGTEXT pour un contenu plus volumineux. Le type VARCHAR(MAX) de SQL Server est nécessaire pour le texte très volumineux, tandis que le type TEXT de PostgreSQL le gère directement. Le type NUMBER d'Oracle est plus flexible que les types numériques de la plupart des bases de données, vous permettant de spécifier la précision et l'échelle différemment.
Consultez la documentation officielle de votre base de données avant de concevoir des schémas destinés à être portables. Testez vos données réelles avec votre système de base de données cible pour identifier les cas limites où les hypothèses sur le comportement des types ne se vérifient pas.
Privilégiez les types à précision fixe comme DECIMAL pour les données financières, en évitant totalement les types à virgule flottante dans les systèmes de comptabilité ou de facturation. La précision financière n'est pas négociable, et l'exactitude de DECIMAL vaut bien le léger coût en performances. Les organisations qui conçoivent des systèmes d'analyse sur des plateformes de data warehouse modernes accordent de plus en plus d'importance à la sélection appropriée des types de données comme fondement de la gouvernance et des performances.
Évitez d'utiliser des chaînes de caractères pour les dates ou les booléens, même si cela est techniquement possible. Le stockage des dates sous forme de VARCHAR rend l'arithmétique des dates difficile, empêche la base de données d'optimiser les requêtes basées sur les dates et complique la validation. Le stockage des booléens sous forme de chaînes introduit une ambiguïté — "false" est-il identique à "no" ? — et gaspille de l'espace de stockage. Utilisez les types natifs DATE, TIMESTAMP et BOOLEAN qui sont spécialement conçus pour ces valeurs.
Examinez et optimisez les types lors des audits de schémas, en particulier lorsque les bases de données existent depuis des années et que les modèles d'utilisation ont changé. Une colonne définie comme VARCHAR(1000) pour des raisons qui ne s'appliquent plus gaspille de l'espace sur chaque ligne. Utilisez EXPLAIN PLAN ou les outils d'analyse de requêtes de votre base de données pour identifier les requêtes lentes causées par de mauvais choix de types, puis procédez à une refactorisation.
Documentez vos choix de types, en particulier les cas limites et les hypothèses. Un commentaire expliquant pourquoi une colonne est TINYINT au lieu d'INT évite que quelqu'un ne la modifie plus tard en se basant sur une compréhension incomplète. Cette documentation est particulièrement importante pour les types numériques où la plage de valeurs est essentielle.
Le type CHAR stocke des chaînes de longueur fixe et utilise toujours la taille totale déclarée, en la complétant par des espaces. Le type VARCHAR stocke des chaînes de longueur variable et n'utilise que l'espace nécessaire pour les données réelles. CHAR est plus efficace pour les données de taille fixe comme les codes pays (toujours 2 lettres), tandis que VARCHAR est plus efficace pour les données de longueur variable comme les noms. Les types de données de chaîne imposent des règles sur la saisie des données dans les colonnes SQL, et le choix entre CHAR et VARCHAR affecte à la fois le stockage et les performances de votre système de base de données.
Le type DECIMAL stocke des valeurs exactes et évite les erreurs d'arrondi, ce qui le rend indispensable pour les données financières où la précision est essentielle. Le type FLOAT stocke des valeurs approximatives plus rapidement mais introduit des artefacts d'arrondi. Utilisez DECIMAL pour les montants monétaires, les mesures scientifiques précises et les calculs dont l'exactitude doit être vérifiable. Utilisez FLOAT pour les approximations, les caractéristiques de machine learning et le calcul scientifique où de petites erreurs sont acceptables. Le choix du bon type de données est essentiel pour l'intégrité des données dans les systèmes financiers.
Utilisez DATE lorsque vous avez uniquement besoin d'enregistrer la date du calendrier sans informations d'heure, comme la date de naissance d'un client ou la date d'une transaction. Utilisez TIMESTAMP lorsque vous avez besoin d'informations temporelles précises incluant les heures, les minutes et les secondes, comme les horodatages d'événements ou les heures de finalisation des transactions. Les types de date et d'heure sont utilisés pour enregistrer le moment où les événements se produisent, et la sélection du bon type simplifie les requêtes et évite le gaspillage de stockage.
Les longueurs maximales varient selon la base de données. VARCHAR prend généralement en charge des longueurs allant jusqu'à 65 535 octets dans MySQL, illimitées dans PostgreSQL, et jusqu'à 8 000 octets dans SQL Server (ou VARCHAR(MAX) pour les valeurs plus volumineuses). Vérifiez toujours la documentation spécifique de votre base de données pour connaître les limites exactes. Le choix de types appropriés peut améliorer l'évolutivité à long terme et éviter d'atteindre des limites de stockage inattendues.
Stockez tous les horodatages en UTC pour garantir la cohérence et la comparabilité. Convertissez les horodatages en UTC avant de les stocker et convertissez-les à nouveau dans le fuseau horaire local de l'utilisateur lors de l'affichage. Certaines bases de données comme PostgreSQL prennent en charge TIMESTAMPTZ pour gérer automatiquement cette conversion. Une gestion cohérente des fuseaux horaires évite les bogues dans les calculs basés sur le temps et rend l'ordonnancement des événements sans ambiguïté.
Les valeurs UUID utilisent généralement BINARY(16) pour le stockage à taille fixe ou CHAR(36) pour la représentation sous forme de chaîne standard incluant des traits d'union. Certaines bases de données comme PostgreSQL prennent en charge les types UUID natifs. INT ou BIGINT conviennent pour les identifiants numériques à incrémentation automatique. Choisissez en fonction de votre schéma d'identification : les identifiants numériques séquentiels sont simples mais facilitent la devinette des identifiants, tandis que les UUID sont aléatoires et adaptés aux systèmes distribués.
Les types de données plus petits permettent de stocker plus de lignes dans le cache du processeur, ce qui accélère les requêtes. Les index sont plus efficaces sur des types numériques de taille appropriée. L'efficacité du stockage réduit les E/S disque et améliore la latence des requêtes. Les performances des requêtes s'améliorent avec l'utilisation de types de données de taille appropriée, et le choix du type le plus petit qui contient vos données en toute sécurité permet de garder les bases de données rapides et légères.
(Cet article de blog a été traduit à l'aide d'outils basés sur l'intelligence artificielle) Article original
Abonnez-vous à notre blog et recevez les derniers articles directement dans votre boîte mail.