INTERVIEW PREP · 2026

⚡ Supabase 面试备考指南

The Postgres Development Platform — from architecture to interview
一份「讲得出原理」级别的 Supabase 学习文档:架构、RLS、Auth、Realtime、连接池逐个讲透,配 28 道高频面试题和一周学习路径。你已经在自己的网站上用过它——这份文档负责把「会用」升级成「能讲」。
📅 调研时间 2026-07-19 📚 官方文档 14 页全文核对 🎯 面向面试 ⏱ 一周计划
🚀

30 秒速览

What is Supabase

先拿到全貌,再逐层加深——读完这一节,你已经能回答面试的第一个问题。

Supabase 是一个开源的后端即服务平台(BaaS,Backend as a Service)。「后端即服务」的意思是:你只写前端,后端那一整套——数据库、用户登录、文件存储、实时推送、服务端函数——它打包提供,不用你自己搭服务器。它最常被介绍为「开源的 Firebase 替代品」,但底座完全不同:Firebase 用私有 NoSQL,Supabase 给你一个完整的、不加抽象层的 PostgreSQL 数据库

你的前端代码 Web / App + supabase-js Supabase 🐘 Postgres 数据库 🔐 Auth 认证 📡 Realtime 实时 🗂 Storage 存储 λ Edge Functions 服务端函数 完整上线的应用 不用自己搭后端
Supabase 的定位:前端之外的一切后端能力,打包成一个平台交付

速览版的三个核心记忆点:

450 万+
开发者(官方与投资方 Craft Ventures 2026 年称)
10 万+/秒
平台处理的 API 请求(官方称)
55%
最近一期 YC 创业营选用 Supabase(官方博客称)
🧭

背景与动机

Why it exists

面试里「为什么会有 Supabase」比「Supabase 是什么」更能体现理解深度。

先看它出现之前的世界。2010 年代,Google 的 Firebase 把「不用写后端」变成了现实:前端直接读写云端数据、内置登录、实时同步,创业团队爱不释手。但它有两个越用越疼的痛点:

Supabase 的回答很直接:用世界上最流行的开源关系型数据库做底座,把 Firebase 的开发体验搬到它上面。官方架构文档里有一句关键表述——他们认为没有其他数据库能在保持可扩展性的同时,提供与 Firebase 竞争所需的功能,所以选择了 Postgres。这句可以在面试里直接引用。

💡 一个重要的认知纠偏:官方多次强调 Supabase 不是「Firebase 的克隆」,而是「Postgres 开发平台」(它的 GitHub 简介就是 The Postgres development platform)。它做的事是:把 Postgres 本来就有的能力(行级安全、逻辑复制、扩展生态)包装成开箱即用的产品,而不是重新发明一套。这也是官方产品原则之一:「扩展现有工具,而非新建工具」。

到 2026 年,它的增长又叠加了一层新动力:AI 编程。据投资方 Craft Ventures 的分析文章,AI 编程工具和「vibe coding」应用大量默认选择 Supabase 当后端(生成的代码就是标准 SQL + 标准 API,对 AI 友好),推动开发者数量在一年内从约 100 万涨到 450 万以上。官方也在 2026 年 6 月上线了 ChatGPT 集成,可以用对话方式管理数据库。这些属于「官方与投资方口径」,引用时注意措辞。

🏗️

架构总览:一个数据库,一圈服务

Architecture ★

面试最高频考点之一:「讲讲 Supabase 的架构」。这一节的目标是让你能白纸画出这张图。

Supabase 不是一个大单体,而是一组围绕 Postgres 的独立开源服务。每个服务只做一件事,全部通过 API 网关对外。理解顺序:先记住「下面是唯一的数据库,上面是一排无状态服务,最前面是网关」,再逐个认识每个服务。

🌐 Web 前端 📱 移动 App 🤖 服务端 / AI Agent API 网关 Kong(Lua)· 统一入口,校验 API Key,路由到各服务 · 自托管默认网关 2026-08 起改为 Envoy 🔐 GoTrue 认证 · 签发 JWT · Go 🔌 PostgREST 自动 REST API · Haskell 📡 Realtime WebSocket · Elixir 🗂 Storage API 对象存储 · TS/Node λ Edge Functions Deno · TS/Rust 🔀 Supavisor 连接池(Elixir)· 多租户连接复用 🐘 PostgreSQL(C)—— 唯一的事实源:业务数据 + 用户表 + 文件元数据 + 实时数据源
Supabase 分层架构:无状态服务环绕唯一的 Postgres;另有 Studio 管理台与 postgres-meta(数据库管理 API)未画入(依据官方 Architecture 文档绘制)

🧩 组件清单(面试背诵版)

