Herança no PostgreSQL

Olá amigos,

 

nesse artigo vamos tratar um conceito que tem, a cada dia, sido mais discutido no âmbito dos bancos de dados relacionais, em especial o PostgreSQL, o conceito de herança.

 

Inicialmente, herança é um conceito da orientação à objetos onde, uma determinada classe herda características (no caso das classes - propriedades ou atributos e métodos ou funções) de uma outra "super" classe. A relação de herança pode ser lida da seguinte forma: "a classe que herda É UM TIPO DA super classe (classe herdada)".

 

Assim teríamos, por exemplo, uma classe funcionário que contém os dados comuns dos funcionários (matricula, nome, dataNascimento, ...) e uma classe gerente que É UM TIPO DE funcionário, mas com algumas outras características exclusivas como por exemplo (percentualParticipacaoLucro, telCeluar, ...).

 

Então, no exemplo acima temos uma classe gerente que herda da classe funcionário. Isso significa que não precisamos replicar todas as características de um funcionário para um gerente. A herança se encarrega de fazer isso e o gerente passa a ter todas as características do funcionário + as suas características próprias.

 

Agora falando do PostgreSQL. Ao contrário do que lemos muitas vezes por ai, o PostgreSQL não é um SGBD (Sistema de Gerência de Banco de Dados) Orientado a Objetos. Ele é o que chamamos de Sistema de Gerência de Banco de Dados Relacional Estendido ou Objeto-Relacional. Essa sua Extensão nos permite utilizar alguns conceitos próprios de um Banco Orientado a Objetos, como por exemplo tipos de dados definidos pelo usuário e herança. No caso da herança no PostgreSQL, uma tabela pode herdar de nenhuma, uma, ou várias tabelas.

 

Implementando o exemplo acima no PostgreSQL teríamos:

 

create table funcionario(

         matricula int,

         nome varchar,

         dataNascimento Date,

         primary key(matricula)

)

 

Ao executar o comando acima, o PostgreSQL automaticamente cria a tabela funcionário (com a estrutura informada) no esquema public.

 

create table gerente(

         percentParticipacaLucro int,

         telCel varchar

) inherits (funcionario);

 

Ao executar o comando acima, o PostgreSQL cria uma tabela gerente com os atributos de funcionário + os atributos de gerente.

 

Então agora temos as seguintes tabelas em nossa base:

 

Funcionário

  matricula int,

  nome varchar,

  datanascimento date,

  CONSTRAINT funcionario_pkey PRIMARY KEY (matricula)

 

Gerente

  matricula int4 NOT NULL,

  nome varchar,

  datanascimento date,

  percentparticipacalucro int4,

  telcel varchar

 

Notem que ao contrário do que dissemos acima com relação às classes, na herança de tabelas no PostgreSQL os campos herdados se repetem "fisicamente" nas duas tabelas.

 

Para inserir um gerente usamos:

insert into gerente values (1000, 'Hesley', '01/01/1975', 10, '99999999'); -- Ao inserir um gerente, automaticamente os atributos herdados (matricula, nome, dataNascimento) são inseridos também na tabela de funcionários.

 

Para inserir um funcionário usamos:

insert into funcionario values (2000, 'Maria', '02/02/1980'); -- Os dados são inseridos somente na tabela funcionários e não na tabela gerente.

 

Para visualizarmos os dados das tabelas.

 

select * from gerente;

Retorna

1000;"Hesley";"1975-01-01";10;"99999999"

 

select * from funcionario;

Retorna

2000;"Maria";"1980-02-02"

1000;"Hesley";"1975-01-01"

 

Bom, agora eu quero saber quais os funcionários que não são gerentes. Em uma situação normal (sem herança) podia usar o conceito de subquery para selecionar os funcionários que não estão na tabela gerente. Uma vez implementada a herança, basta eu usar a palavrinha ONLY como na query abaixo.

 

select * from only funcionario; -- Retorna somente os funcionários que não são gerentes.

Retorna

2000;"Maria";"1980-02-02"

 

Como no SELECT, os comando UPDATE e DELETE também suportam o uso do "ONLY".

 

Existem algumas deficiências com relação à restrição de integridade no uso das heranças. Por exemplo, a tabela funcionário foi criada com uma chave primária matricula, o que impede que eu possua dois funcionários com uma mesma matrícula, entretanto essa restrição não é válida para a tabela herdada. Dessa forma poderiam existir dois gerentes com a mesma matrícula.

 

Com relação à utilidade da herança no PostgreSQl, ainda não consegui ver muita utilidade (posso estar enganado) e a maioria dos textos que tenho lido sobre o tema, desencoraja seu uso. Particularmente, acredito que os recursos relacionais existentes no PostgreSQL e nos outros bancos relacionais são suficientes e adequados para resolver os problemas que seriam tratados usando a herança (posso estar enganado).

 

[]'s,

 

Hesley Py