簡體   English   中英

PostgreSQL 在更新特定列后觸發

[英]PostgreSQL Trigger after update of a specific column

我正在探索觸發器,並希望創建一個在game_saved列上的 Update 事件之后觸發的觸發器。 正如我在PostgreSQL 文檔中讀到的那樣,可以為列創建觸發器。 該列包含boolean值,因此用戶可以將游戲添加到他的收藏中或將其刪除。 所以我希望觸發器函數計算某個用戶在game_saved列中設置為 TRUE 的游戲數量。 然后更新total_game_countgame_collection表。

game_collection

id - BIGSERIAL primary key
user_id - INTEGER REFERENCES users(id)
total_game_count - INTEGER

game_info

id - BIGSERIAL primary key
user_id - INTEGER REFERENCES users(id)
game_id - INTEGER REFERENCES games(id)
review - TEXT
game_saved - BOOLEAN

這是我的觸發器(它不起作用,我想弄清楚原因):

CREATE OR REPLACE FUNCTION total_games() 
RETURNS TRIGGER AS $$ 
BEGIN 
UPDATE game_collection 
SET total_game_count = (SELECT COUNT(CASE WHEN game_saved THEN 1 END)
                        FROM game_info WHERE game_collection.user_id = game_info.user_id)
WHERE user_id = NEW.user_id; 
RETURN NEW; 
END; 
$$ LANGUAGE plpgsql; 

CREATE TRIGGER tr_total_games 
AFTER UPDATE OF game_saved FOR EACH ROW 
EXECUTE PROCEDURE total_games();

如果我將AFTER UPDATE OF game_saved (列)更改為AFTER UPDATE ON game_info (表),觸發器將正常工作。 因此,專門為列更新創建觸發器存在一些問題。

在列更新時觸發觸發器是個好主意還是我應該在這里尋找另一種方法?

語法是:

CREATE TRIGGER tr_total_games 
AFTER UPDATE OF game_saved ON game_info
FOR EACH ROW 
EXECUTE PROCEDURE total_games();

(如手冊中所述。)

但整個方法是可疑的。 通過觸發器使聚合保持最新在並發寫入負載下容易出錯。

如果沒有並發寫入負載,有更簡單的解決方案:只需從當前總數中加/減 1 ...

VIEW將是一個可靠的替代方案。 完全刪除game_collection.total_game_count列 - 可能還有整個表game_collection ,這似乎沒有任何其他目的。 改為創建一個VIEW

CREATE VIEW v_game_collection AS
SELECT user_id, count(*) AS total_game_count
FROM   game_info
WHERE  game_saved
GROUP  BY user_id;

這將返回在game_info中至少有 1 行的所有用戶,其中game_saved IS TRUE (並省略所有其他人)。

對於非常大的表,您可能需要MATERIALIZED VIEW或相關解決方案來提高讀取性能。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM