Postgres 트리거
시나리오
책을 판매하는 전자 상거래 앱이 있고 데이터베이스에서 장바구니 기능을 구현하고 있습니다. 따라서 사용자당 고유한 카트 항목을 저장하는 카트 테이블과 책 테이블이 있습니다. 장바구니 항목의 경우
carts_books
다른 테이블이 있습니다. carts
및 carts_books
는 다대다 관계를 사용하고 있습니다. 따라서 카트에는 많은 책이 있을 수 있고 책은 많은 카트에서 사용할 수 있습니다.carts_books
테이블에 행이 삽입되거나 업데이트될 때마다 사용한 카트의 총 가격을 계산하고 싶습니다. multiplier
테이블의 carts_books
열도 고려하고 싶습니다. 이 multiplier
열은 단일 책의 수량입니다. 즉, 고객이 책을 여러 부 구매하도록 허용하고 있습니다.Postgres 트리거를 사용하여 이 문제를 해결해 보겠습니다. 그 전에 아래는 지금까지 논의된 모든 테이블의 열 목록입니다.
스키마
Table "public.carts"
Column | Type | Collation | Nullable | Default
-------------+--------------------------+-----------+----------+--------------------
created_at | timestamp with time zone | | not null | now()
updated_at | timestamp with time zone | | not null | now()
archived_at | timestamp with time zone | | |
amount | numeric | | not null |
status | text | | not null | 'ENQUEUED'::text
user_id | text | | not null |
id | uuid | | not null | gen_random_uuid()
Table "public.books"
Column | Type | Collation | Nullable | Default
-------------+--------------------------+-----------+----------+-----------------------------------
created_at | timestamp with time zone | | not null | now()
updated_at | timestamp with time zone | | not null | now()
archived_at | timestamp with time zone | | |
name | text | | not null |
price | numeric | | not null |
user_id | bigint | | not null |
id | bigint | | not null | nextval('books_id_seq'::regclass)
description | text | | not null |
Table "public.carts_books"
Column | Type | Collation | Nullable | Default
------------+---------+-----------+----------+---------
book_id | bigint | | not null |
multiplier | integer | | not null |
user_id | text | | not null |
cart_id | uuid | | not null |
해결책
테이블
carts_books
의 행이 INSERTED 또는 UPDATED된 후 프로시저(함수라고도 함)를 실행하려고 합니다.이를 위해 두 개의 Postgres 트리거를 생성해 보겠습니다. 하나는 UPDATE용이고 다른 하나는 INSERT용입니다.
CREATE TRIGGER update_cart_price
AFTER UPDATE ON public.carts_books
FOR EACH ROW
EXECUTE PROCEDURE public.update_cart_price ();
COMMENT ON TRIGGER update_cart_price ON public.carts_books IS
'update the price of the related cart based on the updated cart item(s) in relation carts_books';
CREATE TRIGGER calculate_cart_price
AFTER INSERT ON public.carts_books
FOR EACH ROW
EXECUTE PROCEDURE public.update_cart_price ();
COMMENT ON TRIGGER calculate_cart_price ON public.carts_books IS
'update the price of the related cart based on the updated cart item(s) in relation carts_books';
위의 코드는 두 개의 Postgres 트리거를 생성하는 코드입니다. 구문과 위에서 사용한 각 절이 의미하는 바를 이해합시다.
Postgres 트리거를 생성하기 위해 Postgres에 다음 사항을 알리고 싶습니다.
update_cart_price
과calculate_cart_price
. 이를 위해
AFTER INSERT
및 AFTER UPDATE
절을 사용해야 합니다. update_cart_price()
라는 프로시저를 실행하는 이러한 트리거가 있습니다. You must create the function before using it in a function.
A function must returnTRIGGER
in order to be used in a trigger.
이 트리거에서 실행하려는 함수는 다음과 같이 정의됩니다.
`sql
CREATE OR REPLACE FUNCTION public.update_cart_price ()
RETURNS TRIGGER
AS $$
DECLARE
item record;
new_amount numeric := 0;
BEGIN
FOR item IN
SELECT
price,
multiplier
FROM
carts_books
JOIN books ON book_id = books.id
WHERE
cart_id = NEW.cart_id LOOP
new_amount := new_amount + (item.price * item.multiplier);
END LOOP;
UPDATE
carts
SET
amount = new_amount
WHERE
id = NEW.cart_id;
RETURN new;
END;
$$
LANGUAGE plpgsql;
`
This function selects the price and multiplier of all the books used inside the cart. It then updates the cart's amount column to reflect the updated amount.
The data of the changed row is made available through the new
기록.
또한 함수는 일반SQL
언어를 사용할 수 없으므로 절차적
언어.
결론
Postgres 트리거를 사용하면 데이터 변경에 대해 소규모 비즈니스 로직을 쉽게 실행할 수 있습니다.
또한 다른 서비스(예: nodejs 앱)에서 동일한 논리를 실행할 경우 직면하게 되는 네트워크 대기 시간에 대해 걱정할 필요가 없습니다.
굿리즈
이 게시물 외에도 Postgres에 대해 자세히 알아보려면 이 게시물을 읽는 것이 좋습니다.
방아쇠.
Official Docs Data visibility in trigger functions
Reference
이 문제에 관하여(Postgres 트리거), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/siddhantk232/postgres-triggers-5h0b텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)