PostgreSQL Prático – Como funcionam as Views no PostgreSQL

Como funcionam as Views no PostgreSQL

– O que são views de banco de dados ?

Em teoria de banco de dados, uma visão, ou vista (em inglês: view), é um conjunto resultado de uma consulta armazenada sobre os dados, em que os usuários do banco de dados podem consultar simplesmente como eles fariam em um objeto de coleção de banco de dados persistente.

View é um resultado originado de uma consulta pré-definida. Essencialmente é um metadado que mapeia uma query para outra, por isto pode ser considerado como uma tabela virtual. Como o próprio nome diz, ela representa uma visão de dados e não contém dados. Com ela você tem a ilusão que está vendo uma tabela que não existe. Claro que o que você vê nesta tabela existe de outra forma no banco.

É bom entender que essa “tabela virtual” que é criada, não é bem uma tabela física criada em memória com todos os dados que você precisa. A view é apenas uma forma de traduzir uma query para outra query mais complexa. Mas uma otimização pode acabar tornando sim uma view comum em tabela física. Claro isto depende da implementação do DB.

Uma view é muito usada para ajudar dar entendimento do projeto lógico do banco de dados.

– Qual a diferença entre view e view materializada ?

Quando se trabalha com banco de dados podemos dizer que uma das tarefas mais importantes a ser realizada é a otimização do desempenho do banco de dados.

Dependendo da aplicação, uma determinada tabela deve ser otimizada para receber muitas consultas e poucas atualizações. Algumas vezes é o contrário, muitas atualizações na tabela, mas poucas consultas.

Neste post você vai entender um conceito que deve ser claro para você quando for decidir se pretende priorizar a escrita ou a leitura de uma tabela ou “visão”. Você vai entender a diferença entre uma VIEW e uma MATERIALIZED VIEW.

O que é uma VIEW

Uma VIEW (ou Visão) é uma consulta armazenada no banco de dados. Nós podemos, realizar consultas sobre uma VIEW como se fosse uma tabela. Muitas pessoas se referem às VIEWs como uma tabela virtual.

Uma das principais funções da VIEW é controlar a segurança do banco de dados. Geralmente se cria a VIEW (uma consulta armazenada no banco de dados) com os campos que determinado perfil de usuário pode acessar, e concede-se ao usuário acesso apenas a essa VIEW e não à(s) tabela(s) diretamente.

Também utiliza-se VIEWs para apresentar informações mais organizadas para o usuário sem que ele precise elaborar uma consulta complexa. Esta já estaria pronta e armazenada no próprio banco de dados para uso.

Para entender o que é uma VIEW na prática, imagine as duas tabelas abaixo.

Agora considere que um determinado usuário precisa de uma lista atualizada de Funcionários e seus respectivos departamentos. Por questões de segurança, não pode ser fornecido à este usuário informações de CPF, E-mail e Salário dos funcionários.
A melhor forma para se fazer isso é criar uma VIEW onde essas informações não apareçam e fornecer ao usuário acesso apenas a esta VIEW. Ou seja, o usuário só teria acesso visão conforme a imagem abaixo.

{.aligncenter .size-full .wp-image-2244 width=”298″ height=”106″}

A consulta desta view poderia ser a seguinte:

SELECT F.NOME AS FUNCIONARIO, D.NOME AS DEPARTAMENTO from FUNCIONARIO F INNER JOIN DEPARTAMENTO D ON D.ID_DEPARTAMENTO = F.ID_DEPARTAMENTO

Mas na realidade, a VIEW realiza uma consulta (query) em tempo de execução. Em uma VIEW simples essa consulta que é armazenada. Essa consulta pode ter condições próprias para restringir os dados que serão visualizados pelo usuário, tanto horizontal (colunas que serão apresentadas) quanto vertical (linhas que serão apresentadas).

Por exemplo, se no mesmo caso acima, além de não apresentar cpf, e-mail e salário, quiséssemos também retirar os funcionários do departamento “Recursos Humanos” da “visão” do usuário, bastaria colocar uma condição na cláusula “WHERE” da view (where id_departamento <> 2). O usuário nem saberia disso.

Acho que já deu pra entender o que é uma VIEW: Uma consulta armazenada, uma tabela “virtual”.

