
ํ๋ก์ ํธ๋ฅผ ์งํํ๋ฉฐ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ updated_at ํ๋๋ฅผ ๊ฐฑ์ ํ๋ ์์ ์ ์๋์ผ๋ก ์ฒ๋ฆฌํ๋ ์ค, ์์์น ๋ชปํ ์๋ฌ๋ก ์ธํด ๋ฐ์ดํฐ ๋ณ๊ฒฝ ๊ธฐ๋ก์ด ์ ํํ ๋ฐ์๋์ง ์๋ ๋ฌธ์ ๋ฅผ ๋ฐ๊ฒฌํ์ต๋๋ค. ์ด๋ ๋ฐ์ดํฐ ๋ณ๊ฒฝ ์์ ์์ ๋ฌด๊ฒฐ์ฑ๊ณผ ์ผ๊ด์ฑ์ ๋ณด์ฅํ์ง ๋ชปํ๋ ์น๋ช ์ ์ธ ์ฝ์ ์ผ๋ก ์์ฉํ ์ ์์์ต๋๋ค.
์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ๋ฐ์ดํฐ๋ฒ ์ด์ค ์์ค์์ ๋ณ๊ฒฝ ์์ ๊ณผ ์์ ๊ธฐ๋ก์ ์๋์ผ๋ก ์ฒ๋ฆฌํ๋ ๋ฐฉ์์ ๋ชจ์ํ๊ณ , PostgreSQL ๊ธฐ๋ฐ์ Supabase์์ ์ ๊ณตํ๋ ํธ๋ฆฌ๊ฑฐ(Trigger) ๊ธฐ๋ฅ์ ๋์ ํ์ต๋๋ค. ํธ๋ฆฌ๊ฑฐ๋ ๋ฐ์ดํฐ ๋ณ๊ฒฝ ์ด๋ฒคํธ์ ๊ฒฐํฉ๋์ด ํ์ํ ๋ก์ง์ ์๋์ผ๋ก ์คํํจ์ผ๋ก์จ, ๋ฐ์ดํฐ ๋ฌด๊ฒฐ์ฑ์ ๋ณด์ฅํ๊ณ ๊ฐ๋ฐ์์ ์ถ๊ฐ์ ์ธ ๊ด๋ฆฌ ๋ถ๋ด์ ์ต์ํํ ์ ์๋ ๊ฐ๋ ฅํ ๋๊ตฌ์ ๋๋ค.
PostgreSQL์ ํธ๋ฆฌ๊ฑฐ๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค ํ ์ด๋ธ์์ ํ์ด ์ฝ์ (INSERT), ์์ (UPDATE), ์ญ์ (DELETE)๋๋ ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ ๋, ์๋์ผ๋ก ์ง์ ๋ ๋ก์ง์ ์คํํ๋ ๊ธฐ๋ฅ์ ๋๋ค. ๊ฐ๋ฐ์๋ ์ฌ์ฉ์ ์ ์ ํธ๋ฆฌ๊ฑฐ ํจ์๋ฅผ ์์ฑํ๊ณ ์ด๋ฅผ ํธ๋ฆฌ๊ฑฐ์ ์ฐ๊ฒฐํ์ฌ, ๋ฐ์ดํฐ ๋ฌด๊ฒฐ์ฑ์ ๋ณด์ฅํ๊ณ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์์ ์ ์๋ํํ ์ ์์ต๋๋ค.
ํธ๋ฆฌ๊ฑฐ๋ ์ง์ ๋ ์ด๋ฒคํธ์ ๋์ผํ ํธ๋์ญ์ (transaction) ๋ด์์ ์คํ๋ฉ๋๋ค. ํธ๋ฆฌ๊ฑฐ๊ฐ ์คํจํ๋ฉด ์ ์ฒด ํธ๋์ญ์ ์ด ๋กค๋ฐฑ(rollback)๋๋ฉฐ, ๋ฐ๋๋ก ํธ๋ฆฌ๊ฑฐ์ ์์ ์ด ๋ชจ๋ ์ฑ๊ณตํด์ผ๋ง ํธ๋์ญ์ ์ด ์ปค๋ฐ(commit)๋ฉ๋๋ค. ์ด๋ฌํ ๋์์ ๋ฐ์ดํฐ์ ์ ํ์ฑ๊ณผ ์์ ์ฑ์ ๋ณด์ฅํ๋ ๋ฐ ์ค์ํ ์ญํ ์ ํฉ๋๋ค.
๐
ํธ๋์ญ์ (transaction)
- ๋ฐ์ดํฐ๋ฒ ์ด์ค์์ ํ๋์ ์์ ๋จ์๋ก ๊ฐ์ฃผ๋๋ ์ฐ์ฐ๋ค์ ์งํฉ์ ๋๋ค.
- ํธ๋์ญ์ ์ ๋ชจ๋ ์ฑ๊ณต์ ์ผ๋ก ์คํ(commit)๋๊ฑฐ๋, ํ๋๋ผ๋ ์คํจํ๋ฉด ์ ์ฒด๊ฐ ์ทจ์(rollback)๋ฉ๋๋ค.
ํธ๋ฆฌ๊ฑฐ๋ ํธ๋ฆฌ๊ฑฐ ํจ์์ ์ด๋ฅผ ํธ์ถํ๋ ํธ๋ฆฌ๊ฑฐ ์ค์ ์ผ๋ก ๊ตฌ์ฑ๋ฉ๋๋ค. ํธ๋ฆฌ๊ฑฐ ํจ์๋ฅผ ์์ฑํ ํ, ํธ๋ฆฌ๊ฑฐ๋ฅผ ์์ฑํ์ฌ ํน์ ์ด๋ฒคํธ ๋ฐ์ ์ ํจ์๊ฐ ์คํ๋๋๋ก ์ค์ ํ ์ ์์ต๋๋ค.
CREATE FUNCTION ๋ฌธ์ผ๋ก ์์ฑ๋ฉ๋๋ค. ํจ์ ๋ณธ๋ฌธ์ $$ ๊ธฐํธ๋ก ๋ฌถ์ธ ๋ฌธ์์ด๋ก ์ ์๋๋ฉฐ, ํธ๋ฆฌ๊ฑฐ์ ์ฐ๊ฒฐ๋์ด ๋ฐ์ดํฐ๋ฒ ์ด์ค ์์
์ ํธ์ถ๋ฉ๋๋ค.-- ํจ์ ์ด๋ฆ์ ์ ์ํฉ๋๋ค.
CREATE FUNCTION {function_name}
-- ํจ์๊ฐ ํธ๋ฆฌ๊ฑฐ์ฉ ํจ์์์ ๋ช
์ํฉ๋๋ค.
-- '$$'๋ (์์๋ฐ์ดํ ๋์ ) ์ฌ๋ฌ ์ค๋ก ๊ตฌ์ฑ๋ ์ฝ๋๋ฅผ ๋ฌธ์์ด๋ก ์ ๋ฌํ ๋ ์ฌ์ฉ๋ฉ๋๋ค.
RETURNS TRIGGER AS $$
BEGIN
-- 'NEW'๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ฝ์
๋๋ ์์ ๋ ์๋ก์ด ๋ฐ์ดํฐ๋ฅผ ๋ํ๋
๋๋ค.
NEW.{table_columns} = {value};
-- ํธ๋ฆฌ๊ฑฐ ํจ์๋ ๋ฐ๋์ ๋ฐ์ดํฐ ํ์ ๋ฐํํด์ผ ํฉ๋๋ค.
-- NEW๋ ์์ ๋ ๋ฐ์ดํฐ๋ฅผ ๋ฐํํ๊ณ , OLD๋ ์์ ์ ๋ฐ์ดํฐ๋ฅผ ๋ฐํํฉ๋๋ค.
RETURN {NEW | OLD};
END;
-- ํธ๋ฆฌ๊ฑฐ ํจ์์์ ์ฌ์ฉํ๋ ์ธ์ด๋ฅผ ์ง์ ํ ๊ฒ์ผ๋ก, PostgreSQL์ ํ๋ก์์ ์ธ์ด๋ฅผ ๋๊ฐ ์ฌ์ฉํฉ๋๋ค.
$$ LANGUAGE plpgsql;
CREATE TRIGGER ๋ฌธ์ ํตํด ์์ฑ๋๋ฉฐ, ํน์ ์ด๋ฒคํธ ๋ฐ์ ์ ์คํ๋ ํจ์๋ฅผ ํธ์ถํฉ๋๋ค.-- CREATE TRIGGER๋ฅผ ํตํด ์์ฑํฉ๋๋ค.
CREATE TRIGGER {trigger_name}
-- ์คํ ์ ํ์ ์ง์ ํฉ๋๋ค.
-- AFTER๋ ํธ๋ฆฌ๊ฑฐ ๋ฐ์ดํฐ๊ฐ ๋ณ๊ฒฝ๋ ์ดํ์ ์คํ๋ฉ๋๋ค.
-- BEFORE๋ ํธ๋ฆฌ๊ฑฐ ๋ฐ์ดํฐ๊ฐ ๋ณ๊ฒฝ๋๊ธฐ ์ด์ ์ ์คํ๋ฉ๋๋ค.
{AFTER|BEFORE} {INSERT|UPDATE|DELETE} ON {table_name}
-- ์คํ๋น๋๋ฅผ ์ ํ๋ ์ต์
์
๋๋ค.
-- row๋ผ๋ฉด ๊ฐ ํ์ ํ ๋ฒ์ฉ ์คํ๋์ด์ผ ํ๊ณ ,
-- statement๋ ์ ์ฒด ์ฝ์
์ ํ ๋ฒ ์คํ๋ฉ๋๋ค.
FOR EACH {ROW|STATEMENT}
-- ํธ์ถํ ๋์ ํจ์๋ฅผ ๋ฑ๋กํฉ๋๋ค.
EXECUTE FUNTION {trigger_function()}
ํธ๋ฆฌ๊ฑฐ๋ ๋ฐ์ดํฐ ๋ณ๊ฒฝ ์ด๋ฒคํธ๋ง๋ค ์คํ๋๋ฏ๋ก, ํธ๋ฆฌ๊ฑฐ ๋ก์ง์ ๊ณผ๋ํ ๊ณ์ฐ์ด๋ ๋ณต์กํ ์ฐ์ฐ์ด ํฌํจ๋ ๊ฒฝ์ฐ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฑ๋ฅ์ ์ํฅ์ ๋ฏธ์น ์ ์์ต๋๋ค. ๋ก์ง์ ์ต์ํ์ ์ฐ์ฐ์ผ๋ก ๊ฐ๊ฒฐํ๊ฒ ์์ฑํด์ผ ํฉ๋๋ค.
ํธ๋ฆฌ๊ฑฐ๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค ๋ด๋ถ์์ ๋น๋๊ธฐ์ ์ผ๋ก ์คํ๋์ง ์๊ณ , ํธ๋์ญ์ ๋ด์์ ์ฆ์ ์คํ๋๋ฏ๋ก, ์คํจ ์ ์ ์ฒด ํธ๋์ญ์ ์ด ๋กค๋ฐฑ๋ฉ๋๋ค. ์ด๋ฌํ ํน์ฑ์ผ๋ก ์ธํด ์์์น ๋ชปํ ๋์์ด๋ ์ค๋ฅ๋ฅผ ๋๋ฒ๊น ํ๊ธฐ๊ฐ ์ด๋ ต์ต๋๋ค.
ํธ๋ฆฌ๊ฑฐ๋ ํ ์ด๋ธ ์์ค์์ ์ค์ ๋๋ฏ๋ก, ์๋ํ์ง ์์ ๋ถ์์ฉ(์: ๋ฌดํ ๋ฃจํ ํธ๋ฆฌ๊ฑฐ ํธ์ถ)์ด ๋ฐ์ํ์ง ์๋๋ก ์ค๊ณํด์ผ ํฉ๋๋ค. ํธ๋ฆฌ๊ฑฐ ์คํ ์กฐ๊ฑด๊ณผ ์ ์ฉ ๋ฒ์๋ฅผ ๋ช ํํ ์ ์ํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค.
๋ฐ์ดํฐ ๋ณ๊ฒฝ์ด ์์ฃผ ๋ฐ์ํ๋ ํ ์ด๋ธ์ ํธ๋ฆฌ๊ฑฐ๋ฅผ ์ค์ ํ ๊ฒฝ์ฐ, ์ด๋ฒคํธ ๋น๋์ ํธ๋ฆฌ๊ฑฐ ์คํ ์๊ฐ์ด ์ฟผ๋ฆฌ ์๋ต ์๋์ ์ํฅ์ ๋ฏธ์น ์ ์์ต๋๋ค. ์ด๋ฅผ ์ต์ํํ๊ธฐ ์ํด ํธ๋ฆฌ๊ฑฐ ๋ก์ง์ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์์ (์: UPDATE, INSERT) ์ธ๋ถ์์ ์ฒ๋ฆฌํ ์ ์๋ ์ฐ์ฐ์ ๋ฐฐ์ ํ๊ณ , ๋ฐ์ดํฐ๋ฒ ์ด์ค ๋ด์์๋ง ์ฒ๋ฆฌ ๊ฐ๋ฅํ ์์ ์ ์ง์คํด์ผ ํฉ๋๋ค.
์ ๊ตฌ๋ฌธ ๋ฐฉ์์ ๋ฐ๋ผ updated_at์ ์๋์ผ๋ก ์
๋ฐ์ดํธ ํ๋ ํธ๋ฆฌ๊ฑฐ ํจ์ ๋ฐ ํธ๋ฆฌ๊ฑฐ๋ฅผ ์์ฑํ์ต๋๋ค. ์ด๋ฅผ Supabase Dashboard > SQL Editor ์์ ์คํํ์ฌ ์ค์ ํฉ๋๋ค.
# trigger function
CREATE OR REPLACE FUNCTION update_timestamp()
RETURNS TRIGGER AS $$
BEGIN
NEW.updated_at = NOW();
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
# trigger
CREATE TRIGGER update_house_trigger
BEFORE INSERT OR UPDATE ON house
FOR EACH ROW
EXECUTE FUNCTION update_timestamp();
CREATE TRIGGER update_profile_trigger
BEFORE INSERT OR UPDATE ON user_profile
FOR EACH ROW
EXECUTE FUNCTION update_timestamp();
CREATE OR REPLACE: ํจ์๊ฐ ์ด๋ฏธ ์กด์ฌํ๋ฉด ๋ฎ์ด์ฐ๊ณ , ์กด์ฌํ์ง ์์ผ๋ฉด ์๋ก ์์ฑํ๋ ๋ช
๋ น์ด์
๋๋ค.RETURNS TRIGGER : ์ด ํจ์๋ ํธ๋ฆฌ๊ฑฐ ํจ์์์ ์๋ ค์ค๋๋ค. ์ฆ, ํ
์ด๋ธ์ ๋ฐ์ดํฐ๊ฐ ๋ณ๊ฒฝ๋ ๋ ์๋์ผ๋ก ํธ์ถ๋ ํจ์์์ ์๋ ค์ค๋๋ค.AS $$ ... $$ : ํจ์๋ฅผ ์ ์ํ๋ ๊ตฌ๊ฐ์ผ๋ก $$ ๋ ํจ์ ๋ณธ๋ฌธ์ ๋๋ฌ์ธ๋ ๊ตฌ๋ถ์์
๋๋ค.(์ผ์ข
์ ' '(๋ฐ์ดํ)์ ๊ฐ์ ๊ฒ๋๋ค. ' '๋ก๋ ํ ์ ์์ง๋ง, ํจ์ ๋ด๋ถ์์ ๋ฐ์ดํ๋ฅผ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ \๋ฅผ ๋ถ์ฌ์ ์ฌ์ฉํ๋ ๋ฑ ๋ถํธํจ์ด ๋ง์ $$๋ก ๊ฐ์ธ์ ์ฌ์ฉํ๋ ๊ฒ์ด ์ผ๋ฐ์ ์
๋๋ค.)BEGIN ... END : ํจ์ ์คํ ๊ตฌ๊ฐ ์์๊ณผ ๋์ ์๋ ค์ค๋๋ค. ํจ์ ๋ณธ๋ฌธ์ ์ฌ์ด์ ์์ฑํฉ๋๋ค.NEW : ํธ๋ฆฌ๊ฑฐ๊ฐ ๋์ํ๋ ๋์ ์์ฑใป์์ ๋๋ ๋ฐ์ดํฐ์ ์ ๊ฐ์ ๋ํ๋
๋๋ค. ์ฆ, ํด๋น ํ(column)์ ์ ๋ฐ์ดํฐ๋ฅผ ์ฐธ์กฐํฉ๋๋ค.NEW.updated_at ์ ์๋ก ์์ฑ๋๊ฑฐ๋ ์์ ๋๋ ๋ฐ์ดํฐ ํ์ updated_at ์ด์ ๋ํ๋
๋๋ค.NOW() : ํ์ฌ ๋ ์ง์ ์๊ฐ์ ๋ฐํํ๋ supabase postgreSQL์ ๋ด์ฅ ํจ์์
๋๋ค.RETURN NEW : ํธ๋ฆฌ๊ฑฐ ํจ์๋ ํญ์ ์์ฑใป์์ ๋๋ ์๋ก์ด ๋ฐ์ดํฐ ํ์ ๋ฐํ ๊ฐ์ผ๋ก ์ค์ ํด์ผ ํฉ๋๋ค. ์ด ๋ฐํ๋๋ ๋ฐ์ดํฐ๊ฐ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ ์ฅ๋ฉ๋๋ค.SQL๋ก ์์ฑํ์ง ์๊ณ supabase dashboard๋ฅผ ํตํด์๋ ์์ ๋๊ฐ์ ํธ๋ฆฌ๊ฑฐ ํจ์๋ฅผ ์์ฑํ ์ ์์ต๋๋ค.
๋์ฌ๋ณด๋์์ Database > functions > Create a new function ์ ํตํด ์์ฑํ ์ ์์ต๋๋ค.

