PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Tipo de dados Postgres ENUM ou CHECK CONSTRAINT?


Com base nos comentários e respostas aqui, e em algumas pesquisas rudimentares, tenho o seguinte resumo a oferecer para comentários do Postgres-erati. Vai realmente apreciar a sua entrada.

Existem três maneiras de restringir entradas em uma coluna da tabela do banco de dados Postgres. Considere uma tabela para armazenar "cores" onde você deseja que apenas 'vermelho', 'verde' ou 'azul' sejam entradas válidas.

  1. Tipo de dados enumerados
    CREATE TYPE valid_colors AS ENUM ('red', 'green', 'blue');
    
    CREATE TABLE t (
        color VALID_COLORS
    );
    

    As vantagens são que o tipo pode ser definido uma vez e depois reutilizado em quantas tabelas forem necessárias. Uma consulta padrão pode listar todos os valores de um tipo ENUM e pode ser usada para criar widgets de formulário de aplicativo.
    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
    

    As desvantagens são que o tipo ENUM é armazenado nos catálogos do sistema, portanto, uma consulta como acima é necessária para visualizar sua definição. Esses valores não são aparentes ao visualizar a definição da tabela. E, como um tipo ENUM é, na verdade, um tipo de dados separado dos tipos de dados NUMERIC e TEXT incorporados, os operadores e funções numéricos e string regulares não funcionam nele. Então, não se pode fazer uma consulta como
    SELECT FROM t WHERE color LIKE 'bl%'; 
    

  2. Verificar restrições
    CREATE TABLE t (
        colors TEXT CHECK (colors IN ('red', 'green', 'blue'))
    );
    

    Duas vantagens são que, uma, "o que você vê é o que você obtém", ou seja, os valores válidos para a coluna são registrados diretamente na definição da tabela e, segundo, todos os operadores de string ou numéricos nativos funcionam.

  3. Chaves estrangeiras
    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)
    );
    

    Essencialmente o mesmo que criar um tipo ENUM, exceto que os operadores numéricos ou de string nativos funcionam e não é necessário consultar os catálogos do sistema para descobrir os valores válidos. Uma junção é necessária para vincular o color_id para o valor de texto desejado.