组件职责实现语言
Postgres核心数据库,用户可完全访问、无抽象层C
PostgREST把 Postgres schema 自动映射成 REST API;配合 pg_graphql 提供 GraphQLHaskell
GoTrue认证服务:管理用户、签发 JWTGo
RealtimeWebSocket 引擎:广播、在线状态、数据库变更推送Elixir(Phoenix)
Storage APIS3 兼容对象存储,元数据存在 PostgresNode / TypeScript
Edge Functions全球分布的服务端函数,Deno 运行时TypeScript / Rust
Supavisor云原生多租户 Postgres 连接池Elixir
KongAPI 网关(基于 NGINX);自托管默认网关 2026 年 8 月起换为 EnvoyLua
Studio / postgres-meta管理仪表板 / 数据库管理 REST APITypeScript / Node
🔗 类比
把 Postgres 想成一家银行的金库,所有真正值钱的东西(状态)都只放在这一处。GoTrue 是发工牌的前台(签发 JWT),PostgREST 是柜台(照章办事,规则写在金库门上),Realtime 是广播喇叭(金库有动静就通知订阅的人),Kong 是大门保安(先验你有没有资格进楼)。柜台、前台、喇叭全都不存钱——所以它们坏了随便换、随便加人手(无状态、可水平扩展),金库只有一个。
类比用于理解「有状态/无状态分离」,细节以官方架构文档为准。
🎯 面试加分句:「Supabase 的架构本质是 database-centric——除 Postgres 和 Storage 的文件本体外,其余服务全是无状态的,状态收敛在数据库里;安全规则(RLS)也定义在数据库层,所以无论请求走 REST、GraphQL 还是直连 SQL,约束都一致。」这句话把架构、安全、扩展性三个话题串起来了。
🔌

自动 API:PostgREST

Instant REST API

「建一张表,立刻得到一套 API」是 Supabase 开发体验的核心魔法,魔法师是 PostgREST。

是什么
PostgREST 是一个独立的开源服务器(Haskell 写的,比 Supabase 出现更早),它读取 Postgres 的 schema(有哪些表、列、视图、函数),自动生成一套 RESTful API。官方文档强调这套 API 是「即时的、自动生成的」——你改了表结构,API 立刻跟着变,还自带文档。
为什么
传统开发里,后端工程师要为每张表手写 CRUD 接口(controller、service、DTO……),既重复又容易和数据库结构脱节。PostgREST 的哲学是:schema 即接口——数据库结构本身已经完整描述了数据能怎么读写,何必再手抄一遍?
例子
你建了 products 表,立刻就有了 GET /rest/v1/products?price=gte.100 这样的查询端点;前端用 supabase-js 写出来就是下面这样。
// 官方标准用法(supabase-js)
import { createClient } from '@supabase/supabase-js'
const supabase = createClient(SUPABASE_URL, PUBLISHABLE_KEY)

// 查询:price >= 100 的商品,按创建时间倒序
const { data, error } = await supabase
  .from('products')
  .select('id, name, price')
  .gte('price', 100)
  .order('created_at', { ascending: false })

// 插入
await supabase.from('products').insert({ name: 'Widget', price: 42 })
⚠️ 随之而来的关键问题(面试必被追问):API 是数据库自动生成的、任何前端都能直接调,那安全怎么办?答案是——安全不做在 API 层,做在数据库层,靠 RLS(第 6 节)。这是 Supabase 和传统「后端代码里写权限」最大的思维差异,先在这里挂个钩子。

补充一点:同一套机制还有 GraphQL 版本——pg_graphql 扩展把 schema 映射成 GraphQL 接口;2026 年 7 月还推出了 @supabase-labs/tanstack-db(alpha),把 TanStack DB 集合通过 PostgREST + Realtime 与数据表同步——如果面试聊到你的 TanStack Start 项目,这是个很新的谈资。

🔐

Auth、JWT 与 API Key 体系

GoTrue & keys

认证回答「你是谁」,API Key 回答「什么应用在访问」——两套体系,面试常让你分清。

🧑‍💻 Supabase Auth 能做什么

认证服务由 GoTrue(Go)承担。官方文档列出的登录方式:邮箱密码、magic link(邮件里点链接免密登录)、一次性密码 OTP、社交登录(Apple、Google、GitHub、Discord、Facebook、LinkedIn、Microsoft Azure 等 18+ 家)、手机短信(Twilio、MessageBird、Vonage)、企业单点登录 SSO,以及任何 OAuth2/OIDC 兼容的身份源。2026 年 6 月起还支持 WebAuthn:Face ID、Touch ID、Windows Hello、硬件安全钥匙,走「无密码、防钓鱼」路线。

用户数据存在 Postgres 的专用 auth schema 里(核心是 auth.users 表),官方文档明确说可以用触发器和外键把它关联到你自己的表——最经典的模式就是「auth.users 插入新行时,触发器自动在 public.profiles 建一条资料」。

🎫 JWT:整个安全模型的通行证