๋ํ๋ ์ฌ์ด๋ ๋ฐ์ ํจ์ ๋ช
๊ณผ, ํธ๋ฆฌ๊ฑฐ๋ฅผ ์ค์ ํ๊ณ , ํจ์ ๋ด์ฉ์ ์์ฑํ๋ฉด ๋์
๋๋ค.

ํธ๋ฆฌ๊ฑฐ ์ค์ ๋ํ supabase dash board๋ฅผ ์ฌ์ฉํด์๋ ์ฝ๊ฒ ์ค์ ํ ์ ์์ต๋๋ค.
๋์ฌ๋ณด๋์์ Database > triggers > Create a new trigger ๋ฅผ ํตํด ์์ฑํ ์ ์์ต๋๋ค.

๋ํ๋ ์ฌ์ด๋ ๋ฐ์ ํธ๋ฆฌ๊ฑฐ ๋ช
๊ณผ, ์ ์ฉํ ํ
์ด๋ธ, ํจ์๋ฅผ ํธ์ถํ ์ด๋ฒคํธ์ ์คํ ์๊ธฐ ๋ฑ์ ์ต์
์ ์ ํํ๊ณ ๋ง๋ ํธ๋ฆฌ๊ฑฐ ํจ์๋ฅผ ์ฐ๊ฒฐํด์ฃผ๋ฉด ๋ฉ๋๋ค.

