视图、函数与触发器:数据库内的自动化 除了被动响应查询,PostgreSQL 还能「主动」工作——把常用查询固化为视图,把可复用逻辑写成函数,用触发器在数据变更时自动执行动作。本节介绍这三种数据库对象,它们能让你的应用更简洁、更一致、更不容易出错。 视图(View):给查询起个名字 视图是一段保存在数据库中的查询,表现得像一张「虚拟表」。你可以像查表一样查询视图,而它背后是对底层表的真实查询。 之后即可: 视图的价值: 简化复杂查询:把常用的多表联结封装起来,外部只查一个视图。 统一数据口径:多处使用同一段逻辑,保证一致性。 权限隔离:可只授权访问视图而非底层表,隐藏敏感列。 视图本身不存储数据(除非是物化视图),它只是「命名的查询」。
除了被动响应查询,PostgreSQL 还能「主动」工作——把常用查询固化为视图,把可复用逻辑写成函数,用触发器在数据变更时自动执行动作。本节介绍这三种数据库对象,它们能让你的应用更简洁、更一致、更不容易出错。
视图是一段保存在数据库中的查询,表现得像一张「虚拟表」。你可以像查表一样查询视图,而它背后是对底层表的真实查询。
-- 假设我们常需要「已支付订单及其用户邮箱」 CREATE VIEW paid_orders_with_email AS SELECT orders.id, users.email, orders.amount FROM orders JOIN users ON orders.user_id = users.id WHERE orders.status = 'paid';
之后即可:
SELECT * FROM paid_orders_with_email WHERE amount > 100;
视图的价值:
视图本身不存储数据(除非是物化视图),它只是「命名的查询」。Supabase 中,视图也可以通过客户端库像普通表一样查询,十分方便。
存储函数是一段保存在数据库中的可执行代码,接收参数、返回结果。它适合封装需要直接访问数据、且希望集中复用的逻辑。
PostgreSQL 的函数可以用多种语言编写,最常用的是 PL/pgSQL(过程化 SQL)。一个典型用途是「根据输入的用户 id,返回其订单总数」这类小而明确的计算。
函数的价值:
不过,过度把业务逻辑塞进函数会让系统难以维护——一般原则是:与数据强相关、需要保证一致性的小逻辑适合放函数;复杂的业务编排更适合放应用层或边缘函数。
触发器让你在「某张表发生插入、更新或删除时」自动执行一段函数。它是数据库层面的「事件监听」。
典型场景:
updated_at 时间戳。触发器由两部分组成:
概念结构: 事件(如 INSERT 到某表) → 触发器声明捕获该事件 → 调用触发器函数 → 执行预定义逻辑(修改数据、写日志、调用扩展等)
触发器强大但需谨慎使用:过多的触发器会让数据流变得难以追踪(「为什么这个字段被改了?」),调试也相对困难。建议只用于真正需要「在数据变更点强制保证一致性」的场景。
一个常见组合:用触发器在数据写入时调用函数,更新某个视图依赖的字段。例如「文章更新后,触发函数自动重新计算其字数与摘要,存回文章表」。这样应用层只需关心写入正文,后续的派生计算全部由数据库自动完成,保证一致性。
这三类对象在 Supabase 中都可以通过 SQL 直接创建:
把逻辑放进数据库有诸多好处,但也有代价:
务实做法是:把与数据完整性、派生计算强相关、需要跨所有客户端统一执行的逻辑放进数据库;把业务流程编排、外部交互等留给应用层。
视图命名查询、函数封装逻辑、触发器响应变更——它们赋予数据库「主动」的能力。合理运用,能让数据一致性更强、应用代码更简洁;滥用则增加复杂度。掌握分寸,是专业数据库设计的标志。
至此,第 3 章完成了从增删改查到联结聚合、再到自动化的完整 SQL 训练。从第 4 章开始,我们将在数据层之上引入身份认证,学习如何管理「使用数据的人」。