是什么
JWT(JSON Web Token)是一段自包含的签名令牌,格式为 header.payload.signature 三段。用户登录成功后 GoTrue 签发;此后每个请求都带着它。官方文档:「只要用户保持登录,Supabase Auth 就会为会话持续签发新的 JWT」——SDK 在后台自动完成续期,开发者无感。
为什么
JWT 的妙处是自带身份信息且可离线验证:任何服务拿到 token,用密钥验签即可确认真伪,不用每次回查数据库。这让 PostgREST、Realtime、Storage 等一圈无状态服务都能独立完成鉴权。签名算法支持对称的 HS256 和非对称的 RS256 / ES256(非对称意味着第三方服务只需公钥就能验签)。
例子
把你自己项目的 access token 粘到 jwt.io 解开,能看到下面这些 claims——这是面试展示动手经验的好素材。
Claim含义面试要点
sub用户唯一 IDRLS 里 auth.uid() 读的就是它
rolePostgres 数据库角色核心机制:PostgREST 验签后按此 claim 切换数据库角色(anonauthenticated),RLS 策略随之生效
exp / iss过期时间 / 签发方过期后由 SDK 自动换新;具体有效期可在项目中配置(官方文档未给统一默认值,以你项目设置为准)
email / phone联系方式官方说明:这类 claims 用于「免查库快速读取资料」
app_metadata应用元数据,用户不可修改✅ 可用于授权判断(如所属团队)
user_metadata用户元数据,用户可自行修改❌ 绝不可用于授权——经典安全陷阱题

🗝️ API Key:新旧两套体系

API Key 与用户身份无关,它标识「哪个应用在访问这个项目」。目前两套并存(官方文档口径):

体系Key权限用在哪
Legacy(JWT 型)anon低权限,走 RLS前端公开使用
service_role绕过 RLS仅后端;泄露 = 整库裸奔
新体系sb_publishable_...低权限(映射 anon/authenticated 角色)可公开:网页、App、CLI、源码
sb_secret_...高权限(映射 service_role,绕过 RLS)仅后端/Edge Functions;官方要求不进源码仓库、泄露立即删除轮换
📌 官方文档的两个迁移细节,容易踩:新 key 不能放在 Authorization: Bearer 头里用;Edge Functions 若用新 key 调用,需要 --no-verify-jwt 并在函数内自行做鉴权。新旧体系可同时启用,平滑迁移。
🛡️

RLS 行级安全:整个平台的安全地基

Row Level Security ★

如果 Supabase 面试只考一个主题,一定是 RLS。这一节讲透:是什么、四种策略怎么写、性能怎么调、有哪些坑。

📎 需先理解 JWT 的 role 与 sub claim——RLS 策略读的就是它们
是什么
RLS(Row Level Security,行级安全)是 Postgres 的原生安全机制:给表定义「策略」(policy)后,数据库会为每一次访问自动追加一个隐式的 WHERE 条件,不满足条件的行就像不存在一样。官方文档称 policy 为「Postgres 的规则引擎」。
为什么
因为 Supabase 的 API 是数据库自动生成的、前端直连,传统「在后端代码里写权限判断」这条路不存在了,权限必须下沉到数据库本身。好处也正在这里:规则只写一份,任何入口都逃不掉——REST、GraphQL、Realtime、直连 SQL、定时任务,统统走同一套检查。
例子
「用户只能看自己的资料」写成策略,就是给所有对 profiles 的查询自动加上 WHERE auth.uid() = user_id
① 客户端请求 带 API Key + JWT ② 网关 校验 API Key ③ PostgREST 验 JWT 签名 按 role 切数据库角色 ④ Postgres 执行 policy 变成隐式 WHERE 逐行过滤 ⑤ 只返回 有权的行 🔑 关键:JWT 的 role claim 决定连接用哪个 Postgres 角色(anon / authenticated),策略再按 auth.uid() 逐行判断
一条带 JWT 的请求如何被 RLS 过滤(依据官方 RLS 与 JWT 文档整理)

✍️ 四种策略写法(官方示例)

-- 第一步:开启 RLS(暴露在 API 里的表必须开!)
alter table profiles enable row level security;

-- SELECT:能"看"哪些行 → USING 子句
create policy "只能看自己的资料" on profiles
for select using ( (select auth.uid()) = user_id );

-- INSERT:能"写入"什么样的新行 → WITH CHECK 子句
create policy "只能以自己的身份建资料" on profiles
for insert to authenticated
with check ( (select auth.uid()) = user_id );

-- UPDATE:改之前要能"看到"旧行(USING),改出来的新行要合规(WITH CHECK)
create policy "只能改自己的资料" on profiles
for update to authenticated
using  ( (select auth.uid()) = user_id )
with check ( (select auth.uid()) = user_id );

-- DELETE:能"删"哪些行 → USING 子句
create policy "只能删自己的资料" on profiles
for delete to authenticated
using ( (select auth.uid()) = user_id );
💬 USING 和 WITH CHECK 到底怎么区分?点这里换种说法

