【PostgreSQL】トリガーで履歴テーブルへデータをinsertする
トリガーで履歴テーブルへデータをinsert
最新価格を保持するテーブルpriceと価格履歴テーブルprice_historyを考えます。priceテーブルに対する新規データ登録、データ更新時にprice_historyテーブルに同じデータをinsertすることで価格履歴を保持します。
price_historyテーブルへのデータ登録を確実に行うためにトリガーを使ってinsertを行います。トリガーはpriceテーブルへinsert、updateを行ったときに実行するようにします。
テーブルとトリガーの作成
以下のようにテーブルとトリガーを作成します。
-- 最新価格を保持するテーブル
create table price (
id serial,
product_id int not null,
price numeric not null,
updated_at timestamp with time zone not null,
constraint pk_price primary key(id)
);
-- 価格履歴を保持するテーブル
create table price_history (
id serial,
product_id int not null,
price numeric not null,
updated_at timestamp with time zone not null,
constraint pk_price_history primary key(id)
);
-- 更新日時をセットする関数
create function set_updated_at() returns trigger as $set_updated_at$
begin
NEW.updated_at = now();
return NEW;
end;
$set_updated_at$
language plpgsql;
-- 価格履歴をinsertする関数
create function insert_price_history() returns trigger as $insert_price_history$
begin
insert into price_history (product_id, price, updated_at) values (NEW.product_id, NEW.price, NEW.updated_at);
return NEW;
end;
$insert_price_history$
language plpgsql;
-- 更新日時をセットするトリガーを作成
create trigger set_updated_at_trigger before insert or update on price for each row execute function set_updated_at();
create trigger set_updated_at_trigger before insert or update on price_history for each row execute function set_updated_at();
-- 価格履歴をinsertするトリガーを作成
create trigger insert_price_history_trigger after insert or update on price for each row execute function insert_price_history();
動作確認
priceテーブルに対してinsert、updateを行い動作確認を行います。
-- priceテーブルへのinsert
$ insert into price (product_id, price) values (1, 100);
INSERT 0 1
$ select * from price;
id | product_id | price | updated_at
----+------------+-------+-------------------------------
1 | 1 | 100 | 2021-05-17 14:36:17.174571+00
(1 row)
$ select * from price_history;
id | product_id | price | updated_at
----+------------+-------+-------------------------------
1 | 1 | 100 | 2021-05-17 14:36:17.174571+00
$ insert into price (product_id, price) values (2, 200);
INSERT 0 1
$ select * from price;
id | product_id | price | updated_at
----+------------+-------+-------------------------------
1 | 1 | 100 | 2021-05-17 14:36:17.174571+00
2 | 2 | 200 | 2021-05-17 14:37:02.012947+00
$ select * from price_history;
id | product_id | price | updated_at
----+------------+-------+-------------------------------
1 | 1 | 100 | 2021-05-17 14:36:17.174571+00
2 | 2 | 200 | 2021-05-17 14:37:02.012947+00
$ update price set price = 201 where id = 1;
UPDATE 1
$ select * from price;
id | product_id | price | updated_at
----+------------+-------+-------------------------------
2 | 2 | 200 | 2021-05-17 14:37:02.012947+00
1 | 1 | 201 | 2021-05-17 14:37:48.462558+00
(2 rows)
$ select * from price_history;
id | product_id | price | updated_at
----+------------+-------+-------------------------------
1 | 1 | 100 | 2021-05-17 14:36:17.174571+00
2 | 2 | 200 | 2021-05-17 14:37:02.012947+00
3 | 1 | 201 | 2021-05-17 14:37:48.462558+00