Debe actualizar la vista en los activadores después de insertar/actualizar/eliminar/truncar para cada declaración en table1
y 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();
De esta manera, su vista materializada siempre está actualizada. Esta solución simple puede ser difícil de aceptar con inserciones/actualizaciones frecuentes y selecciones esporádicas. En su caso (rara vez cambia dos veces al día) se ajusta idealmente a sus necesidades.
Para realizar actualización diferida de una vista materializada necesita una de las siguientes características:
- disparador asíncrono
- activar antes de seleccionar
- regla sobre seleccionar antes
Postgres no tiene ninguno de ellos, por lo que parece que no hay claro solución postgres.
Teniendo esto en cuenta, consideraría una función contenedora para selecciones en mat_view, por ejemplo,
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;
Si es aceptable en la práctica depende de detalles que desconozco.