Self-hosted PostgreSQL vs Supabase 对比

在你自己的服务器上运行、自 1986 年起不断成熟的开源关系型数据库

VS
Supabase

构建在真正的 PostgreSQL 之上的托管式开源后端平台

17 分钟阅读数据库

快速结论

这个决定没有唯一正确答案。如果你是小团队且优先考虑速度,那么 Supabase 就是正确选择:auth、storage、realtime 和连接池都已就绪。若负载可预测、有数据落地要求(17 个区域中没有土耳其),或成本随用户数增长,则自建 PostgreSQL 更胜一筹。一个警示:官方文档写明,自托管时托管式备份/PITR 会被禁用——掌控权到手的同时也接手了恢复演练。备份本身不是判断标准;能否恢复才是。

Self-hosted PostgreSQLSupabase
阅读完整结论

评分对比

图表加载中…

详细评分

详细评分: Self-hosted PostgreSQL Supabase ——按类别打分,满分 10 分
分类Self-hosted PostgreSQLSupabase
性能
8/10
8/10
学习难易度
5/10
8/10
生态系统
9/10
8/10
社区
9/10
9/10
就业市场
8/10
7/10
面向未来
8/10
8/10

优缺点

Self-hosted PostgreSQL

优点

  • 软件完全免费(PostgreSQL License)——成本固定在你的基础设施上
  • 完全的扩展自由:pgvector、PostGIS、pg_cron,你想装什么就装什么
  • 数据物理上留在你选择的服务器上——数据落地完全由你掌控
  • PITR 是核心功能(WAL 归档 + pg_basebackup)
  • 没有厂商锁定——你本就运行在自己的基础设施上
  • 每个主版本获得 5 年官方支持,补丁节奏可预测
  • RLS 自 9.5 版本起就是核心功能,你可以随意使用

缺点

  • Auth、Storage、Realtime 不在核心功能内——需要单独搭建和运维
  • 连接池需要 PgBouncer/Supavisor 等单独的工具
  • 备份/PITR/高可用/监控完全是你的责任,没有官方 SLA
  • 学习曲线更陡峭:手动搭建 auth+连接池+高可用需要时间
  • 没有发布官方客户案例/基准测试页面(社区项目)

最适合

需要固定且可预测预算的中大型项目合同中明确要求 KVKK/数据落地条款的系统需要 pgvector/PostGIS 等特定扩展组合的工作具备 DevOps 能力、会把恢复演练排入日程的团队厂商独立性至关重要的长期项目

Supabase

优点

  • Auth、Storage、Realtime、Data API 开箱即用——你不必从零编写 auth 层
  • Free 套餐 $0/月起(500MB 数据库、5GB 出站流量、5 万 MAU)
  • 提供 Dedicated/Shared 连接池选项,连接池开箱即用(Supavisor)
  • 自带 HIPAA(BAA)、ISO 27001、GDPR DPA 等合规认证
  • 通过 Health Check Advisors 自动监控服务错误率(2026 年 9 月)
  • 通过 Grafana Cloud 一键集成实现可观测性(2026 年 7 月)
  • 底层运行真正的 PostgreSQL,可通过 pg_dump 迁移,厂商锁定程度低

缺点

  • 成本随用户/数据增长而阶梯式上升($0.125/GB 磁盘、$0.09/GB 出站流量、$0.00325/MAU)
  • 17 个区域中没有土耳其——从 KVKK 角度会产生跨境传输问题
  • Free 套餐没有自动备份,Pro 套餐也仅保留 7 天
  • 扩展仅限于平台精选目录,没有完全的操作系统级自由度
  • 自托管选项为“社区支持”——没有官方 SLA,托管式备份/PITR 会被禁用

最适合

单人或小团队快速实现从 0 到 1不想从零搭建 Auth/Storage/Realtime 的产品团队需要 HIPAA/ISO 27001/GDPR 等现成认证的项目希望获得托管式监控和自动错误率告警的团队希望借助 pg_dump 保留厂商独立性、同时快速起步的团队

代码对比