Qualquer dúvida deixe um comentário no final do post.

Agora vamos ver …

O que é uma MATERIALIZED VIEW

Visão Materializada é uma view, só que neste caso, o que é armazenado não é a consulta e sim o resultado dela.

Isso implica algumas coisas muito importantes que devem ser entendidas quando for decidir entre criar uma VIEW ou uma MATERIALIZED VIEW.

Primeiro, uma MATERIALIZED VIEW é uma tabela real no banco de dados que é atualizada SEMPRE que ocorrer uma atualização em alguma tabela usada pela sua consulta. Por este motivo, no momento em que o usuário faz uma consulta nesta visão materializada o resultado será mais rápido que se ela não fosse materializada.

Basicamente a diferença no uso das duas é essa. A view realiza a consulta no momento que o usuário faz uma consulta nela e a materialized view realiza a consulta no momento em que uma das tabelas consultadas é atualizada.

Vejamos como seria na prática com o mesmo exemplo que utilizamos acima.

Se a view V_FUNCIONARIO_DEPARTAMENTO for materializada, sempre que a tabela departamento ou a tabela funcionário receber uma inclusão, alteração ou exclusão, a “consulta da view” também será executada e o resultado será armazenado.

Embora a consulta na view fique mais rápida com o pre-processamento da consulta interna, o processo de escrita no banco de dados fica mais lento, pois é necessário executar a consulta interna da materialized view toda vez que um dado sofrer alteração.

Quando usar VIEW ou MATERIALIZED VIEW?

A decisão se a sua view deve ser simples ou materializada é tomada com base no tipo de utilização das tabelas usadas pela consulta da view. A decisão é simples. Você consulta mais na view do que altera os dados das tabelas? Os dados do seu banco de dados são alterados com frequência?

Em resumo, você deve usar uma visão materializada quando o desempenho das buscas na view é mais importante que o desempenho da escrita nas tabelas que ela utiliza. Mas se uma tabela utilizada pela view tem muita alteração de dados, talvez seja mais interessante que a view não seja materializada.

Como funcionam as Views no PostgreSQL

 

Neste artigo trataremos da criação e exclusão das Views no PostgreSQL. Conheceremos sua estrutura básica e aprenderemos a usá-las em nossas consultas para obter resultados de forma simplificada.

Primeiramente, precisamos entender o que são as Views, que são consideradas pseudo-tables, ou seja, elas são usadas junto a instrução SELECT para apresentar subconjuntos de dados presentes em tabelas reais. Assim, podemos apresentar as colunas e linhas que foram selecionadas da tabela original ou associada. E como as Views possuem permissões separadas, podemos utilizá-las para restringir mais o acesso aos dados pelos usuários, para que veja apenas o que é necessário.

Vamos começar apresentando a sintaxe básica de uma view, conforme a Listagem 1.

Listagem 1. Sintaxe de criação de uma View.

CREATE [ OR REPLACE ] [ TEMP | TEMPORARY
] [ RECURSIVE ] VIEW name

  [
( column_name [, ...] ) ]

  [
WITH ( view_option_name [= view_option_value] [, ... ] ) ]

  AS
query

  [
WITH [ CASCADED | LOCAL ] CHECK OPTION ]

O código começa com a instrução de criação CREATE VIEW. E como ela é virtual, sempre que uma consulta é executada, a View é referenciada na consulta.

Vamos criar uma tabela funcionários que será responsável por manter os registros reais, como mostra a Listagem 2.

Listagem 2. Criando a tabela de funcionários.

CREATE TABLE funcionarios

  (

    codigo integer NOT NULL,

    nome_func character varying(100) NOT NULL,

    data_entrada date,

    profissao character varying(100) NOT NULL,

    salario real,

    CONSTRAINT funcionarios_pkey PRIMARY KEY (codigo)

  )

  WITH (

    OIDS=FALSE

  );

  ALTER TABLE funcionarios

    OWNER TO postgres;

Vamos criar uma view para essa tabela usando a sintaxe a seguir:

CREATE VIEW view_funcionarios AS SELECT * FROM Funcionarios;

