quinta-feira, 27 de novembro de 2008

Campos Tipo ENUM no PostgreSQL 8.3

Campos com enumerações de valores aceitos são implementados em vários bons bancos de dados. No caso do PostgreSQL, este recurso poderia ser realizado através de constraints tipo CHECK ou domínios. Na versão 8.3 foi introduzido um tipo de dado ENUM, facilitando ainda mais a operação de campos com uma lista restrita de valores permitidos.

Vantagens:
- Cria listas de valores aceitos que podem ser reutilizadas várias vezes, inclusive dentro de uma mesma tabela, para disciplinar os valores aceitos por um determinado campo.
- Apresenta funções específicas para manipulação dos tipos ENUM criados.
- Melhor uso de espaço: o armazenamento campos Enum ocupam 4 bytes em disco. Dependendo da quantidade de valores armezenados, pode ser economizado um bom espaço no banco de dados.
- Podem ser visualizados através de consultas a pg_enum.

Desvantagens:
- O tipo ENUM é diferente dos demais tipos do PostgreSQL, portanto não pode ser comparado com valores de outros tipos. Na ausência de CAST, empregue um operador customizado ou uma função que realize esta conversão.
- Falta de recursos para alterações no tipo. Não é possível simplesmente inserir ou retirar valores de um tipo, mas os valores de campos de tabelas tipo ENUM podem ser livremente alterados.
- Enumerados que não sejam de valores alfanuméricios não podem ser criados. Para enumerados de datas e números deve ser empregada uma restrição do tipo CHECK, por exemplo, ou outra maneira de simular o ENUM.

Sintaxe:
CREATE TYPE name AS ENUM
( 'label' [, ... ] )
Exemplos:

1 - Criação e Utilização de Tipo Enumerado

CREATE TYPE dia_sem AS ENUM ('Dom', 'Seg', 'Ter', 'Qua', 'Qui', 'Sex', 'Sab');

--Utilização na criação de tabelas
CREATE TABLE registro (
dia_coleta dia_sem,
dia_analise dia_sem,
dia_resultado dia_sem);

INSERT INTO registro VALUES ('Seg', 'Ter', 'Qua');
INSERT INTO registro VALUES ('Seg', 'Ter', 'Dom');
INSERT INTO registro VALUES ('Seg', 'Ter', 'QuW'); --ERRO - Não encontrado no tipo ENUM
INSERT INTO registro VALUES ('Seg', 'Ter', 'QuA'); --ERRO - Case sentitive

2 - Implementação similar com a cláusula check

CREATE TABLE registro_teste (
dia_coleta text check (dia_coleta in ('Dom', 'Seg', 'Ter', 'Qua', 'Qui', 'Sex', 'Sab')));

3 - Criação de Tipo Enumerado II

CREATE TYPE situacao AS ENUM ('Em elaboração', 'Proposto',
'Em homologação', 'Aprovado', 'Recusado', 'Cancelado', 'Efetivado');

--Utilização na criação de tabelas
CREATE TABLE documento (
descricao varchar(50) PRIMARY KEY,
estado situacao);
INSERT INTO documento VALUES ('Ata de reunião de 12/12/2008', 'Aprovado');
INSERT INTO documento VALUES ('Levantamento do Protótipo', 'Cancelado');

4 - Consulta aos enumerados no catálogo do PostgreSQL (OID do Tipo e Valor)

SELECT * from pg_enum;

5 - Consulta aos enumerados no catálogo do PostgreSQL (OID do Valor, do Tipo e o Valor)

SELECT oid,* from pg_enum;

Nenhum comentário: