sql >> Base de Datos >  >> RDS >> PostgreSQL

¿Tipo de datos ENUM de Postgres o RESTRICCIÓN DE COMPROBACIÓN?

Basado en los comentarios y respuestas aquí, y algunas investigaciones rudimentarias, tengo el siguiente resumen para ofrecer comentarios de Postgres-erati. Realmente apreciaré su aporte.

Hay tres formas de restringir las entradas en una columna de la tabla de la base de datos de Postgres. Considere una tabla para almacenar "colores" donde solo desea que las entradas "rojo", "verde" o "azul" sean válidas.

  1. Tipo de datos enumerados

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

    Las ventajas son que el tipo puede definirse una vez y luego reutilizarse en tantas tablas como sea necesario. Una consulta estándar puede enumerar todos los valores para un tipo ENUM y se puede usar para crear widgets de formulario de solicitud.

    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
    

    Las desventajas son que el tipo ENUM se almacena en los catálogos del sistema, por lo que se requiere una consulta como la anterior para ver su definición. Estos valores no son evidentes cuando se visualiza la definición de la tabla. Y, dado que un tipo ENUM es en realidad un tipo de datos separado de los tipos de datos NUMERIC y TEXT incorporados, los operadores y funciones numéricos y de cadena regulares no funcionan en él. Entonces, uno no puede hacer una consulta como

    SELECT FROM t WHERE color LIKE 'bl%'; 
    
  2. Comprobar restricciones

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

    Dos ventajas son que, una, "lo que ve es lo que obtiene", es decir, los valores válidos para la columna se registran directamente en la definición de la tabla, y dos, todos los operadores numéricos o de cadena nativos funcionan.

  3. Claves foráneas

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

    Esencialmente lo mismo que crear un tipo ENUM, excepto que los operadores numéricos o de cadena nativos funcionan y no es necesario consultar los catálogos del sistema para descubrir los valores válidos. Se requiere una unión para vincular el color_id al valor de texto deseado.