PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Postgres ENUM tipo di dati o CHECK CONSTRAINT?

Sulla base dei commenti e delle risposte qui presenti e di alcune ricerche rudimentali, ho il seguente riassunto da offrire per i commenti del Postgres-erati. Apprezzerò davvero il tuo contributo.

Esistono tre modi per limitare le voci in una colonna della tabella del database Postgres. Prendi in considerazione una tabella per memorizzare i "colori" in cui desideri che solo "rosso", "verde" o "blu" siano voci valide.

  1. Tipo di dati enumerati

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

    I vantaggi sono che il tipo può essere definito una volta e quindi riutilizzato in tutte le tabelle necessarie. Una query standard può elencare tutti i valori per un tipo ENUM e può essere utilizzata per creare widget di moduli di domanda.

    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
    

    Gli svantaggi sono che il tipo ENUM è memorizzato nei cataloghi di sistema, quindi è necessaria una query come sopra per visualizzarne la definizione. Questi valori non sono evidenti quando si visualizza la definizione della tabella. E, poiché un tipo ENUM è in realtà un tipo di dati separato dai tipi di dati NUMERIC e TEXT incorporati, gli operatori e le funzioni numerici e di stringa regolari non funzionano su di esso. Quindi, non si può fare una query come

    SELECT FROM t WHERE color LIKE 'bl%'; 
    
  2. Verifica i vincoli

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

    Due vantaggi sono che, uno, "ciò che vedi è ciò che ottieni", ovvero i valori validi per la colonna sono registrati direttamente nella definizione della tabella e due, tutti gli operatori numerici o di stringa nativi funzionano.

  3. Chiavi esterne

    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)
    );
    

    Essenzialmente come la creazione di un tipo ENUM, tranne per il fatto che gli operatori numerici o di stringa nativi funzionano e non è necessario eseguire query sui cataloghi di sistema per scoprire i valori validi. È necessario un join per collegare il color_id al valore di testo desiderato.