触发器
触发器可以在表数据插入、更新或删除时自动执行数据库函数。它适合维护更新时间、写审计日志、同步汇总字段等靠近数据层的逻辑。
适用场景
- 自动维护
updated_at字段。 - 写入审计日志或变更历史。
- 维护计数、状态或冗余字段。
- 对复杂写入做数据库层校验。
不要把耗时外部调用放进触发器。触发器在事务内执行,耗时过长会影响写入性能和锁释放。
自动维护更新时间
触发器函数需要读取 NEW / OLD 行变量并返回 trigger,属于过程逻辑,必须使用 LANGUAGE plpgsql。
可以通过控制台或 SQL 语句创建触发器。当前云开发控制台的 PostgreSQL 管理界面与 Supabase 控制台保持一致,适合配置常规表触发器。
- 控制台操作
- SQL 语句操作
- 确认目标表已包含需要自动维护的字段,例如
public.todos.updated_at。 - 在「数据库函数」管理页面创建或选择触发器函数,例如
public.set_updated_at。该函数返回类型需要是trigger,语言选择LANGUAGE plpgsql。 - 打开「触发器」管理页面。
- 点击「新建触发器」。
- 选择目标表
public.todos。 - 配置触发时机为
BEFORE,触发事件为UPDATE,触发粒度为FOR EACH ROW。 - 选择触发器函数
public.set_updated_at,确认后提交。
控制台适合创建常规触发器。涉及复杂条件、批量迁移或需要与函数一起版本化发布时,建议使用 SQL 语句操作。
先创建触发器函数:
create or replace function public.set_updated_at()
returns trigger
LANGUAGE plpgsql
as $$
begin
new.updated_at = now();
return new;
end;
$$;
再绑定到表:
create trigger todos_set_updated_at
before update on public.todos
for each row
execute function public.set_updated_at();
写审计日志
create table public.audit_logs (
id bigint generated by default as identity primary key,
table_name text not null,
row_id text not null,
action text not null,
changed_at timestamptz not null default now()
);
create or replace function public.log_todo_changes()
returns trigger
LANGUAGE plpgsql
as $$
begin
insert into public.audit_logs(table_name, row_id, action)
values ('todos', coalesce(new.id, old.id)::text, tg_op);
return coalesce(new, old);
end;
$$;
create trigger todos_audit_log
after insert or update or delete on public.todos
for each row
execute function public.log_todo_changes();
调试触发器
触发器逻 辑运行在数据库内部,调试时建议先在测试表中验证。可以使用 raise notice 输出调试信息。
raise notice 'trigger %, row id %', tg_op, new.id;
上线前应移除不必要的调试输出,避免影响日志可读性。
注意事项
- 触发器应保持短小,避免复杂循环和外部依赖。
- 同一表多个触发器的执行顺序可能影响结果,应明确命名和测试。
- 触发器在事务中执行,函数异常会导致整个写入回滚。
- 大批量导入前应评估触发器带来的额外写入成本。