Views no PostgreSQL
Um guia prático e completo sobre views em PostgreSQL
O Que São Views?
Views são consultas SQL armazenadas que funcionam como tabelas
virtuais. Elas não armazenam dados fisicamente, mas fornecem uma
camada de abstração sobre as tabelas reais, simplificando consultas
complexas e melhorando a segurança.
No PostgreSQL, views são objetos de banco de dados que permitem
encapsular lógica de negócio, restringir acesso a dados sensíveis e criar
interfaces mais intuitivas para usuários finais e aplicações.
Vantagens das Views
Segurança Simplicidade
Restrinja acesso a colunas específicas sem expor toda a tabela. Encapsule consultas complexas com múltiplos JOINs em uma
Perfeito para proteger dados sensíveis como CPF e informações interface simples. Desenvolvedores usam a view sem precisar
pessoais. entender toda a lógica.
Manutenção Reusabilidade
Altere a estrutura das tabelas subjacentes sem impactar aplicações Defina lógica uma vez e reutilize em múltiplas consultas. Views
que dependem da view. Reduza o acoplamento no código. promovem consistência e evitam duplicação de código SQL.
Estrutura do Banco de Exemplo
Nosso banco de dados de e-commerce contém quatro tabelas principais que se
relacionam para formar um sistema completo de gestão de pedidos e produtos.
Clientes
Armazena informações dos clientes: nome, CPF, idade e status VIP. Chave
primária é o ID serial.
Produtos
Catálogo de produtos com nome e preço. Produtos variam de periféricos até
móveis gamer.
Pedidos
Registra cada pedido com referência ao cliente, data/hora e valor total calculado.
Itens do Pedido
Detalha cada item dentro de um pedido: produto, quantidade e preço unitário
aplicado.
Sintaxe Básica: CREATE VIEW
A sintaxe fundamental para criar uma view no PostgreSQL segue este padrão:
CREATE VIEW nome_da_view AS
SELECT coluna1, coluna2, ...
FROM tabela
WHERE condição;
A cláusula AS é seguida por qualquer consulta SELECT válida. A view pode incluir JOINs, agregações, subconsultas e todas as funcionalidades
disponíveis em SELECT.
Importante: Views são apenas leituras por padrão. Para permitir INSERT, UPDATE ou DELETE, você precisa criar triggers ou usar views
materializadas.
Exemplo 1: View Simples de Clientes VIP
Vamos criar nossa primeira view para filtrar apenas clientes VIP, ocultando informações
sensíveis como CPF completo:
CREATE VIEW clientes_vip AS
SELECT
id,
nome,
idade,
CONCAT(LEFT(cpf, 3), '.***.***-**') AS cpf_mascarado
FROM clientes
WHERE vip = true;
Esta view mascara o CPF e retorna apenas clientes com status VIP ativo, fornecendo
uma camada de segurança adicional.
Consultando a View
Depois de criar a view, você pode consultá-la exatamente como se fosse uma tabela normal:
SELECT * FROM clientes_vip;
O resultado mostrará apenas clientes VIP com CPF mascarado:
id nome idade cpf_mascarado
2 Maria Oliveira 28 234.***.***-**
4 Ana Paula 21 456.***.***-**
6 Julia Santos 35 678.***.***-**
Exemplo 2: View com JOINs Múltiplos
Views realmente brilham quando simplificam consultas complexas. Vamos criar uma view que combina pedidos com informações de clientes e
produtos:
CREATE VIEW resumo_pedidos AS
SELECT
p.id AS pedido_id,
c.nome AS cliente,
c.vip,
p.data,
p.valor_total,
COUNT(ip.id) AS total_itens
FROM pedidos p
JOIN clientes c ON p.cliente_id = c.id
LEFT JOIN itens_pedido ip ON ip.pedido_id = p.id
GROUP BY p.id, c.nome, c.vip, p.data, p.valor_total
ORDER BY p.data DESC;
Benefícios da View de Resumo
01 02
Simplificação Consistência
Em vez de escrever JOINs complexos A lógica de agregação fica centralizada.
toda vez, basta consultar SELECT * FROM Todos os desenvolvedores usam o mesmo
resumo_pedidos. cálculo de total de itens.
03
Performance em Leitura
Views podem usar índices das tabelas subjacentes, mantendo boa performance em
consultas frequentes.
Exemplo 3: View com Agregações
Vamos criar uma view que mostra estatísticas de vendas por produto, incluindo
quantidade vendida e receita total:
CREATE VIEW estatisticas_produtos AS
SELECT
prod.id,
prod.nome,
prod.preco,
COUNT(ip.id) AS vezes_vendido,
SUM(ip.quantidade) AS qtd_total,
SUM(ip.quantidade * ip.preco_unitario) AS receita_total
FROM produtos prod
LEFT JOIN itens_pedido ip ON prod.id = ip.produto_id
GROUP BY prod.id, prod.nome, prod.preco
ORDER BY receita_total DESC NULLS LAST;
Views Materializadas: O Que São?
View Normal View Materializada Quando Usar
Executa a consulta toda vez que é acessada. Armazena o resultado fisicamente. Precisa Ideal para consultas pesadas que não
Sempre retorna dados atualizados. ser atualizada manualmente com REFRESH. precisam de dados em tempo real.
Views materializadas são perfeitas para dashboards e relatórios que agregam milhões de registros, onde a performance é crítica e alguns minutos de
defasagem são aceitáveis.
Criando uma View Materializada
A sintaxe é muito similar, mas usa CREATE MATERIALIZED VIEW:
CREATE MATERIALIZED VIEW ranking_clientes AS
SELECT
c.id,
c.nome,
c.vip,
COUNT(p.id) AS total_pedidos,
SUM(p.valor_total) AS valor_total_gasto,
AVG(p.valor_total) AS ticket_medio
FROM clientes c
LEFT JOIN pedidos p ON c.id = p.cliente_id
GROUP BY c.id, c.nome, c.vip
ORDER BY valor_total_gasto DESC;
Para atualizar os dados, execute periodicamente:
REFRESH MATERIALIZED VIEW ranking_clientes;
Use REFRESH MATERIALIZED VIEW CONCURRENTLY para atualizar sem bloquear leituras, mas isso requer um índice UNIQUE na view.
Gerenciando Views: Comandos Essenciais
1 2
Listar todas as views Ver definição de uma view
SELECT table_name SELECT definition
FROM information_schema.views FROM pg_views
WHERE table_schema = 'public'; WHERE viewname = 'clientes_vip';
3 4
Alterar uma view existente Remover uma view
CREATE OR REPLACE VIEW clientes_vip AS DROP VIEW IF EXISTS clientes_vip;
SELECT id, nome, idade FROM clientes
WHERE vip = true;
Opções Avançadas: WITH CHECK
OPTION
A cláusula WITH CHECK OPTION garante que dados inseridos ou atualizados através
da view continuem visíveis na view após a operação:
CREATE VIEW clientes_jovens AS
SELECT * FROM clientes
WHERE idade < 30
WITH CHECK OPTION;
Se você tentar atualizar a idade de um cliente para 35 através desta view, a operação
será rejeitada, pois o registro não atenderia mais à condição idade < 30.
Isso previne modificações que resultariam em dados "desaparecendo" da view,
garantindo integridade lógica.
Performance: Índices e Views
Views Normais Views Materializadas
Usam automaticamente os índices das tabelas base Permitem criação de índices próprios
Performance depende da consulta subjacente Performance de leitura muito rápida
Não é possível criar índices diretamente Custo de armazenamento e refresh
Otimização acontece via EXPLAIN ANALYZE Ideal para consultas complexas e frequentes
Exemplo de índice em view materializada:
CREATE INDEX idx_ranking_valor ON ranking_clientes(valor_total_gasto DESC);
Boas Práticas no Uso de Views
Nomes Descritivos Documente a Lógica
Use prefixos como vw_ ou sufixos como _view para identificar views Adicione comentários explicando a finalidade e regras de negócio. Use
facilmente no schema. Exemplo: vw_resumo_vendas_mensais. COMMENT ON VIEW para documentação persistente no banco.
Monitore Performance Controle de Acesso
Views complexas podem impactar performance. Use EXPLAIN para Configure permissões apropriadas usando GRANT. Views são excelentes
analisar planos de execução e identifique gargalos. para implementar segurança em nível de linha.
Exemplo Completo: Sistema de Relatórios
Vamos criar um conjunto completo de views para um sistema de relatórios de e-commerce:
-- View 1: Performance de vendas diária
CREATE VIEW vendas_diarias AS
SELECT
DATE(data) AS data_venda,
COUNT(DISTINCT id) AS total_pedidos,
SUM(valor_total) AS receita_dia,
AVG(valor_total) AS ticket_medio
FROM pedidos
GROUP BY DATE(data)
ORDER BY data_venda DESC;
-- View 2: Top produtos mais lucrativos
CREATE VIEW top_produtos AS
SELECT
p.nome,
COUNT(ip.id) AS vendas,
SUM(ip.quantidade * ip.preco_unitario) AS receita
FROM produtos p
JOIN itens_pedido ip ON p.id = ip.produto_id
GROUP BY p.id, p.nome
ORDER BY receita DESC
LIMIT 10;
Troubleshooting Comum
Erro: "view already exists" View retorna dados desatualizados
Solução: Use CREATE OR REPLACE VIEW para atualizar, ou DROP Verifique se é uma view materializada. Execute REFRESH
VIEW antes de recriar. MATERIALIZED VIEW nome_view; para atualizar.
Performance lenta em views Dependências quebradas
Analise com EXPLAIN ANALYZE. Considere adicionar índices nas Se alterar estrutura de tabela base, recrie a view. Use CASCADE ao
tabelas base ou converter para view materializada. dropar tabelas para remover views dependentes.
Recursos Avançados do
PostgreSQL
1 Updatable Views
Views simples (uma tabela, sem agregações) podem suportar
INSERT/UPDATE/DELETE automaticamente.
2 INSTEAD OF Triggers
Crie triggers personalizados para controlar operações DML em views
complexas.
3 Recursive Views
Use WITH RECURSIVE para criar views que referenciam a si mesmas, útil
para hierarquias.
4 Security Barrier
Adicione security_barrier=true para prevenir vazamento de dados
através de funções customizadas.
Próximos Passos
Continue Aprendendo
1 Pratique com seus dados 2 Explore views materializadas
Aplique os exemplos deste guia ao seu Experimente com dados volumosos e
próprio banco de dados meça ganhos de performance
3 Documente suas views
Crie um repositório de views reutilizáveis para sua equipe
Consulte a documentação oficial do PostgreSQL para recursos ainda mais avançados:
postgresql.org/docs