Você deve atualizar a visualização nos gatilhos após inserir/atualizar/excluir/truncar para cada instrução em
table1
e table2
. create or replace function refresh_mat_view()
returns trigger language plpgsql
as $$
begin
refresh materialized view mat_view;
return null;
end $$;
create trigger refresh_mat_view
after insert or update or delete or truncate
on table1 for each statement
execute procedure refresh_mat_view();
create trigger refresh_mat_view
after insert or update or delete or truncate
on table2 for each statement
execute procedure refresh_mat_view();
Desta forma, sua visão materializada está sempre atualizada. Esta solução simples pode ser difícil de aceitar com inserções/atualizações frequentes e seleções esporádicas.
Para realizar a atualização adiada de uma visualização materializada, você precisa de um dos seguintes recursos:
- acionador assíncrono
- acionar antes de selecionar
- regra sobre selecionar antes
Postgres não tem nenhum deles, então parece que não há clear solução postgres.
Levando isso em consideração, eu consideraria uma função wrapper para seleções em mat_view, por exemplo.
CREATE OR REPLACE FUNCTION select_from_mat_view(where_clause text)
RETURNS SETOF mat_view AS $body$
BEGIN
-- here is checking whether to refresh the mat_view
-- then return the select:
RETURN QUERY EXECUTE FORMAT ('SELECT * FROM mat_view %s', where_clause);
END;
$body$ LANGUAGE plpgsql;
Se é aceitável na prática depende de particularidades que desconheço.