CREATE OR REPLACE VIEW professores_publico AS
SELECT id_prof, nome, id_escola, ch_semanal
FROM professor;Visões
Em muitas situações, não é desejável que todos os usuários vejam o modelo lógico completo do banco de dados. Uma visão (view) é uma relação virtual — não armazenada fisicamente — que expõe apenas os dados relevantes para cada perfil de usuário.
Uma visão é qualquer relação que não faz parte do modelo conceitual mas que é tornada visível ao usuário como uma relação virtual. Ela é definida por uma expressão de consulta e não ocupa espaço de armazenamento próprio.
Definindo uma Visão
A sintaxe de criação é:
CREATE VIEW <nome> AS <expressão de consulta>;A definição da visão é salva pelo SGBD; a expressão de consulta é executada toda vez que a visão é referenciada em uma consulta.
Visão pública de professores — oculta o salário:
Visão de carga salarial por escola:
CREATE OR REPLACE VIEW salario_escola(id_escola, total_salario, n_professores) AS
SELECT id_escola, SUM(salario), COUNT(*)
FROM professor
GROUP BY id_escola;Usando Visões
Uma vez definida, a visão pode ser usada em consultas exatamente como uma tabela real:
-- Consulta a visão pública (sem salário)
SELECT nome, ch_semanal
FROM professores_publico
WHERE id_escola = 31
ORDER BY nome;| nome | ch_semanal |
|---|---|
| Gustavo Costa | 20 |
| Helena Carvalho | 40 |
| Igor Melo | 20 |
-- Junta a visão de salário com a tabela escola
SELECT e.nome_escola, s.total_salario, s.n_professores,
ROUND(s.total_salario::numeric / s.n_professores, 2) AS media_salario
FROM salario_escola s
JOIN escola e USING (id_escola)
ORDER BY s.total_salario DESC;| nome_escola | total_salario | n_professores | media_salario |
|---|---|---|---|
| Escola Superior de Gestão | 13100 | 2 | 6550.00 |
| Escola Superior de Engenharias, Tecnologia e Inovação | 13100 | 3 | 4366.67 |
| Escola de Educação, Magistério e Arte | 9600 | 2 | 4800.00 |
Visões Definidas sobre Outras Visões
Uma visão pode referenciar outra visão em sua definição. Dizemos que a visão v₁ depende diretamente de v₂ quando v₂ é usada na expressão que define v₁, e que v₁ depende de v₂ se há uma cadeia de dependências entre elas.
Visão de professores de tempo integral de cada escola (usa a visão professores_publico):
CREATE OR REPLACE VIEW professores_40h AS
SELECT id_prof, nome, id_escola
FROM professores_publico
WHERE ch_semanal = 40;Consulta que usa a visão derivada:
SELECT e.sigla AS escola, p.nome AS professor
FROM professores_40h p
JOIN escola e USING (id_escola)
ORDER BY e.sigla, p.nome;| escola | professor |
|---|---|
| EEMA | Felipe Araujo |
| ESETI | Helena Carvalho |
| ESG | Bruno Teixeira |
| ESG | Carla Pinto |
Expansão de Visão
Quando uma consulta usa uma visão, o SGBD substitui a referência à visão pela expressão de consulta que a define — processo chamado de expansão de visão. Isso se repete recursivamente até que nenhuma visão permaneça na expressão final.
A expansão funciona substituindo iterativamente cada visão vᵢ encontrada na expressão e₁ pela sua definição. O processo termina quando não há mais visões na expressão — desde que as definições não sejam recursivas.
Visões Materializadas
Uma visão materializada (materialized view) é uma visão cujo resultado é fisicamente armazenado no banco de dados. Diferentemente de uma visão comum, ela ocupa espaço em disco e precisa ser mantida (atualizada) quando as tabelas subjacentes mudam.
O PostgreSQL suporta visões materializadas com CREATE MATERIALIZED VIEW. O refresco é manual com REFRESH MATERIALIZED VIEW.
CREATE MATERIALIZED VIEW IF NOT EXISTS mv_desempenho_aluno AS
SELECT a.id_aluno, a.nome, a.id_curso,
COUNT(*) AS disciplinas_cursadas,
ROUND(AVG(md.nota), 2) AS media_geral,
SUM(CASE WHEN md.aprovado = 1 THEN 1 ELSE 0 END) AS aprovacoes
FROM aluno a
JOIN matricula_disciplina md USING (id_aluno)
WHERE md.nota IS NOT NULL
GROUP BY a.id_aluno, a.nome, a.id_curso;-- Consultando a visão materializada
SELECT nome, media_geral, aprovacoes, disciplinas_cursadas
FROM mv_desempenho_aluno
ORDER BY media_geral DESC NULLS LAST;| nome | media_geral | aprovacoes | disciplinas_cursadas |
|---|---|---|---|
| Beatriz Carvalho | 9.30 | 2 | 2 |
| Camila Teixeira | 8.00 | 2 | 2 |
| Carolina Lima | 8.00 | 4 | 4 |
| Letícia Souza | 7.90 | 2 | 2 |
| Rafael Costa | 7.75 | 4 | 4 |
| Amanda Moreira | 7.70 | 6 | 6 |
| Gabriel Ribeiro | 7.25 | 4 | 4 |
| Matheus Silva | 7.22 | 5 | 6 |
| Rodrigo Lima | 6.60 | 2 | 2 |
| Vinícius Pereira | 6.55 | 2 | 2 |
-- Refresco manual (atualiza a visão com os dados atuais das tabelas base)
REFRESH MATERIALIZED VIEW mv_desempenho_aluno;Atualização de Visões
Em geral, uma visão só pode ser atualizada (suportar INSERT, UPDATE, DELETE) quando satisfaz certas condições que garantem que a operação pode ser traduzida univocamente para a tabela base.
Uma visão é considerada atualizável pelo SQL quando:
- A cláusula
FROMcontém apenas uma tabela base. - A cláusula
SELECTcontém apenas nomes de atributos (sem expressões, agregações ouDISTINCT). - Todo atributo não listado no
SELECTpode receberNULL. - A consulta não contém
GROUP BYnemHAVING.
A visão professores_publico é atualizável — contém uma única tabela base e apenas nomes de colunas. No entanto, inserir via ela exige que salario (não exposto) aceite NULL:
-- Insere um professor novo pela visão (salario ficará NULL na tabela base)
INSERT INTO professores_publico (id_prof, nome, id_escola, ch_semanal)
VALUES (31200004, 'Julia Mendes', 31, 20);Visões como salario_escola (que usam GROUP BY) não são atualizáveis. Tentativas de inserção ou atualização direta são rejeitadas pelo SGBD.
Para Praticar
-- Visão de disciplinas com pré-requisitos: mostra o nome de ambas
CREATE OR REPLACE VIEW v_prereqs AS
SELECT d.id_disciplina,
d.nome_disciplina AS disciplina,
dp.nome_disciplina AS prerequisito,
d.id_curso,
d.semestre
FROM prereq pr
JOIN disciplina d ON d.id_disciplina = pr.id_disciplina
JOIN disciplina dp ON dp.id_disciplina = pr.id_prereq;-- Usando a visão para listar pré-requisitos do curso ENS
SELECT disciplina, prerequisito, semestre
FROM v_prereqs
WHERE id_curso = 311
ORDER BY semestre, disciplina;| disciplina | prerequisito | semestre |
|---|---|---|
| Bases da Eng. de Software 4 | Bases da Eng. de Software 2 | 4 |
| Projeto Aplicado 4 - blockchain | Projeto Aplicado 2 - site WEB | 4 |
| Bases da Eng. de Software 6 | Bases da Eng. de Software 4 | 6 |
| Bases da Eng. de Software 6 | Projeto Aplicado 4 - blockchain | 6 |
| Projeto Aplicado 6 - Machine Learning | Projeto Aplicado 4 - blockchain | 6 |
| Bases da Eng. de Software 8 | Bases da Eng. de Software 6 | 8 |
| Projeto Aplicado 8 - Sistema em Tempo Real | Bases da Eng. de Software 6 | 8 |
| Projeto Aplicado 8 - Sistema em Tempo Real | Projeto Aplicado 6 - Machine Learning | 8 |
-- Visão de alunos reprovados com informação do curso
CREATE OR REPLACE VIEW v_alunos_reprovados AS
SELECT a.nome AS aluno, c.sigla_curso, d.nome_disciplina,
md.nota, md.ano, md.semestre
FROM matricula_disciplina md
JOIN aluno a USING (id_aluno)
JOIN disciplina d USING (id_disciplina)
JOIN curso c ON c.id_curso = a.id_curso
WHERE md.aprovado = 0;SELECT * FROM v_alunos_reprovados ORDER BY sigla_curso, aluno;| aluno | sigla_curso | nome_disciplina | nota | ano | semestre |
|---|---|---|---|---|---|
| Fernanda Martins | ECO | História Econômica Geral | 3.4 | 2024 | 2 |
| Isabela Freitas | ENS | Projeto Aplicado 4 - blockchain | 0.4 | 2025 | 2 |
| Isabela Freitas | ENS | Bases da Eng. de Software 2 | 4.3 | 2024 | 2 |
| Juliana Nunes | ENS | Bases da Eng. de Software 2 | 1.9 | 2025 | 2 |
| Larissa Araújo | ENS | Bases da Eng. de Software 6 | 0.3 | 2025 | 2 |
| Matheus Silva | ENS | Bases da Eng. de Software 6 | 4.1 | 2025 | 2 |
| Thiago Gomes | PED | Eletiva II | 1.3 | 2025 | 2 |