A view_funcionarios contém uma instrução SELECT para receber os dados da tabela. Para que possamos ver as views que criamos, podemos utilizar a seguinte declaração:

SELECT codigo, nome_func, profissao FROM view_funcionarios;

Uma View é um objeto que permite a visualização de dados da tabela a qual esteja associada. Como ela não existe por conta própria, é criada com base em consultas nas tabelas para selecionar colunas, dando assim acessos restritos ou com privilégios. Além disso possuem a capacidade de juntar informações contidas em diversas tabelas para representar em um único lugar como, por exemplo, na geração de relatórios.

Devido as suas especificações de restrição, os dados retornados são apenas aqueles que o usuário pode ver. E por serem tabelas virtuais, não podemos realizar por elas as operações DML de inserção, atualização e exclusão, mas sim apenas usando o SELECT.

Para exemplificarmos esse ponto utilizaremos a tabela funcionários em conjunto com uma nova tabela registro_ponto que conterá o registro de entrada e saída de cada um da empresa, conforme o código da Listagem 3. Veja que obteremos apenas o nome do funcionário, profissão, data e a hora de entrada.

Listagem 3. Criação da tabela de registro_ponto.

CREATE TABLE registro_ponto

(

registro_ponto_id integer NOT NULL,

hora_entrada time without time zone,

“codFunc” integer NOT NULL,

entrada date,

CONSTRAINT registro_ponto_pkey PRIMARY KEY (registro_ponto_id),

CONSTRAINT “codFuncFK” FOREIGN KEY (“codFunc”)

REFERENCES funcionarios (codigo) MATCH SIMPLE

ON UPDATE NO ACTION ON DELETE NO ACTION

)

WITH (

OIDS=FALSE

);

ALTER TABLE registro_ponto

OWNER TO postgres;

— Index: “fki_codFuncFK”

— DROP INDEX “fki_codFuncFK”;

CREATE INDEX “fki_codFuncFK”

ON registro_ponto

USING btree

(“codFunc”);

    ON
registro_ponto

    USING
btree

    ("codFunc");

Agora criaremos uma segunda view View_Ponto_funcionario que utilizará o código do funcionário na cláusula where, como vemos a seguir:

CREATE VIEW View_Ponto_funcionario AS SELECT nome_func, profissao, entrada, hora_entrada FROM funcionarios, registro_ponto WHERE funcionarios.codigo = registro_ponto.“codFunc”;

Feito isso, podemos executar a instrução a seguir para ver a View criada:

SELECT * FROM View_Ponto_funcionario;

Para vermos o resultado inseriremos alguns registros em ambas as tabelas, como mostra a Listagem 4.

Listagem 4. Inserção de dados nas tabelas funcionarios e registro_ponto.

INSERT INTO funcionarios(codigo, nome_func, data_entrada, profissao, salario) VALUES (1, ‘Edson Dionisio’, ‘2015-09-01’, ‘Desenvolvedor Web’, 2000.00);

INSERT INTO funcionarios(codigo, nome_func, data_entrada, profissao, salario) VALUES (5, ‘Danilo Dionisio’, ‘2018-09-01’, ‘Desenvolvedor Web’, 2500.00);

INSERT INTO funcionarios(codigo, nome_func, data_entrada, profissao, salario) VALUES (2, ‘Marilia Kessia’, ‘2017-09-01’, ‘Coordenadora’, 5000.00);

INSERT INTO funcionarios(codigo, nome_func, data_entrada, profissao, salario) VALUES (3, ‘Caroline França’, ‘2019-01-03’, ‘Estéticista’, 2500.00);

INSERT INTO registro_ponto(registro_ponto_id, entrada, hora_entrada, “codFunc”) VALUES (1, ‘2015-10-03’, ’13:00:00′, 1);

INSERT INTO registro_ponto(registro_ponto_id, entrada, hora_entrada, “codFunc”) VALUES (2, ‘2015-11-04’, ’08:00:00′, 2);

INSERT INTO registro_ponto(registro_ponto_id, entrada, hora_entrada, “codFunc”) VALUES (3, ‘2015-10-05’, ’08:00:00′, 1);

Feita
a inserção dos dados, podemos ver as mudanças na nossa segunda
View utilizando a seguinte instrução:

