Les types numériques sont constitués d'entiers de deux, quatre ou huit octets, de nombres à virgule flottante de quatre ou huit octets et de décimaux dont la précision peut être indiquée. Le Tableau 8.2 précise les types disponibles.
Tableau 8.2. Types numériques
| Nom | Taille de stockage | Description | Étendue | 
|---|---|---|---|
| smallint | 2 octets | entier de faible étendue | de -32768 à +32767 | 
| integer | 4 octets | entier habituel | de -2147483648 à +2147483647 | 
| bigint | 8 octets | grand entier | de -9223372036854775808 à +9223372036854775807 | 
| decimal | variable | précision indiquée par l'utilisateur, valeur exacte | jusqu'à 131072 chiffres avant le point décimal ; jusqu'à 16383 après le point décimal | 
| numeric | variable | précision indiquée par l'utilisateur, valeur exacte | jusqu'à 131072 chiffres avant le point décimal ; jusqu'à 16383 après le point décimal | 
| real | 4 octets | précision variable, valeur inexacte | précision de 6 décimales | 
| double precision | 8 octets | précision variable, valeur inexacte | précision de 15 décimales | 
| smallserial | 2 bytes | Entier sur 2 octets à incrémentation automatique | 1 to 32767 | 
| serial | 4 octets | entier à incrémentation automatique | de 1 à 2147483647 | 
| bigserial | 8 octets | entier de grande taille à incrémentation automatique | de 1 à 9223372036854775807 | 
La syntaxe des constantes pour les types numériques est décrite dans la Section 4.1.2. Les types numériques ont un ensemble complet d'opérateurs arithmétiques et de fonctions. On peut se référer au Chapitre 9 pour plus d'informations. Les sections suivantes décrivent ces types en détail.
    Les types smallint, integer et
    bigint stockent des nombres entiers, c'est-à-dire sans
    décimale, de différentes étendues. Toute tentative d'y stocker une valeur
    en dehors de l'échelle produit une erreur.
   
    Le type integer est le plus courant. Il offre un bon
    compromis entre capacité, espace utilisé et performance. Le type
    smallint n'est utilisé que si l'économie d'espace disque est
    le premier critère de choix. Le type bigint est conçu pour
    n'être utilisé que si l'échelle de valeurs du type integer
    n'est pas suffisante.
   
    SQL ne définit que les types de données
    integer (ou int), smallint et
    bigint. Les noms de types int2,
    int4, et int8 sont des extensions, partagées par
    d'autres systèmes de bases de données SQL.
   
    Le type numeric peut stocker des nombres contenant un très
    grand nombre de chiffres. Il est spécialement recommandé pour stocker les
    montants financiers et autres quantités pour lesquels l'exactitude est
    indispensable. Les calculs avec des valeurs numeric renvoient
    des résultats exacts quand c'est possible (addition, soustraction,
    multiplication). Néanmoins, les calculs sur les valeurs
    numeric sont très lents comparés aux types entiers ou aux
    types à virgule flottante décrits dans la section suivante.
   
    Dans ce qui suit, on utilise les termes suivants. La
    précision d'un numeric est le nombre
    total de chiffres significatifs dans le nombre complet, c'est-à-dire le
    nombre de chiffres de part et d'autre du séparateur.
    L'échelle d'un numeric est le nombre
    de chiffres décimaux de la partie fractionnaire, à droite du séparateur de
    décimales. Donc, le nombre 23.5141 a une précision de 6 et une échelle de
    4. On peut considérer que les entiers ont une échelle de 0.
   
    La précision maximale et l'échelle maximale d'une colonne
    numeric peuvent être toutes deux réglées. Pour déclarer une
    colonne de type numérique, il faut utiliser la syntaxe :
    