USING 管「已经存在的行」,WITH CHECK 管「即将写入的行」。把表想成档案室:USING 是「哪些柜子允许你打开看」(SELECT/UPDATE/DELETE 都要先找到行,所以都用它);WITH CHECK 是「你交上来的新档案要盖章合格才收」(INSERT/UPDATE 会产生新行,所以要检查)。UPDATE 两者都要:先能打开旧档案(USING),改完的新档案也要合格(WITH CHECK)。

⚠️ 官方文档明确的三个易错点:
UPDATE 策略需要配套的 SELECT 策略才能生效(更新前得先「看见」那一行);
auth.uid() 对未登录用户返回 null,而 null = user_id 在 SQL 里不为真也不报错——逻辑复杂时建议显式写 auth.uid() is not null and ...;
③ JWT 不是实时刷新的:改了用户的 app_metadata,旧 token 里还是旧值,直到下次刷新——授权数据变更不会立刻生效。

⚡ 性能优化六招(官方基准数据)

RLS 策略会在每一行上求值,写得不好就是性能杀手。官方 RLS 文档给出了六个优化手段和实测提升幅度:

手段做法官方实测提升
加索引给策略里用到的列(如 user_id)建 btree 索引~99.94%
select 包裹函数(select auth.uid()) = user_id 而非裸调用——让优化器只求值一次并缓存~99.93%
security definer 函数复杂判断(如查团队表)封装进提权函数,避免策略里嵌查询~99.99%
减少 JOIN策略里用子查询代替表连接~99.78%
显式指定 TO 角色to authenticated 让匿名请求提前短路~99.78%
查询自带过滤客户端查询也写 .eq('user_id', id),不全靠策略兜底~94.74%

🕳️ 还要知道的三件事

📡

Realtime:三种实时能力

Broadcast · Presence · Postgres Changes

「Realtime 怎么工作、能扛多大规模」是系统设计向面试题的常客,官方数字要背两个。

Realtime 是一台 Elixir/Phoenix 写的 WebSocket 服务器,提供三种能力,按「谁产生消息」区分最清楚:

功能消息来源典型场景
Broadcast客户端 ↔ 客户端(低延迟转发)聊天、光标跟踪、游戏事件;2026-07 起支持二进制载荷(遥测、截图流)
Presence各客户端上报状态,服务端合并同步「谁在线」「谁在编辑」
Postgres Changes数据库本身(监听数据变更)数据面板、列表实时刷新

🔍 Postgres Changes 的工作原理(深挖点)

✏️ 数据写入 INSERT / UPDATE / DELETE 📜 WAL 逻辑复制 supabase_realtime 发布 📡 Realtime 服务(Elixir) 对每个订阅者做 RLS 授权检查 ⚠ 单线程处理以保证顺序 🌐 WebSocket 扇出 推送到订阅客户端 吞吐随「订阅者数量」而非「写入速率」下降:官方基准 Micro 实例 500 连接 ≈ 30 变更/秒;3,000 连接 ≈ 5 变更/秒
Postgres Changes 数据流:WAL → 逻辑复制 → 逐订阅者授权 → WebSocket 推送(依据官方 Postgres Changes 文档绘制)

订阅端写法(官方参数):可按 schema / 表 / 行三级过滤,filter 支持 eq、neq、lt、gt、in、like 等 PostgREST 风格操作符,还能用 select 参数只接收部分列以减小载荷:

supabase.channel('room1')
  .on('postgres_changes',
      { event: 'UPDATE', schema: 'public', table: 'orders',
        filter: 'status=eq.paid' },
      (payload) => console.log(payload))
  .subscribe()
⚠️ 官方文档写明的四条硬限制(面试高频):
单线程处理变更以保序——换更大的计算实例并不能显著提升吞吐;
DELETE 事件不能加 filter;且 RLS 策略不应用于 DELETE(无法对已删的行验证权限),old 记录通常只含主键;
③ 吞吐由订阅者数量决定(见图中基准数字);
④ 官方建议:同一变更预计有 超过约 3,000 个并发订阅者时,改用 Broadcast 转发数据库变更——变更只发一次,由 Broadcast 扇出,可扩展到高得多的连接数。

配额方面(官方定价页):免费档 200 个并发连接、200 万条消息/月;Pro 500 个并发(超额 $10/千连接)、500 万条消息/月。

🗂️

Storage:文件也归数据库管

Object storage

Storage 本身不难,考点在「权限怎么做」——答案还是 RLS。

Storage 是 S3 兼容的对象存储:文件本体存在对象存储里,元数据(路径、大小、所有者)存在 Postgres 的 storage.objects 表里。这个设计的直接后果是:文件权限就是往 storage.objects 上写 RLS 策略——和管表数据完全同一套思路,不用再学一门「安全规则语言」(这正是它与 Firebase Security Rules 的对照点)。

⚙️

Edge Functions:全球分发的服务端函数

Deno at the edge

「自动 API 覆盖不了的服务端逻辑放哪?」——放这里。限制数字要背准,网上旧资料错得很多。