Como mostra a Figura 1,
as informações sendo apresentadas na View contendo os dados
solicitados das duas tabelas.

Figura 1. Resultado da consulta a View View_Ponto_funcionario.

Para excluir uma view usamos o seguinte comando:

DROP VIEW view_funcionarios;

Trabalhando com as Views
materializadas

Como as Views são apenas para leitura e
representação lógica dos dados que estão armazenados nas tabelas
do banco de dados, podemos “materializadas”, ou seja,
armazená-las fisicamente no disco.

A criação dessas Views, ao invés de novas tabelas, melhora o desempenho em operações de leitura. Os dados das Views materializadas serão então armazenados em uma tabela que pode ser indexada rapidamente quando esta for associada e também em momentos que precisemos atualizar as Views materializadas. Isso ocorre com frequência em Data warehouse e aplicações de Business Intelligence, por exemplo.

Com base no exemplo que desenvolvemos nesse
artigo, a instrução a seguir cria uma view materializada para a
tabela funcionarios:

CREATE MATERIALIZED VIEW view_materializada_funcionario AS SELECT * FROM funcionarios WITH NO DATA;

Para inserir dados nessa view usaremos o código da Listagem 6.

Listagem 6. Inserindo dados na view materializada

INSERT INTO funcionarios (codigo, nome_func, data_entrada, profissao) VALUES (10, ‘Gustavo França’, ‘2014-10-11’, ‘Estagiário’);

INSERT INTO funcionarios (codigo, nome_func, data_entrada, profissao) VALUES (6, ‘Mayara Silva’, ‘2015-06-10’, ‘Analista de testes’);

INSERT INTO funcionarios (codigo, nome_func, data_entrada, profissao) VALUES (7, ‘João dos testes’, ‘2011-01-01’, ‘Gerente de negócios’);

INSERT INTO funcionarios (codigo, nome_func, data_entrada, profissao) VALUES (8, ‘Marina França’, ‘2012-03-07’, ‘Analista de negócios’);

INSERT INTO funcionarios (codigo, nome_func, data_entrada, profissao) VALUES (9, ‘Paulo Dionisio’, ‘2013-07-07’, ‘DBA Sênior’);

Agora utilizaremos o comando SELECT para
verificarmos se os registros foram realmente inseridos com sucesso:

Podemos ver que obtivemos um erro ao
tentarmos consultar a nossa View, como mostra a
Figura 2.

SELECT * FROM view_materializada_funcionario;

Figura 2. Visualização de erro ao consultar View materializada.

Este erro ocorreu porque a view não se atualizou automaticamente, então precisamos do comando Refresh Materialized View:

REFRESH MATERIALIZED VIEW view_materializada_funcionario;

Feito isso, e em seguida, tentando consultar
novamente os dados e assim obtemos êxito.

Com o PostgreSQL 9.4 podemos consultar Views materializadas enquanto são atualizadas, porém, nas versões anteriores isso não é possível. Para esse procedimento utilizamos a palavra-chave CONCURRENTLY, como mostra o comando a seguir:

REFRESH MATERIALIZED VIEW CONCURRENTLY view_materializada_funcionario;


SELECT * FROM view_materializada_funcionario;

Para que isso ocorra, um índice exclusivo
passa a ser necessário para existir na View materializada. Sendo
assim, ao executarmos o comando select novamente, teremos todos os
dados atualizados, como podemos ver na
Figura 3.

Figura 3. Selecionando dados da View Materializada.

Para excluir esse tipo de view basta utilizarmos o seguinte comando:

DROP
MATERIALIZED VIEW view_materializada_funcionario;

Todos os recursos de otimização são
importantes, pois lembre-se que as views são apenas visões dos
dados e são carregadas apenas quando necessárias. Mas elas criam
uma camada extra para administrar e podem limitar exageradamente,
impedindo certas tarefas.

Além disso, não confunda uma view materializada com uma trigger, pois apesar de funcionarem de forma semelhante, a trigger tem muito mais poder sobre a tabela.

Esperamos que tenham gostado. Até a próxima!

Links

Documentação da View
http://www.postgresql.org/docs/9.4/static/sql-createview.html

  • Renato de Oliveira Lucena – 22/01/2019