[英]Efficiency between using a string as a table key and splitting it into two tables
[英]in postgres, splitting an update between two tables using Rules
嘗試使用規則維護編輯日志。
create table t1(
id serial primary key,
c1 text,
... );
create table edit_log(
id int references t1,
editor_id int references users,
edit_ts timestamp default current_timestamp );
更新后,希望update t1
並insert into edit_lot
update t1 set c1='abc', ... where id=456;
insert into edit_log( id, editor_id, current_timestamp );
除了任意數量的列,這將非常簡單明了,例如,
update t1 set c1='abc', c2='def', editor_id=123 where id=456;
update t1 set c3='xyz', editor_id=123 where id=456;
怎么寫規則呢?
我認為觸發器比規則更能為您服務。 考慮這個演示。
CREATE TEMP TABLE t1(id int, editor_id int, c1 text);
INSERT INTO t1(id, editor_id) VALUES (1,1),(2,2);
CREATE TEMP TABLE edit_log(id int, editor_id int, edit_ts timestamp);
CREATE OR REPLACE FUNCTION trg_t1_upaft_log()
RETURNS trigger AS
$BODY$
BEGIN
IF OLD IS DISTINCT FROM NEW THEN -- to avoid empty updates
INSERT INTO edit_log(id, editor_id, edit_ts)
VALUES(NEW.id, NEW.editor_id, now()::timestamp);
END IF;
RETURN NULL; -- trigger will be fired AFTER updates, return value is irrelevant.
END;
$BODY$
LANGUAGE plpgsql VOLATILE;
CREATE TRIGGER upaft_log
AFTER UPDATE ON t1
FOR EACH ROW
EXECUTE PROCEDURE trg_t1_upaft_log();
UPDATE t1 SET c1 = 'baz' WHERE id = 1;
SELECT * FROM edit_log; -- 1 new entry
UPDATE t1 SET c1 = 'baz' WHERE id = 1;
SELECT * FROM edit_log; -- no new entry, update changed nothing!
UPDATE t1 SET c1 = 'blarg';
SELECT * FROM edit_log; -- 2 new entries, update changed two rows.
DROP TRIGGER upaft_log ON t1;
DROP FUNCTION trg_t1_upaft_log()
-- Temp. tables will be dropped automatically at end of session.
根據規則確定要更新的行是非常困難或完全不可能的(取決於安裝程序的詳細信息)。
觸發AFTER UPDATE可以根據實際情況決定,是更好的選擇。 在這種情況下,還易於與(大多數)其他觸發器和/或規則集成。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.