Edge Functions 是跑在 Deno 运行时(TypeScript 优先)上的服务端函数,部署后在离用户最近的边缘节点执行。官方列举的典型场景:Webhook 接收器(Stripe、GitHub)、AI 推理 / LLM 编排、按需生成 OG 图、发事务邮件、聊天机器人。本地用 CLI 开发(supabase functions serve),再部署到全球。

📌 官方限制数字(截至 2026-07 调研,以官方 Limits 页为准):内存上限 256MB;墙钟时长免费档 150 秒、付费档 400 秒;CPU 时间上限 2 秒(不含异步 I/O 等待);函数数量免费 100 / Pro 500 / Team 1000。
⚠️ 注意:中文社区不少文章还在写「最长执行 30 秒」,那是过时信息——面试引用数字时说明「以官方当前文档为准」反而是加分项。

设计约束(官方指引):存在冷启动,函数应短生命周期、幂等;长任务转后台 worker;在函数里连数据库要用连接池或 serverless 驱动(呼应第 10 节);密钥放项目 secrets,以环境变量读取。

🔀

连接与连接池:Supavisor 的两种模式

Connection pooling ★

这是被公开面经点名的考点(session vs transaction mode)。先懂「为什么需要池」,数字就好记了。

为什么需要
Postgres 的每个连接都对应服务器上的一个进程,又重又有限。传统长驻后端开几十个连接没问题;但 serverless / 边缘函数是海量短命实例,每个都要新连接,瞬间就能打爆数据库。连接池的作用:池子对外接受海量客户端连接,对内只维护少量真实数据库连接,复用着用。
是什么
Supabase 自研的池化服务叫 Supavisor(Elixir 写的云原生多租户连接池),另有付费的专属 PgBouncer。
连接方式端口适用场景关键限制
直连 Direct5432长驻后端、迁移、pg_dump走 IPv6(IPv4 需付费附加)
Supavisor Session 模式5432只有 IPv4 网络的长驻后端一客户端独占一真实连接直到断开
Supavisor Transaction 模式6543Serverless / Edge Functions事务结束就归还连接;不支持 prepared statements(需在驱动里关闭)
专属 PgBouncer6543高性能付费场景仅 transaction 模式
💬 session 和 transaction 模式的区别,一句话版本

Session 模式像「包车」:你上车后这辆车整程归你,直到下车(断开连接)——行为和直连几乎一样,但池子帮你管理车队。Transaction 模式像「拼车」:每做完一单事务就下车,车马上接下一位——真实连接利用率极高,所以适合海量短命的 serverless 请求;代价是「车上不能留私人物品」——prepared statements 这类依赖连接状态的特性没法用。

💡 官方文档补充的两个细节:① Supavisor 与 PgBouncer 共享同一个池大小设置;② IPv4 附加是「非双栈」——开了它,项目就只能走 IPv4。选型口诀:长驻后端 → 直连或 session;serverless → transaction(记得关 prepared statements)。
🤖

AI 与 pgvector:顺手的 RAG 后端

Vectors & embeddings

面 AI 相关岗位时,这一节能把 Supabase 和你的主战场接上。

官方 AI 文档的口号概括了一切:「最好的向量数据库,是你已经在用的数据库」。做法:启用 pgvector 扩展,表里加一个向量列存 embedding,相似度搜索就是一条 SQL——业务数据和向量放在同一个库里,不用再为 RAG 单独引一个 Pinecone/Weaviate,也不用跨库同步。

⚖️

对比与选型:vs Firebase

Trade-offs

「你为什么选 Supabase 而不是 X」是判断你有没有工程判断力的题——答案要讲权衡,不是站队。

维度SupabaseFirebase
数据模型PostgreSQL 关系型:完整 SQL、JOIN、CTE、窗口函数、事务Firestore 文档型 NoSQL(另有 Realtime DB JSON 树;新推 Data Connect 接 Cloud SQL Postgres)
安全模型RLS,定义在数据库层,任何入口统一生效Security Rules + IAM,定义在平台层
实时/离线实时强(逻辑复制 + Phoenix);离线支持仍在成熟中离线持久化和自动冲突合并非常成熟,移动端体验最佳
开源/锁定Apache 2.0,可 Docker/K8s 自托管,pg_dump 随时搬家闭源,无自托管路径
定价固定档位(Free / Pro $25 / Team $599)+ 超额计费,可预测按操作量计费,随用量增长,较难预测
AIpgvector 原生向量搜索Firestore 向量搜索 + Firebase AI Logic(Gemini)

对比依据:Bytebase 2026-04 对比文(每年更新)+ 官方文档;「离线成熟度」「定价可预测性」为多家评测的共同结论,属社区共识而非官方口径。

✅ 选 Supabase 当:

· Web / SaaS 应用,关系型数据 + 复杂查询

· 要 AI/RAG 能力(pgvector)

· 在乎开源、可自托管、随时能搬家

· 团队会 SQL,想把权限收敛到数据库层

🤔 Firebase 更合适当:

· 移动优先 + 重度离线同步(笔记、外勤类 App)

· 深度绑定 Google 生态(Analytics、FCM 推送)

