Esse artigo faz parte da revista SQL Magazine edição 56. Clique aqui para ler todos os artigos desta edição
mso-bidi-font-family: 'Times New Roman'; mso-bidi-font-weight: normal; mso-fareast-font-family: Times">Desvendando os tipos de dados enumerados
Como usar enums no PostgreSQL
Ao buscar na Internet pelas palavras chaves "enum" e "postgres", você encontrará diversos tutoriais úteis para lidar com o fato de que o PostgreSQL, até pouco tempo atrás, não suportava os tipos de dados enumerados. Sugestões incluíam criar um domínio e uma restrição (constraint), criar uma tabela auxiliar e usar chaves estrangeiras ou escrever um pouco de código para o seu próprio tipo enum. Felizmente não precisamos fazer mais isso!
Com tantas melhorias no desempenho e significantes novas funcionalidades, a versão 8.3 representa um grande salto para o PostgreSQL. Isso foi possível graças a uma comunidade em expansão que acelerou o ritmo de desenvolvimento deste SGBD. Uma das maiores features que esta versão apresenta são os "tipos de dados enumerados", comumente chamados de enums (vide Nota 1).
A primeira vez que uma implementação nativa de tipos enumerados no PostgreSQL foi proposta data de outubro de 2005. Na ocasião, Andrew Dunstan postou o “enumkit” na “pg-hackers”, a lista de discussão dos desenvolvedores do SGBD. O kit era uma espécie de módulo para o PostgreSQL que pretendia simplificar a criação de tipos enum no banco de dados. Em menos de um ano depois, Andrew e Tom Dunstan (também desenvolvedor do PostgreSQL) expuseram na mesma lista de discussão suas idéias sobre como implementar enums no core do PostgreSQL baseando-se no trabalho anterior feito no “enumkit”. Após muita discussão sobre os detalhes técnicos envolvidos nessa implementação nativa, eis que a proposta finalmente é aceita em meados de 2007 e Tom Dunstan fica encarregado de incluir esta feature na release 8.3 do PostgreSQL.
Neste artigo apresentaremos esta tão esperada e controversa modalidade de tipo de dados através de exemplos baseados em situações práticas.
Nota 1. Tipos de dados enumerados (enums)
Tipos enumerados, ou simplesmente enums, são tipos de dados que compreendem um conjunto estático e predefinido de valores que seguem uma ordem específica. Eles são equivalentes aos tipos enum presentes em diversas linguagens de programação. Como exemplos de aplicações para os tipos enum, poderíamos citar: estado civil (solteiro, casado, etc), gênero (masculino, feminino), status de um pedido (em aberto, fechado, cancelado), combustível de automóvel (gasolina, álcool, flex, diesel, gás, etc), naipes do baralho (espada, paus, copas e ouro).
Como se fazia anteriormente
O tipo enum, presente em linguagens de programação como Pascal, Visual Basic, Java (a partir da versão 5.0), C, C++ e C#, tem se mostrado uma tendência também no campo de banco de dados.
O MySQL, um dos mais populares SGBDs de código aberto, possui suporte aos tipos de dados enumerados pelo menos desde a sua versão 3. E como o enum não é contemplado no padrão SQL-ANSI, para a maioria dos SGBDs relacionais atuais ele ainda não existe.
Pelo fato de o PostgreSQL, até a sua versão 8.3, não implementar o enum, o desenvolvedor era obrigado a recorrer a outros recursos do SGBD para garantir a integridade em colunas específicas. A alternativa mais comum era criar uma restrição (constraint) do tipo CHECK para a coluna da tabela em questão, conforme exemplificado na Listagem 1. Feito isso, a inclusão ou modificação de seus registros está sujeita à regra de validação imposta pela restrição. Como exemplificado na Listagem 2, apenas as duas primeiras instruções serão efetuadas com sucesso.
Listagem 1. Alternativa ao enum usando constraint CHECK.
CREATE TABLE pessoa (
id int NOT NULL PRIMARY KEY,
nome varchar(50) NOT NULL,
sexo char(1) NOT NULL,
CHECK (sexo IN ('M', 'F'))
);
Listagem 2. Validação da constraint CHECK na inclusão de registros.
-- instruções válidas
INSERT INTO pessoa VALUES (1, 'Daniel Auteuil', 'M');
INSERT INTO pessoa VALUES (2, 'Vanessa Paradis', 'F');
-- erro proposital
INSERT INTO pessoa VALUES (3, 'Emmanuel
Sendo assim, ao incluir as linhas na tabela, os possíveis valores seriam checados e evitariam registros incorretos, conforme ilustrado na Figura 1.
Figura 1. Criação de tabela com constraint simulando enum e posterior validação.
Uma segunda abordagem consistia em criar um domínio, que compreendia o tipo de dados básico e a restrição (constraint) a ser verificada na coluna. Com isso, poderíamos reutilizar este tipo de dados customizado em diversas tabelas de um mesmo banco de dados, conforme exemplificado na Listagem 3.
Listagem 3. Alternativa ao enum criando um domínio.
-- criação do domínio
CREATE DOMAIN ...