์ด๋ ๊ฒ ์๋์ผ๋ก ์ฒ๋ฆฌํ๋ updated_at ํ๋ ๊ฐฑ์ ๋ก์ง์ ๋ฐ์ดํฐ๋ฒ ์ด์ค ํธ๋ฆฌ๊ฑฐ๋ก ๋์ฒดํ์ฌ, ๋ฐ์ดํฐ ์์ ์ updated_at์ด ์๋์ผ๋ก ๊ฐฑ์ ๋๋๋ก ๊ตฌํํ์ต๋๋ค.
์ด์ ๋ update ํจ์๋ฅผ ๋ถ๋ฌ์ ๋ฐ์ดํฐ๋ฅผ ๋๊ธธ ๋, new Date()๋ก ๋ถ๋ฌ์จ ํ์ฌ ์๊ฐ์ ์ ์ ํด์ ๋๊ธธ ํ์๊ฐ ์์ด์ก์ต๋๋ค. supabase์์ ์๋์ผ๋ก ์
๋ฐ์ดํธ ๋๋ ์๊ฐ์ ํ์์คํญํ๋ฅผ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ ์ฅํฉ๋๋ค.
์ด๋ฅผ ํตํด ๋ฐ์ดํฐ ๋ณ๊ฒฝ ๊ธฐ๋ก์ ์ ํ์ฑ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์์ค์์ ๋ณด์ฅํ ์ ์๊ฒ ๋์์ผ๋ฉฐ, ์ดํ๋ฆฌ์ผ์ด์ ์ฝ๋์์ ๋ฐ์ํ ์ ์๋ ๊ฐฑ์ ๋ก์ง์ ๋๋ฝ์ด๋ ์ค์๋ฅผ ์์ฒ์ ์ผ๋ก ๋ฐฉ์งํ์ต๋๋ค.
๋ํ, ๋ฐ์ดํฐ๋ฒ ์ด์ค์์ ์ง์ updated_at ๊ฐฑ์ ์ ์ฒ๋ฆฌํจ์ผ๋ก์จ ์๋ฒ-ํด๋ผ์ด์ธํธ ๊ฐ์ ๋ถํ์ํ ๋ฐ์ดํฐ ์ ๋ฌ ๋ฐ ์ฝ๋ ์ค๋ณต์ ์ ๊ฑฐํ์ฌ ์ ๋ฐ์ ์ธ ์ฝ๋๋ฒ ์ด์ค๋ฅผ ๊ฐ๊ฒฐํ๊ณ ์ ์ง๋ณด์ํ๊ธฐ ์ฝ๊ฒ ๊ฐ์ ํ์ต๋๋ค.