· 需要多语言 serverless 运行时(Python/Go/Java)

🎯 面试收尾句(体现趋势观察):「有意思的是两边在收敛——Firebase 推出 Data Connect 接入 Postgres,说明关系型 + BaaS 这个方向被验证了;而 Supabase 也在补离线和移动端短板。选型时我更看团队能力和数据形态,而不是平台信仰。」
🕳️

常见坑与限制

Pitfalls

面试聊「你踩过/知道哪些坑」时,分清「官方明示的限制」和「社区反馈的痛点」会显得非常专业。

📕 官方文档明示的

💬 社区反馈的(标注来源性质)

🎯

高频面试题自测(28 题)

Q&A bank ★

题目综合自 Adaface 题库(2024-09)、techinterview.org 考点清单与官方文档;先自己答,再点开对要点。答案均可回溯到前文章节。

🧱 A · 基础与架构

1. 用一句话向非技术人解释 Supabase;再用一句话向工程师解释。
  • 非技术版:「一个让你不用雇后端团队就能做出完整 App 的工具箱——数据、登录、文件、实时通知都替你管好。」
  • 工程师版:「一个以 Postgres 为核心的开源 BaaS:schema 自动生成 API(PostgREST),JWT 认证(GoTrue),安全下沉到数据库层(RLS),外加 Realtime/Storage/Edge Functions。」
2. 讲讲一条请求从客户端到数据库的完整链路。
  • 客户端带 API key + JWT → Kong 网关验 key、路由 → PostgREST 验 JWT 签名、按 role claim 切换 Postgres 角色 → Postgres 执行 SQL,RLS 策略化为隐式 WHERE → 只返回该用户有权的行。(见第 6 节流程图)
3. 为什么 Supabase 选 Postgres 而不是自研或 NoSQL?这个选择的代价是什么?
  • 官方立场:没有别的数据库能兼顾「对标 Firebase 的功能」和「可扩展性」;且产品原则是扩展现有工具而非重造。
  • 获得:SQL 全能力、RLS、扩展生态(pgvector 等)、可移植性。
  • 代价:离线同步等移动端体验不如 Firestore 原生;水平扩展要靠 Postgres 生态手段(读副本、连接池)而非 NoSQL 式自动分片。
4. Supabase 各组件分别是什么语言写的?为什么面试官爱问这个?
  • Postgres(C)、PostgREST(Haskell)、GoTrue(Go)、Realtime(Elixir/Phoenix)、Storage(TS/Node)、Supavisor(Elixir)、Kong(Lua)、Edge Runtime(Deno,TS/Rust)。
  • 考察点:你是否理解「它是一组独立开源服务的组合」而非单体——每个组件可独立使用和替换。
5. 自托管 Supabase 和用官方云,怎么权衡?
  • 官方云:免运维、带 Supavisor/CDN/备份等托管能力,按档位付费。
  • 自托管:数据主权、成本可控、可进内网;代价是要运维十余个服务,默认单节点无 HA,高可用要自建(社区反馈)。另注意 2026-08 起自托管默认网关从 Kong 换 Envoy。

🛡️ B · RLS(必考区)

6. 什么是 RLS?为什么 Supabase 的安全模型必须建立在它上面?
  • Postgres 原生机制:policy 为每次表访问追加隐式 WHERE。
  • 因为 API 是自动生成、前端直连的,没有「后端代码」这一层可以写权限——安全必须收敛到数据库层,且好处是所有入口(REST/Realtime/SQL)统一受控。
7. USING 和 WITH CHECK 的区别?UPDATE 为什么两个都要?
  • USING 过滤「已存在的行」(SELECT/UPDATE/DELETE 的可见性);WITH CHECK 校验「写入的新行」(INSERT/UPDATE 的合法性)。
  • UPDATE 先要看到旧行(USING),改出的新行也要合规(WITH CHECK);且官方明确 UPDATE 需要配套 SELECT 策略。
8. RLS 导致查询变慢,你会怎么排查和优化?
  • 官方六招:策略列加索引;(select auth.uid()) 包裹让其只求值一次;复杂逻辑封装 security definer 函数;策略内避免 JOIN 改子查询;to authenticated 提前短路;客户端查询自带过滤条件。配合 EXPLAIN ANALYZE 验证。
9. auth.uid() 有什么著名陷阱?
  • 未登录时返回 null,null = user_id 静默为「不为真」——策略看似安全实则行为隐晦;复杂逻辑建议显式 auth.uid() is not null and ...
  • 另一个关联陷阱:JWT 里的 metadata 不实时刷新,授权变更旧 token 感知不到。
10. 什么时候需要绕过 RLS?怎么绕才安全?
  • 可信服务端场景:后台任务、管理面板、数据修复。
  • 途径:service_role / secret key,或 bypassrls 角色属性;只存在于服务端环境变量,绝不进前端与源码仓库,泄露立即轮换。
