How to make materialized view refresh automatically in postgres?

how can materialized view refresh automatically in postgres?

because to do BI applications, you need to use materialized view, but it is troublesome to manually refresh every time. How can you let materialized view update automatically when the data source generates new data?

Aug.04,2021

I think we can consider using AFTER triggers to meet the needs of the subject in PG.

suppose you have a table foo whose definition and available data are as follows:

postgres=-sharp \d+ foo;
                                    Table "public.foo"
 Column |  Type   | Collation | Nullable | Default | Storage  | Stats target | Description 
--------+---------+-----------+----------+---------+----------+--------------+-------------
 id     | integer |           | not null |         | plain    |              | 
 name   | text    |           |          |         | extended |              | 
Indexes:
    "idx_foo" PRIMARY KEY, btree (id)
    
postgres=-sharp SELECT * FROM foo;
 id |      name       
----+-----------------
  1 | Paul McCartney
  2 | John Lennon
  3 | George Harrison
  4 | Ringo Starr
(4 rows)

the following steps create a materialized view and create an automatic refresh trigger associated with it

  1. create a materialized view

    postgres=-sharp CREATE MATERIALIZED VIEW mvfoo AS SELECT * FROM foo;
  2. create a trigger function to refresh the materialized view

    postgres=-sharp CREATE OR REPLACE FUNCTION tri_foo_func() RETURNS TRIGGER AS $$ BEGIN REFRESH MATERIALIZED VIEW mvfoo; RETURN NULL; END; $$ LANGUAGE plpgsql;

    since we are going to create an AFTER trigger, the function returns NULL

  3. create the AFTER trigger itself

    CREATE TRIGGER tri_foo AFTER INSERT OR UPDATE OR DELETE ON foo FOR EACH STATEMENT EXECUTE PROCEDURE tri_foo_func();
    The trigger is triggered by

    INSERT, UPDATE, DELETE events

then you can do a simple check

  1. query the materialized view when no changes have been made to the table

    postgres=-sharp SELECT * FROM mvfoo;
     id |      name       
    ----+-----------------
      1 | Paul McCartney
      2 | John Lennon
      3 | George Harrison
      4 | Ringo Starr
    (4 rows)
  2. query the materialized view after updating the table (in this case, the INSERT operation).

    postgres=-sharp INSERT INTO foo VALUES (5, 'Brain Epstein');
    INSERT 0 1
    postgres=-sharp SELECT * FROM mvfoo;
     id |      name       
    ----+-----------------
      1 | Paul McCartney
      2 | John Lennon
      3 | George Harrison
      4 | Ringo Starr
      5 | Brain Epstein
    (5 rows)

    it can be seen that this set of trigger-based materialized view automatic refresh mechanism has taken effect

    however, it must be emphasized that using triggers is harmful to the update performance of the original table , please use it carefully in combination with specific application scenarios.

Menu