Supabase 连接模式说明
修正记录:20251210
修正描述:supabase无疑是ai时代最火的db服务提供商,连同postgre都走向巅峰,这里简单阐述supabase的三种连接模式和适用场景,方便读者了解避免使用错误!
关键词:supabase,连接模式
1 三种连接模式对比
1.1 Direct Connection(直接连接)
适用场景:
- ✅ 持久化、长连接的应用
- ✅ 运行在虚拟机(VM)上的应用
- ✅ 长期运行的容器(Docker containers)
- ✅ 传统服务器应用
特点:
- 🔗 持久连接:每个客户端保持一个长期数据库连接
- ⚡ 低延迟:直接连接,无中间层
- 📊 支持所有 PostgreSQL 功能:包括事务、会话变量等
- 💰 连接数限制:每个连接占用一个数据库连接槽位
连接字符串格式:
postgresql://postgres:[password]@[host]:5432/postgres
示例代码:
// 适合传统服务器应用
const { createClient } = require('@supabase/supabase-js');
const supabase = createClient(url, key);
// 连接会保持打开,直到应用关闭
1.2 Transaction Pooler(事务池化器)⭐ 推荐用于 Serverless
适用场景:
- ✅ Serverless Functions(Vercel、AWS Lambda、Cloudflare Workers)
- ✅ 无状态应用
- ✅ 每次数据库交互都是短暂且独立的
- ✅ 需要快速启动和关闭连接
特点:
- 🔄 连接复用:多个请求共享连接池
- ⚡ 快速启动:不需要建立新连接
- 🎯 事务级别隔离:每个事务独立,不共享会话状态
- 📈 高并发:支持大量并发请求
- ⚠️ 限制:不支持会话级别的功能(如
SET命令、临时表等)
连接字符串格式:
postgresql://postgres:[password]@[host]:6543/postgres?pgbouncer=true
注意端口是 6543(不是 5432)
示例代码:
// 适合 Serverless Functions
import { createClient } from '@supabase/supabase-js';
export default async function handler(req, res) {
// 每次请求创建新客户端,但使用连接池
const supabase = createClient(url, key);
// 执行查询
const { data } = await supabase.from('posts').select('*');
// 函数结束后,连接自动返回到池中
return res.json(data);
}
1.3 Session Pooler(会话池化器)
适用场景:
- ✅ 作为 Direct Connection 的替代方案
- ✅ 需要通过 IPv4 网络连接
- ✅ 需要会话级别的功能(如
SET命令) - ⚠️ 不推荐:除非有特殊需求
特点:
- 🔗 会话级别连接:每个客户端会话保持连接
- 📊 支持会话变量:可以使用
SET命令、临时表等 - 🌐 IPv4 支持:适合需要 IPv4 的场景
- ⚠️ 性能较低:相比 Transaction Pooler,连接复用效率较低
连接字符串格式:
postgresql://postgres:[password]@[host]:6543/postgres?pgbouncer=true&pool_mode=session
2 详细对比表
| 特性 | Direct Connection | Transaction Pooler | Session Pooler |
|---|---|---|---|
| 连接方式 | 持久连接 | 连接池(事务级) | 连接池(会话级) |
| 端口 | 5432 | 6543 | 6543 |
| 适用场景 | 传统服务器 | Serverless Functions | IPv4 网络 |
| 连接复用 | ❌ 否 | ✅ 是 | ✅ 是 |
| 会话变量 | ✅ 支持 | ❌ 不支持 | ✅ 支持 |
| 临时表 | ✅ 支持 | ❌ 不支持 | ✅ 支持 |
| 事务支持 | ✅ 完整 | ✅ 完整 | ✅ 完整 |
| 并发性能 | 中等 | ⭐ 最高 | 中等 |
| 启动速度 | 慢 | ⭐ 快 | 中等 |
3 针对你的项目说明(Vercel Serverless Functions)
3.1 ✅ 推荐使用:Transaction Pooler
原因:
- Serverless 特性:Vercel Functions 是无状态的,每次请求都是独立的
- 快速启动:不需要等待建立新连接
- 高并发:支持大量并发请求
- 成本效益:连接复用,减少数据库连接数
3.2 配置方式
3.2.1. 在 Supabase Dashboard 获取连接字符串
- 进入 Supabase Dashboard
- 选择 Settings → Database
- 找到 Connection string 部分
- 选择 Transaction pooler 模式
- 复制连接字符串(端口是 6543)
3.2.2. 在代码中使用
// api/data/[resource].ts
import { createClient } from '@supabase/supabase-js';
// 使用 Transaction Pooler 连接字符串
const supabaseUrl = process.env.SUPABASE_URL!;
const supabaseServiceKey = process.env.SUPABASE_SERVICE_ROLE_KEY!;
// 注意:如果使用连接池,需要确保 URL 包含正确的端口
// Transaction Pooler 使用端口 6543
const supabase = createClient(supabaseUrl, supabaseServiceKey, {
db: {
schema: 'public',
},
// 连接会自动使用池化(如果 URL 配置正确)
});
3.2.3 环境变量配置
# 使用 Transaction Pooler
SUPABASE_URL=https://your-project.supabase.co
# 或者直接使用连接池 URL(如果 Supabase 提供)
# SUPABASE_URL=postgresql://postgres:[password]@db.xxx.supabase.co:6543/postgres?pgbouncer=true
SUPABASE_SERVICE_ROLE_KEY=your_service_role_key
4 注意事项
4.1 Transaction Pooler 的限制
不支持会话变量
-- ❌ 不支持 SET local myvar = 'value';不支持临时表
-- ❌ 不支持 CREATE TEMP TABLE temp_data (...);每个事务独立
- 不能跨请求共享会话状态
- 每个请求都是新的事务
4.2 如果遇到问题
如果使用 Transaction Pooler 时遇到:
SET命令错误- 临时表错误
- 会话变量问题
解决方案:
- 检查是否真的需要这些功能
- 如果不需要,继续使用 Transaction Pooler
- 如果需要,考虑使用 Session Pooler(但性能会降低)
5 总结
对于 Vercel Serverless Functions + Supabase 架构:
✅ 推荐:Transaction Pooler
- 最适合 Serverless 场景
- 高性能、高并发
- 自动连接复用
❌ 不推荐:Direct Connection
- 不适合 Serverless(连接无法持久)
- 每次请求都要建立新连接,性能差
⚠️ 谨慎使用:Session Pooler
- 只在需要会话功能时使用
- 性能不如 Transaction Pooler
6 检查当前配置
在 Supabase Dashboard 中:
- Settings → Database
- 查看 Connection string 部分
- 确认选择了 Transaction pooler
- 复制连接字符串(注意端口是 6543)