Postgresql
相關事務後觸發一次更新物化視圖?
我正在使用 PostgreSQL 9.6。
我有一個物化視圖來支持跨兩個表的全文搜尋,我將其稱為
posts
和tags
。這些表不經常更新和經常搜尋。我試圖找到一個好的策略來執行
REFRESH MATERIALIZED VIEW post_search
。理想的解決方案是這樣的觸發器:在任何修改和****/或(連接表)的****事務結束時(或之後),只刷新一次實體化視圖
posts``tags``posts_tags
。我怎麼能做到這一點?
使用觸發器的 OK 解決方案
這就是我現在正在做的事情。這不是我想要的,因為觸發器在每個語句中觸發一次,而不是在每個事務中觸發一次。但它現在有效。
(在未來,我們正在考慮使用實際表進行搜尋而不是物化視圖,並通過觸發器更新各個相關行而不是刷新整個 matview。)
創建一個函式來同時刷新物化視圖:
CREATE OR REPLACE FUNCTION refresh_post_search() RETURNS TRIGGER LANGUAGE plpgsql AS $$ BEGIN REFRESH MATERIALIZED VIEW CONCURRENTLY post_search; RETURN NULL; END $$;
並為每個基礎表創建一個觸發器:
CREATE TRIGGER refresh_post_search AFTER INSERT OR UPDATE OR DELETE OR TRUNCATE ON posts FOR EACH STATEMENT EXECUTE PROCEDURE refresh_post_search(); CREATE TRIGGER refresh_post_search AFTER INSERT OR UPDATE OR DELETE OR TRUNCATE ON posts_tags FOR EACH STATEMENT EXECUTE PROCEDURE refresh_post_search(); CREATE TRIGGER refresh_post_search AFTER INSERT OR UPDATE OR DELETE OR TRUNCATE ON tags FOR EACH STATEMENT EXECUTE PROCEDURE refresh_post_search();
好吧,很可能你做錯了。雖然動詞
REFRESH
可能有其他含義,但您實際上是在執行表時重寫了它。在觸發器中執行這種工作負載很重(儘管您可以)。這沒有多大意義。你要麼
- 不想一個
MATERIALIZED VIEW;
- 想要
REFRESH
在停機時間、休息時間或定期進行策略。第二個通常是用
- 一個簡單的 cron、pg_cron或類似的
- 在導入結束時
通常,您要麼需要
- 永遠正確:使用普通視圖。
- 週期性正確:使用物化視圖。
- 流動性和正確性:您可以檢查
NOTIFY/EVENT
或時間序列數據庫a 很可能
MATERIALIZED VIEW
不是您想要的。