跳到主要内容

触发器

触发器可以在表数据插入、更新或删除时自动执行数据库函数。它适合维护更新时间、写审计日志、同步汇总字段等靠近数据层的逻辑。

适用场景

  • 自动维护 updated_at 字段。
  • 写入审计日志或变更历史。
  • 维护计数、状态或冗余字段。
  • 对复杂写入做数据库层校验。

不要把耗时外部调用放进触发器。触发器在事务内执行,耗时过长会影响写入性能和锁释放。

自动维护更新时间

触发器函数需要读取 NEW / OLD 行变量并返回 trigger,属于过程逻辑,必须使用 LANGUAGE plpgsql

可以通过控制台或 SQL 语句创建触发器。当前云开发控制台的 PostgreSQL 管理界面与 Supabase 控制台保持一致,适合配置常规表触发器。

  1. 确认目标表已包含需要自动维护的字段,例如 public.todos.updated_at
  2. 在「数据库函数」管理页面创建或选择触发器函数,例如 public.set_updated_at。该函数返回类型需要是 trigger,语言选择 LANGUAGE plpgsql
  3. 打开「触发器」管理页面。
  4. 点击「新建触发器」。
  5. 选择目标表 public.todos
  6. 配置触发时机为 BEFORE,触发事件为 UPDATE,触发粒度为 FOR EACH ROW
  7. 选择触发器函数 public.set_updated_at,确认后提交。

控制台适合创建常规触发器。涉及复杂条件、批量迁移或需要与函数一起版本化发布时,建议使用 SQL 语句操作。

写审计日志

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;

上线前应移除不必要的调试输出,避免影响日志可读性。

注意事项

  • 触发器应保持短小,避免复杂循环和外部依赖。
  • 同一表多个触发器的执行顺序可能影响结果,应明确命名和测试。
  • 触发器在事务中执行,函数异常会导致整个写入回滚。
  • 大批量导入前应评估触发器带来的额外写入成本。