PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Type de données Postgres ENUM ou CHECK CONSTRAINT ?

Sur la base des commentaires et des réponses ici, et de quelques recherches rudimentaires, j'ai le résumé suivant à proposer aux commentaires des Postgres-erati. J'apprécierai vraiment votre contribution.

Il existe trois façons de restreindre les entrées dans une colonne de table de base de données Postgres. Envisagez une table pour stocker les « couleurs » où vous ne voulez que « rouge », « vert » ou « bleu » comme entrées valides.

  1. Type de données énumérées

    CREATE TYPE valid_colors AS ENUM ('red', 'green', 'blue');
    
    CREATE TABLE t (
        color VALID_COLORS
    );
    

    Les avantages sont que le type peut être défini une fois puis réutilisé dans autant de tables que nécessaire. Une requête standard peut répertorier toutes les valeurs d'un type ENUM et peut être utilisée pour créer des widgets de formulaire de candidature.

    SELECT  n.nspname AS enum_schema,  
            t.typname AS enum_name,  
            e.enumlabel AS enum_value
    FROM    pg_type t JOIN 
            pg_enum e ON t.oid = e.enumtypid JOIN 
            pg_catalog.pg_namespace n ON n.oid = t.typnamespace
    WHERE   t.typname = 'valid_colors'
    
     enum_schema | enum_name     | enum_value 
    -------------+---------------+------------
     public      | valid_colors  | red
     public      | valid_colors  | green
     public      | valid_colors  | blue
    

    Les inconvénients sont que le type ENUM est stocké dans les catalogues système, donc une requête comme ci-dessus est nécessaire pour afficher sa définition. Ces valeurs ne sont pas apparentes lors de l'affichage de la définition de table. Et, comme un type ENUM est en fait un type de données distinct des types de données NUMERIC et TEXT intégrés, les opérateurs et fonctions numériques et de chaîne classiques ne fonctionnent pas dessus. Donc, on ne peut pas faire une requête comme

    SELECT FROM t WHERE color LIKE 'bl%'; 
    
  2. Vérifier les contraintes

    CREATE TABLE t (
        colors TEXT CHECK (colors IN ('red', 'green', 'blue'))
    );
    

    Deux avantages sont que, premièrement, "ce que vous voyez est ce que vous obtenez", c'est-à-dire que les valeurs valides pour la colonne sont enregistrées directement dans la définition de la table, et deuxièmement, toutes les chaînes natives ou les opérateurs numériques fonctionnent.

  3. Clés étrangères

    CREATE TABLE valid_colors (
        id SERIAL PRIMARY KEY NOT NULL,
        color TEXT
    );
    
    INSERT INTO valid_colors (color) VALUES 
        ('red'),
        ('green'),
        ('blue');
    
    CREATE TABLE t (
        color_id INTEGER REFERENCES valid_colors (id)
    );
    

    Essentiellement identique à la création d'un type ENUM, sauf que les opérateurs numériques ou de chaîne natifs fonctionnent et qu'il n'est pas nécessaire d'interroger les catalogues système pour découvrir les valeurs valides. Une jointure est nécessaire pour lier le color_id à la valeur de texte souhaitée.