Menu

Views no SQLite: CREATE VIEW e INSTEAD OF

Como funcionam as views no SQLite: salvando consultas como tabelas virtuais, quando criar views temporárias e por que elas são read-only por padrão.

Esta página tem editores executáveis — edite, execute e veja a saída na hora.

O que é uma view no SQLite

Uma view nada mais é do que um SELECT com nome. Depois de criar uma, você consulta ela como se fosse uma tabela comum — só que nada fica armazenado de fato. A cada vez que você lê de uma view, o SQLite executa a query original do zero.

paid_orders parece e se comporta como uma tabela. Tem colunas, dá pra usar SELECT, dá pra fazer JOIN. Mas, por baixo dos panos, toda consulta é expandida para o filtro original WHERE status = 'paid'.

Esse é o modelo mental que importa: uma view é um apelido para uma consulta.

Por que usar views no SQLite

O maior ganho é dar nome às coisas. Uma consulta complicada ganha um nome curto e descritivo, e o resto do seu código continua legível:

Sem a view, cada chamador teria que escrever o GROUP BY na mão — e qualquer um deles poderia errar o filtro. Com ela, a agregação fica definida em um único lugar. Os chamadores só precisam consultar customer_totals e aplicar os filtros adicionais que quiserem por cima.

Views também funcionam como uma espécie de fronteira de permissão. Se uma consulta não deve expor a coluna password_hash, crie uma view que selecione tudo menos essa coluna e faça o código da aplicação usar a view.

Sintaxe do CREATE VIEW no SQLite

A forma completa:

CREATE [TEMPORARY] VIEW [IF NOT EXISTS] view_name [(column_aliases)] AS
SELECT ...;

Algumas coisas que vale a pena saber:

  • IF NOT EXISTS ignora a criação silenciosamente caso a view já exista.
  • TEMPORARY (ou TEMP) cria uma view temporária que some quando a conexão é fechada.
  • Os aliases de coluna entre parênteses permitem renomear as colunas da view sem mexer no SELECT original.

A view expõe nomes mais amigáveis (item, dollars) sem precisar renomear as colunas da tabela original.

Substituindo e removendo views no SQLite

O SQLite não tem CREATE OR REPLACE VIEW nem ALTER VIEW. Para alterar a definição de uma view, o jeito é remover e criar de novo:

DROP VIEW IF EXISTS active_orders; é a forma segura — não dá erro caso a view não exista. Apagar uma view nunca mexe nas tabelas subjacentes; você está removendo apenas a consulta salva.

Views temporárias no SQLite

Uma TEMP VIEW existe somente enquanto durar a conexão atual com o banco. Quando a conexão é encerrada, a view some junto. É útil em sessões de análise pontual, quando você não quer deixar definições espalhadas pelo banco:

Views temporárias também são úteis pra "sombrear" o nome de uma consulta sem precisar gravar isso no schema — ótimo na hora de explorar dados.

Views no SQLite são read-only por padrão

Esse é o detalhe mais importante de todos. Não dá pra fazer INSERT, UPDATE nem DELETE direto em uma view:

sqlite> INSERT INTO paid_orders (customer, amount) VALUES ('Eve', 50);
Runtime error: cannot modify paid_orders because it is a view

A solução são as triggers INSTEAD OF. Você cria uma trigger que dispara no lugar da tentativa de escrita e traduz isso em uma operação real na tabela base:

A view continua sendo view — mas agora escrever nela tem para onde ir. A gente vê triggers com calma na próxima página.

Não existe materialized view no SQLite — faça na unha

Alguns bancos deixam você cachear o resultado de uma view em disco e atualizar quando quiser. O SQLite não tem isso. Toda leitura de uma view reexecuta a query por trás. Na maior parte dos casos isso nem incomoda — o SQLite é rápido e o planejador de queries é bom. Mas para agregações pesadas que você consulta muitas vezes, o jeito é criar uma tabela de verdade e manter ela sincronizada na mão:

Você precisa atualizar esse cache em intervalos definidos, ou então configurar triggers na tabela orders para manter os dados em dia. Dá trabalho braçal — mas é a única alternativa no SQLite.

Listando views no SQLite

Os metadados das views ficam guardados em sqlite_master, no mesmo lugar das tabelas e dos índices:

A coluna sql devolve o CREATE VIEW original — ótimo pra quando você esqueceu o que uma view faz. No CLI, o comando .schema nome_da_view mostra a mesma coisa de forma mais limpa.

Quando usar uma view no SQLite

As views valem a pena quando:

  • Uma consulta não-trivial aparece repetida em três ou mais lugares. Dar um nome a ela uma vez é melhor do que ficar copiando e colando.
  • Você quer expor um recorte específico de colunas ou linhas para uma parte da aplicação.
  • Uma agregação representa conceitualmente uma única coisa (monthly_sales, active_users) que faz sentido o consumidor tratar como um substantivo.

Pule a view quando:

  • A consulta é usada em um único lugar. Coloca ela inline e pronto.
  • Performance é crítica e a consulta por trás é cara — esse custo é pago a cada leitura. Nesses casos, é melhor materializar o resultado numa tabela real.
  • A view depende de outra view, que depende de outra view. O SQLite lida bem com esse aninhamento, mas uma cadeia de três ou quatro views torna o SQL real difícil de seguir na hora de debugar.

A seguir: triggers

Views e triggers costumam andar juntas — o padrão INSTEAD OF, que torna uma view gravável, é justamente uma das razões principais para os triggers existirem. Mas os triggers também brilham sozinhos: auditoria, cascateamento de updates e garantia de invariantes. É o assunto da próxima página.

Perguntas frequentes

O que é uma view no SQLite?

Uma view nada mais é do que um SELECT salvo, que você pode consultar como se fosse uma tabela. Ela não armazena dados — toda vez que você faz uma leitura, o SQLite executa a consulta original de novo. As views são úteis para dar nome a uma query complexa e reaproveitá-la em vários lugares, ou para esconder colunas que não devem aparecer para quem está consumindo os dados.

Dá para fazer INSERT ou UPDATE através de uma view no SQLite?

Direto não dá. As views no SQLite são read-only — qualquer INSERT, UPDATE ou DELETE em cima de uma view vai falhar. O jeito de tornar uma view gravável é criar triggers INSTEAD OF, que traduzem a operação de escrita em comandos nas tabelas reais.

O SQLite suporta materialized views?

Não. O SQLite só tem views comuns (virtuais) — a query é executada toda vez que você lê da view. Se precisar de resultados em cache, o caminho é criar uma tabela de verdade e atualizá-la por conta própria, ou usar uma trigger para mantê-la sincronizada com as tabelas de origem.

Como listar todas as views de um banco SQLite?

Faça uma consulta na sqlite_master: SELECT name FROM sqlite_master WHERE type = 'view';. Pelo CLI, o comando .schema mostra os CREATE VIEW e o .tables lista as views junto com as tabelas.

Coddy programming languages illustration

Aprenda a programar com o Coddy

COMEÇAR