PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Postgres-ENUM-Datentyp oder CHECK CONSTRAINT?

Basierend auf den Kommentaren und Antworten hier und einigen rudimentären Recherchen habe ich die folgende Zusammenfassung für Kommentare aus der Postgres-Erati anzubieten. Wird Ihren Beitrag wirklich zu schätzen wissen.

Es gibt drei Möglichkeiten, Einträge in einer Postgres-Datenbanktabellenspalte einzuschränken. Stellen Sie sich eine Tabelle zum Speichern von "Farben" vor, in der nur "rot", "grün" oder "blau" gültige Einträge sein sollen.

  1. Aufgezählter Datentyp

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

    Vorteile sind, dass der Typ einmal definiert und dann in beliebig vielen Tabellen wiederverwendet werden kann. Eine Standardabfrage kann alle Werte für einen ENUM-Typ auflisten und kann verwendet werden, um Anwendungsformular-Widgets zu erstellen.

    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
    

    Nachteile sind, dass der ENUM-Typ in Systemkatalogen gespeichert wird, sodass eine Abfrage wie oben erforderlich ist, um seine Definition anzuzeigen. Diese Werte sind beim Anzeigen der Tabellendefinition nicht ersichtlich. Und da ein ENUM-Typ tatsächlich ein Datentyp ist, der von den eingebauten Datentypen NUMERIC und TEXT getrennt ist, funktionieren die regulären numerischen und String-Operatoren und -Funktionen nicht damit. Man kann also keine Abfrage wie

    machen
    SELECT FROM t WHERE color LIKE 'bl%'; 
    
  2. Einschränkungen prüfen

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

    Zwei Vorteile sind, erstens, „was Sie sehen, ist, was Sie bekommen“, das heißt, die gültigen Werte für die Spalte werden direkt in der Tabellendefinition aufgezeichnet, und zweitens, alle nativen Zeichenfolgen- oder numerischen Operatoren funktionieren.

  3. Fremdschlüssel

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

    Im Wesentlichen dasselbe wie das Erstellen eines ENUM-Typs, außer dass die nativen numerischen oder String-Operatoren funktionieren und man keine Systemkataloge abfragen muss, um die gültigen Werte zu ermitteln. Zum Verknüpfen der color_id ist ein Join erforderlich auf den gewünschten Textwert.