11. 设计一个多租户 SaaS 的 RLS 方案。
  • 每表带 org_id;成员关系放 org_members 表或用户的 app_metadata(不可被用户篡改)。
  • 策略:org_id in (select org_id from org_members where user_id = (select auth.uid())),或封装成 security definer 函数提高性能与复用。
  • 加分:提 app_metadata 方案要处理「JWT 不实时刷新」——踢出成员后旧 token 仍带旧团队列表,可用短 token 有效期缓解。

🔐 C · Auth 与 Key

12. 描述 Supabase Auth 的 JWT 流程。
  • 登录 → GoTrue 验证凭据 → 签发 JWT(含 sub/role/exp/metadata)→ 客户端每请求携带 → 各服务独立验签 → PostgREST 按 role 切数据库角色。
  • 会话期间 SDK 自动续期(官方:「只要保持登录就持续签发新 JWT」)。
13. JWT 的 role claim 如何连接到数据库权限?
  • 这是「两套体系的接头处」:验签通过后,PostgREST 以 role claim 对应的 Postgres 角色(anon/authenticated)执行 SQL,RLS 策略再用 TO 子句和 auth.uid() 精确到行。
14. anon/service_role 与新的 publishable/secret key 是什么关系?
  • 职责相同(标识应用、区分公开/特权),实现升级:legacy 是 JWT 型 key,新体系是 sb_publishable_/sb_secret_ 不透明字符串,支持独立轮换。
  • 细节:新 key 不能放 Authorization: Bearer 头;Edge Functions 用新 key 需 --no-verify-jwt 并自行鉴权;两套可并存平滑迁移。
15. user_metadata 和 app_metadata 有什么区别?哪个能进授权逻辑?
  • user_metadata 用户可自改 → 只能放展示性资料;app_metadata 仅服务端可改 → 可用于授权(团队、角色、订阅等级)。官方 RLS 文档明确此边界。
16. Supabase 支持哪些登录方式?给产品选型时你怎么推荐?
  • 密码、magic link、OTP、18+ 家 OAuth、手机短信、SSO、匿名登录、WebAuthn 生物识别(2026-06 起)。
  • 推荐思路:消费级产品 OAuth + magic link 降摩擦;企业产品 SSO;高安全场景叠加 WebAuthn/MFA。任何 OIDC 兼容源都能接。

📡 D · Realtime

17. Realtime 的三种能力分别解决什么问题?
  • Broadcast:客户端间低延迟消息(聊天、光标);Presence:共享在线状态;Postgres Changes:数据库变更推送(数据面板)。按「消息由谁产生」区分记忆。
18. Postgres Changes 底层怎么实现的?
  • 基于 Postgres 逻辑复制:表加入 supabase_realtime publication → Realtime 服务读 WAL 变更流 → 对每个订阅者做 RLS 授权检查 → WebSocket 推送。支持 schema/表/行(filter)三级订阅粒度。
19. Postgres Changes 有哪些硬限制?
  • 单线程保序,加大实例无助于吞吐;DELETE 事件不能 filter,且 RLS 不应用于 DELETE(old 记录通常只有主键);吞吐随订阅者数量下降(官方基准:Micro 实例 500 连接 ≈30 变更/秒,3000 连接 ≈5/秒)。
20. 【系统设计】一万人实时看同一份数据的变更,怎么设计?
  • 不能直接 Postgres Changes(超官方 ~3,000 并发订阅建议线)。
  • 官方推荐架构:数据库变更(触发器或服务端)发到 Broadcast → 变更只处理一次,由 Broadcast 扇出到全部连接;需要初始状态就先拉快照再订阅增量。
  • 加分:提消息裁剪(select 指定列)、2026-07 起 Broadcast 支持二进制载荷。

🔀 E · 连接与性能

21. 为什么 serverless 环境连 Postgres 是个问题?Supabase 怎么解?
  • Postgres 连接 = 进程,昂贵有限;serverless 实例海量短命,直连会耗尽连接。
  • 解法:Supavisor transaction 模式(6543)——事务级复用真实连接;或 Edge Functions 里用 serverless 驱动。
22. Supavisor 的 session 模式和 transaction 模式怎么选?
  • Session:客户端独占连接到断开,行为等同直连,适合 IPv4 网络的长驻后端。
  • Transaction:事务结束即归还,高复用,适合 serverless;代价是不支持 prepared statements 等连接级状态(驱动需关闭)。
23. 「数据库连接数打满了」你会怎么排查?
  • 先分来源:长驻后端还是 serverless 突发?→ 前者查连接泄漏/池配置,后者切 transaction 模式。
  • 注意官方细节:Supavisor 与 PgBouncer 共享池大小设置;必要时升配或加只读副本分流。
24. 一条查询突然变慢,你的排查顺序?
  • EXPLAIN ANALYZE 看计划 → 缺索引?→ RLS 策略是否逐行执行昂贵函数(用 select 包裹、security definer 优化)→ 数据量变化/统计信息过期 → 连接模式是否合适。体现「先测量再动手」。