NUMERIC(précision,échelle)
La précision doit être strictement positive, alors que l'échelle peut être positive ou négative (voir ci-dessous). Alternativement :
NUMERIC(précision)indique une échelle de 0.
NUMERIC
     sans précision ni échelle crée une « colonne non contrainte »
     dans laquelle on peut stocker des valeurs de n'importe quelle longueur,
     dans les limites de l'implémentation. Une colonne de ce type n'impose
     aucune précision
     à la valeur entrée, alors que les colonnes numeric ayant une
     échelle forcent les valeurs entrées à cette échelle. (Le standard
     SQL demande une précision par défaut de 0,
     c'est-à-dire de forcer la transformation en entier. Les auteurs trouvent
     cela inutile. Dans un souci de portabilité, il est préférable de toujours
     indiquer explicitement la précision et l'échelle.)
    
      La précision maximale autorisée qui peut être explicitement spécifiée
      dans la déclaration du type est de 1000. Une donnée numeric sans
      contrainte est sujet aux limites décrites dans Tableau 8.2.
     
Si l'échelle d'une valeur à stocker est supérieure à celle de la colonne, le système arrondit la valeur au nombre de décimales indiqué pour la colonne. Si le nombre de chiffres à gauche du point décimal est supérieur à la différence entre la précision déclarée et l'échelle déclarée, une erreur est levée. Par exemple, une colonne déclarée comme
NUMERIC(3, 1)
voit ses valeurs arrondies à une place décimale et peut enregistrer des valeurs entre -99,9 et 99,9, valeurs inclues.
     À partir de PostgreSQL, il est autorisé de
     déclarer une colonne de type numeric avec une échelle
     négative. Les valeurs sont alors arrondies à partir de la gauche du point
     décimal. La précision représente toujours le nombre maximum de chiffres non
     arrondis. De ce fait, une colonne déclarée ainsi
NUMERIC(2, -3)
arrondira les valeurs au millier le plus proche et peut enregistrer des valeurs entre -99000 et 99000 inclus. Il est aussi autorisé de déclarer une échelle plus grande que la précision déclarée. Une telle colonne peut seulement contenir des valeurs fractionnelles, et elle nécessite le nombre de chiffres zéro juste à droite du point décimal pour être au moins l'échelle déclarée moins la précision déclarée. Par exemple, une colonne déclarée ainsi
NUMERIC(3, 5)
arrondira les valeurs aux 5 places décimales et peut enregistrer des valeurs comprises entre -0,00999 et 0,00999, valeurs inclues.
      PostgreSQL permet à l'échelle dans une
      déclaration de type numeric d'être toute valeur dans
      l'échelle de -1000 à 1000. Néanmoins, le standard SQL
      requiert que l'échelle soit dans l'intervalle 0 à
      precision. Utiliser des échelles en dehors de
      cet interval peut ne pas autre portable auprès d'autres systèmes de bases
      de données.
     
     Les valeurs numériques sont stockées physiquement sans zéro avant ou
     après. Du coup, la précision déclarée et l'échelle de la colonne sont des
     valeurs maximales, pas des allocations fixes (en ce sens, le type
     numérique est plus proche de
     varchar( que de
     n)char(). Le besoin pour le
     stockage réel est de deux octets pour chaque groupe de quatre chiffres
     décimaux, plus trois à huit octets d'en-tête.
    n)
     En plus des valeurs numériques ordinaires, le type numeric
     a plusieurs valeurs spéciales :
     
      Infinity
      -Infinity
      NaN
     
     Ces valeurs sont adaptées du standard IEEE 754, et représentent
     respectivement « l'infini », « l'infini négatif »
     et « pas-un-nombre ». Pour écrire ces valeurs sous forme de
     constantes dans une commande SQL, vous devez les mettre entre
     guillemets, par exemple UPDATE table SET x
     = '-Infinity'. En entrée, ces chaînes sont reconnues quelque
     soit leur casse. Les valeurs infinis peuvent s'écrire alternativement
     inf et -inf.
    
     Les valeurs infinies se comportent comme attendues mathématiquement. Par
     exemple, Infinity plus n'importe quelle valeur finie
     donne Infinity ; mais
     Infinity moins Infinity retourne
     NaN (pas un nombre) parce qu'il n'y a pas
     d'interprétation correcte possible. Notez que l'infini peut être
     seulement employé dans une colonne numeric sans contrainte,
     parce que sa notion dépasse n'importe quelle précision finie.
    
     La valeur NaN est utilisée pour représenter un
     résultat non défini d'un calcul. En général, n'importe quelle opération
     avec une entrée NaN donne un autre
     NaN. La seule exception est quand les autres entrées
     de l'opération sont telles que le même résultat serait obtenu si les
     valeurs NaN étaient remplacées par n'importe quelle
     valeur numérique finie ou infinie ; ainsi, ce résultat est utilisé
     aussi pour NaN. (Un exemple de cette notion est que
     NaN élevé à la puissance zéro donne un.)
    
      Dans la plupart des implémentations du concept
      « not-a-number », NaN est considéré
      différent de toute valeur numérique (ceci incluant
      NaN). Pour autoriser le tri des valeurs de type
      numeric et les utiliser dans des index basés sur le tri,
      PostgreSQL traite les valeurs
      NaN comme identiques entre elles, mais toutes
      supérieures aux valeurs non NaN.
     
     Les types decimal et numeric sont équivalents.
     Les deux types sont dans le standard SQL.
    
     Lors de l'arrondissement de valeurs, le type numeric
     arrondit en s'éloignant de zéro, alors que (sur la plupart des machines)
     les types real et double precision arrondissent
     vers le nombre le plus proche. Par exemple :
SELECT x,
  round(x::numeric) AS num_round,
  round(x::double precision) AS dbl_round
FROM generate_series(-3.5, 3.5, 1) as x;
  x   | num_round | dbl_round
------+-----------+-----------
 -3.5 |        -4 |        -4
 -2.5 |        -3 |        -2
 -1.5 |        -2 |        -2
 -0.5 |        -1 |        -0
  0.5 |         1 |         0
  1.5 |         2 |         2
  2.5 |         3 |         2
  3.5 |         4 |         4
(8 rows)
    
    Les types de données real et double precision
    sont des types numériques inexacts de précision variable. Sur toutes les
    plateformes actuellement supportées, ces types sont une implémentation du
    « IEEE Standard 754 for Binary Floating-Point
     Arithmetic » (respectivement, simple et double précision), suivant
    le support fourni par le processeur, le système d'exploitation et le
    compilateur.
   
Inexact signifie que certaines valeurs ne peuvent être converties exactement dans le format interne. Elles sont, de ce fait, stockées sous une forme approchée. Ainsi, stocker puis réafficher ces valeurs peut faire apparaître de légers écarts. Prendre en compte ces erreurs et la façon dont elles se propagent au cours des calculs est le sujet d'une branche entière des mathématiques et de l'informatique, qui n'est pas le sujet de ce document, à l'exception des points suivants :
       pour un stockage et des calculs exacts, comme pour les valeurs
       monétaires, le type numeric doit être privilégié ;
      
pour des calculs compliqués avec ces types pour quoi que ce soit d'important, et particulièrement pour le comportement aux limites (infini, zéro), l'implantation spécifique à la plateforme doit être étudiée avec soin ;
tester l'égalité de deux valeurs à virgule flottante peut ne pas donner le résultat attendu.
    Sur toutes les plates-formes supportées, le type real a une
    étendue d'au moins 1E-37 à 1E37 avec une précision d'au moins six
    chiffres décimaux. Le type double precision a une étendue de
    1E-307 à 1E+308 avec une précision d'au moins quinze chiffres. Les
    valeurs trop grandes ou trop petites produisent une erreur. Un arrondi
    peut avoir lieu si la précision d'un nombre en entrée est trop grande.
    Les nombres trop proches de zéro qui ne peuvent être représentés
    autrement que par zéro produisent une erreur (underflow).
   
    Par défaut, les valeurs à virgule flottante sont renvoyées sous forme de
    texte dans leur représentation décimale la plus courte ; la valeur
    décimale produite est plus proche de la vraie valeur binaire enregistrée
    que toute autre valeur représentable dans la même précision binaire.
    (Néanmoins, la valeur en sortie n'est en fait jamais
    exactement entre deux valeurs représentables, pour
    éviter un bug fréquent où les routines en entrée ne respectent pas la
    règle d'arrondi.) Cette valeur utilisera au plus les 17 chiffres décimaux
    significatifs pour des valeurs float8, et au plus 9 chiffres
    pour des valeurs float4.
   
Ce format de sortie le plus précis tout en étant le plus court est bien plus rapide à générer que le format arrondi historique.
    Pour la compatibilité avec la sortie générée par les anciennes versions
    de PostgreSQL et pour permettre de réduire la
    précision de la sortie, le paramètre extra_float_digits peut être utilisé pour sélectionner
    une sortie décimale arrondie à la place. Configurer une valeur 0 restaure
    le précédent comportement par défaut avec un arrondi à de la valeur aux 6
    (pour float4) ou 15 (pour float8) chiffres
    décimaux significatifs. Configurer une valeur négative réduit encore plus
    le nombre de chiffres ; par exemple, -2 arrondirait la sortie à,
    respectivement, 4 ou 13 chiffres.
   
Toute valeur de extra_float_digits supérieure à 0 sélectionne le format précis le plus court.
Les applications qui voulaient des valeurs précises devaient historiquement configurer extra_float_digits à 3 pour les obtenir. Pour un maximum de compatibilité entre les versions, elles doivent continuer à le faire.
     Le paramètre extra_float_digits contrôle le nombre
     de chiffres significatifs inclus lorsqu'une valeur à virgule flottante
     est convertie en texte. Avec la valeur par défaut de
     0, la sortie est la même sur chaque plateforme
     supportée par PostgreSQL. L'augmenter va produire une sortie
     représentant plus précisément la valeur stockée, mais il est possible
     que la sortie soit différente suivant les plates-formes.
    
En plus des valeurs numériques ordinaires, les types à virgule flottante ont plusieurs valeurs spéciales :
Infinity -Infinity
    NaN
 Elles représentent les valeurs
    spéciales de l'IEEE 754, respectivement « infinity »
    (NdT : infini), « negative infinity » (NdT : infini
    négatif) et « not-a-number » (NdT : pas un nombre).
    Lorsqu'elles sont saisies en tant que constantes dans une commande SQL,
    ces valeurs doivent être placées entre guillemets. Par exemple,
    UPDATE table SET x = '-Infinity'. En entrée, ces
    valeurs sont reconnues, quelle que soit la casse utilisée. Les valeurs
    infinies peuvent être alternativement écrites inf et
    -inf.
   
     IEEE 754 spécifie que NaN ne devrait pas être
     considéré égale à toute autre valeur en virgule flottante (ceci incluant
     NaN). Pour permettre le tri des valeurs en virgule
     flottante et leur utilisation dans des index basés sur des arbres,
     PostgreSQL traite les valeurs
     NaN comme identiques entre elles, mais supérieures à
     toute valeur différente de NaN.
    
    PostgreSQL autorise aussi la notation
    float du standard SQL, ainsi que
    float( pour indiquer des types
    numériques inexacts. p)p indique la précision
    minimale acceptable en chiffres binaires.
    PostgreSQL accepte de float(1) à
    float(24), qu'il transforme en type real, et de
    float(25) à float(53), qu'il transforme en type
    double precision. Toute valeur de
    p hors de la zone des valeurs possibles
    produit une erreur. float sans précision est compris comme
    double precision.
   
Cette section décrit une façon spécifique à PostgreSQL de créer une colonne autoincrémentée. Une autre façon revient à utiliser les colonnes d'identité, décrite sur Section 5.3.
    Les types de données smallserial, serial et
    bigserial ne sont pas de vrais types, mais plutôt un
    raccourci de notation pour créer des colonnes d'identifiants uniques
    (similaires à la propriété AUTO_INCREMENT utilisée par
    d'autres SGBD). Dans la version actuelle, indiquer :
    
CREATE TABLEnom_de_table(nom_de_colonneSERIAL );
est équivalent à écrire :
CREATE SEQUENCEnom_de_table_nom_de_colonne_seq AS integer; CREATE TABLEnom_de_table(nom_de_colonneinteger NOT NULL DEFAULT nextval('nom_de_table_nom_de_colonne_seq') NOT NULL ); ALTER SEQUENCEnom_de_table_nom_de_colonne_seq OWNED BYnom_de_table.nom_de_colonne;
     Ainsi a été créée une colonne d'entiers dont la valeur par défaut est
     assignée par un générateur de séquence. Une contrainte NOT
     NULL est ajoutée pour s'assurer qu'une valeur NULL ne puisse
     pas être insérée. (Dans la plupart des cas, une contrainte
     UNIQUE ou PRIMARY KEY peut être
     ajoutée pour interdire que des doublons soient créés par accident, mais
     ce n'est pas automatique.) Enfin, la séquence est marquée « owned
     by » (possédée par) la colonne pour qu'elle soit supprimée si la
     colonne ou la table est supprimée.
    
      Comme smallserial, serial et
      bigserial sont implémentés en utilisant des séquences, il
      peut y avoir des trous dans la séquence de valeurs qui apparait dans la
      colonne, même si aucune ligne n'est jamais supprimée. Une valeur allouée
      à partir de la séquence est toujours utilisée même si la ligne contenant
      cette valeur n'est pas insérée avec succès dans la colonne de la table.
      Cela peut survenir si la transaction d'insertion est annulée. Voir
      nextval() dans Section 9.17
      pour plus de détails.
     
     Pour insérer la valeur suivante de la séquence dans la colonne
     serial, il faut préciser que la valeur par défaut de la
     colonne doit être utilisée. Cela peut se faire de deux façons : soit
     en excluant cette colonne de la liste des colonnes de la commande
     INSERT, soit en utilisant le mot-clé
     DEFAULT.
    
     Les types serial et serial4 sont
     identiques : ils créent tous les deux des colonnes
     integer. Les types bigserial et
     serial8 fonctionnent de la même façon, mais créent des
     colonnes bigint. bigserial doit être utilisé si
     plus de 231 identifiants sont prévus sur la
     durée de vie de la table. Les noms de type smallserial et
     serial2 fonctionnent de la même façon, sauf qu'ils créent
     une colonne de type smallint.
    
     La séquence créée pour une colonne serial est
     automatiquement supprimée quand la colonne correspondante est supprimée.
     La séquence peut être détruite sans supprimer la colonne, mais la valeur
     par défaut de la colonne est alors également supprimée.