Self-hosted PostgreSQL
# Self-hosted PostgreSQL - WAL 归档 + PITR 配置(postgresql.conf)
wal_level = replica
archive_mode = on
archive_command = 'test ! -f /var/backups/pg_wal_archive/%f && cp %p /var/backups/pg_wal_archive/%f'
max_wal_senders = 3

# 创建基础备份(pg_basebackup)
pg_basebackup -D /var/backups/base -Ft -z -P -U replicator -h localhost

# PITR:恢复到指定时间点(recovery.signal + postgresql.conf)
# 1) 将基础备份解压到恢复目录
# 2) 在 postgresql.conf 中添加以下几行,并创建 recovery.signal 文件
restore_command = 'cp /var/backups/pg_wal_archive/%f %p'
recovery_target_time = '2026-09-23 09:00:00+03'

# pg_hba.conf - 仅允许应用服务器连接
host    appdb    app_user    10.0.0.5/32    scram-sha-256

-- SQL (psql):安装扩展(完全自由 —— 自托管特有)
CREATE EXTENSION IF NOT EXISTS vector;
CREATE EXTENSION IF NOT EXISTS postgis;
CREATE EXTENSION IF NOT EXISTS pg_cron;

# 连接池(PgBouncer, pgbouncer.ini)
[databases]
appdb = host=127.0.0.1 port=5432 dbname=appdb
[pgbouncer]
pool_mode = transaction
max_client_conn = 500
default_pool_size = 25
Supabase
-- SQL (Supabase SQL Editor): 1) 创建表并开启 RLS(Data API 强制要求)
create table public.notes (
  id uuid default gen_random_uuid() primary key,
  user_id uuid references auth.users not null,
  content text not null,
  created_at timestamptz default now()
);
alter table public.notes enable row level security;

create policy "kullanicilar kendi notlarini okur"
  on public.notes for select
  using (auth.uid() = user_id);

create policy "kullanicilar kendi notlarini yazar"
  on public.notes for insert
  with check (auth.uid() = user_id);

// 2) 使用 supabase-js 查询(RLS 自动生效)
import { createClient } from '@supabase/supabase-js'

const supabase = createClient(
  process.env.SUPABASE_URL!,
  process.env.SUPABASE_ANON_KEY!
)

const { data: notes, error } = await supabase
  .from('notes')
  .select('id, content, created_at')
  .order('created_at', { ascending: false })

// 3) Postgres 客户端连接字符串(参见官方 "Endpoints and IP versions" 表)
// Direct connection(长驻后端、pg_dump、迁移场景):
// postgresql://postgres:[YOUR-PASSWORD]@db.[PROJECT-REF].supabase.co:5432/postgres
// Dedicated pooler(仅 transaction 模式,付费套餐可用):
// postgresql://postgres:[YOUR-PASSWORD]@db.[PROJECT-REF].supabase.co:6543/postgres
// 手动拼接连接串:从 Dashboard > Connect 页面复制(shared pooler 的 host 无法从区域直接推导)。

结论

这个决定没有唯一正确答案。如果你是小团队且优先考虑速度,那么 Supabase 就是正确选择:auth、storage、realtime 和连接池都已就绪。若负载可预测、有数据落地要求(17 个区域中没有土耳其),或成本随用户数增长,则自建 PostgreSQL 更胜一筹。一个警示:官方文档写明,自托管时托管式备份/PITR 会被禁用——掌控权到手的同时也接手了恢复演练。备份本身不是判断标准;能否恢复才是。

获取免费咨询
常见问题

常见问题

由于 Supabase 使用标准 PostgreSQL,你可以通过 `pg_dump`/`pg_dumpall` 或原生 Postgres 复制导出数据;官方文档以一个 Node.js 脚本示例说明了项目间迁移(含 auth/storage)。而在自托管端重建 Auth、Storage、Realtime 等 Supabase 专属服务(通过 Docker Compose 运行官方自托管技术栈)是另一项工作——迁移数据与搭建对等服务是两个不同的步骤。

相关博客文章

查看全部文章
全部对比