🧰 F · 其他服务与场景判断

25. Edge Functions 适合与不适合什么?数字说话。
  • 适合:webhook、AI 编排、OG 图、邮件等短平快胶水逻辑(全球边缘低延迟)。
  • 不适合:重计算与长任务——CPU 上限 2 秒、内存 256MB、墙钟 150s(免费)/400s(付费);长活转后台 worker。
26. Storage 的权限控制怎么做?
  • 文件元数据在 storage.objects 表,权限就是对它写 RLS policy——与表数据同一套模型,无需单独的规则语言。可按 bucket、路径前缀、所有者字段控制。
27. 用 Supabase 搭一个 RAG 后端,你的方案?
  • pgvector 存 embedding(与业务数据同库);Edge Function 里调 embedding 模型;检索用混合搜索(语义+关键词);权限天然由 RLS 管——多租户知识库每租户只搜自己的向量。
  • 可引用官方案例:Firecrawl 从 Pinecone 迁到 pgvector。
28. 什么场景你会劝人不要用 Supabase?(反向题,最见功力)
  • 重离线的移动优先产品(Firebase 离线同步更成熟);主要用户在中国大陆(无节点,网络不可控);已有成熟微服务体系、只缺个数据库的团队(直接用云 Postgres 更简单);对单组件有极端要求(如百万级实时扇出,需专门方案)。
  • 答题姿态:诚实讲边界比无脑吹更能赢得信任。
📅

一周学习路径

7-day plan

你不是零基础——自己的网站就跑在 Supabase 上(建过表、写过 RLS、用过 REST PATCH)。所以这份计划的重心不是「学会用」,而是「讲得出原理」:每天 2–3 小时,动手 + 口述并重。

D1 全景架构 D2 PostgREST+SQL D3 ★ RLS 专项 D4 Auth+JWT D5 Realtime 三件套 D6 连接池+系统设计 D7 ★ 全量自测+Mock
一周路径:D3(RLS)和 D7(自测)是两个重心日
  1. Day 1 · 全景与架构读本文 §1–3 + 官方 Architecture 文档。动手:白纸默画架构图(网关→五服务→Postgres,标语言),对照本文检查。口述练习:3 分钟讲「Supabase 是什么、架构长什么样」,录音回听。
  2. Day 2 · PostgREST 与 SQL 补强读官方 REST API 文档。动手:用 curl 直接调你自己网站项目的 REST 端点(带 apikey header),观察响应;对 resources 表跑一次 EXPLAIN ANALYZE,看懂执行计划。自问:「schema 即接口」的安全前提是什么?
  3. Day 3 · RLS 专项(重心日)精读本文 §6 + 官方 RLS 文档。动手:在自己项目找一张表(比如你做过的 reading_status)把四种 policy 写全;用 Dashboard 的 RLS Tester 扮演另一个用户验证;给策略列加索引前后各测一次耗时。口述:USING vs WITH CHECK、六个优化招。
  4. Day 4 · Auth 与 JWT读本文 §5 + 官方 JWT 文档。动手:把自己项目的 access token 粘进 jwt.io,逐个 claim 对照含义;找到项目里 anon/service key 的使用处,想清楚每处为什么用那把 key。自问:app_metadata 为什么能进授权而 user_metadata 不能?
  5. Day 5 · Realtime + Storage + Edge Functions读本文 §7–9。动手:本地写 20 行代码订阅一张表的 postgres_changes 并触发一次 UPDATE 看 payload;部署一个 hello-world Edge Function。背数字:单线程/3000 订阅线/2 秒 CPU/256MB。
  6. Day 6 · 连接池 + pgvector + 系统设计读本文 §10–11。动手:找到自己项目连接串用的端口,判断走的哪种模式。口述:完整答一遍第 20 题(万人订阅设计)和第 28 题(何时不用 Supabase),计时 5 分钟。
  7. Day 7 · 全量自测 + 项目故事(重心日)§14 的 28 题全部盲答,答不出的回读对应章节。压轴任务:把你自己的网站整理成 2 分钟项目故事——「TanStack Start + Supabase 全栈站:RLS 保护的私有阅读状态表、REST PATCH 做内容运维、静态资源同步管线」——真实项目经验是面试里最硬的通货。
💡 学习方法提醒:每天的「口述练习」不是可选项。面试考的是「讲出来」的能力,读懂和讲清之间隔着一次真实输出——录音回听是发现卡壳点最快的办法。
📚

学习资源清单

Keep learning

按学习顺序排列,全部为调研中实际核对过的来源。

🎓 收尾:面试前的最后三句话

① Supabase 的一切从「database-centric」出发——架构、安全、实时,答什么题都可以往这个锚点收。

② 数字要新:Edge Functions 150/400 秒、CPU 2 秒、Realtime 3000 订阅线、RLS 优化六招——引用时加一句「以官方当前文档为准」。

③ 你有真实生产项目在 Supabase 上跑,这比任何背题都值钱——把它讲成故事。