Neon 是一个现代化的 Serverless PostgreSQL 数据库服务,提供自动扩缩容、按需计费和分支管理等特性。它将传统 Postgres 的强大功能与云原生架构结合,让开发者能够像使用无服务器函数一样使用数据库。本文将介绍 Neon 的核心概念、使用方法和实际应用场景。
核心特性
Serverless 架构
Neon 采用 Serverless 设计,数据库实例可以在无请求时自动暂停,有请求时快速恢复。这种设计大幅降低了空闲时的成本,开发者只需为实际使用的计算资源付费。
自动扩缩容
Neon 支持根据负载自动调整计算资源。在流量高峰时自动扩容,流量降低时自动缩容,无需手动干预。
分支管理
Neon 支持为数据库创建分支(Branch),类似 Git 分支管理代码。每个分支都是独立的数据库实例,可以用于开发、测试或预览环境。
快速开始
本章介绍如何快速上手 Neon,从注册账号到执行第一个查询。
创建项目
- 访问 Neon Console 并注册账号(支持 GitHub、Google 登录)
- 点击 "Create a project" 创建新项目
- 选择区域(Region)和 PostgreSQL 版本
- 系统会自动创建一个默认数据库
main
获取连接字符串
创建项目后,在项目面板中可以看到连接字符串:
# 连接字符串格式
postgresql://username:password@ep-xxx.region.aws.neon.tech/dbname?sslmode=require
连接字符串包含以下信息:
- username:数据库用户名
- password:自动生成的密码
- ep-xxx:Endpoint ID(计算实例标识)
- region:数据中心区域
- dbname:数据库名称
连接数据库
使用 Node.js
import { Pool } from "@neondatabase/serverless";
const pool = new Pool({
connectionString: process.env.DATABASE_URL,
});
async function main() {
const client = await pool.connect();
try {
// 创建表
await client.query(`
CREATE TABLE IF NOT EXISTS users (
id SERIAL PRIMARY KEY,
name VARCHAR(100),
email VARCHAR(100) UNIQUE,
created_at TIMESTAMP DEFAULT NOW()
)
`);
// 插入数据
await client.query("INSERT INTO users (name, email) VALUES ($1, $2)", ["Alice", "alice@example.com"]);
// 查询数据
const result = await client.query("SELECT * FROM users");
console.log(result.rows);
} finally {
client.release();
}
}
main();
使用 psql 命令行
# 使用 psql 连接
psql "postgresql://username:password@ep-xxx.region.aws.neon.tech/main?sslmode=require"
# 执行查询
main=> SELECT version();
main=> \dt -- 列出所有表
使用其他客户端
Neon 完全兼容 PostgreSQL,可以使用任何支持 PostgreSQL 的客户端工具:
- GUI 工具:pgAdmin, DBeaver, TablePlus
- ORM:Prisma, TypeORM, Sequelize, Drizzle
- 语言驱动:
pg(Node.js),psycopg2(Python),pgx(Go)
使用 API Client
@neondatabase/api-client 是 Neon 官方提供的 TypeScript/JavaScript SDK,用于通过代码管理 Neon 项目、数据库、分支等资源。
安装和配置
安装依赖
npm install @neondatabase/api-client
# 或
pnpm add @neondatabase/api-client
获取 API Key
- 登录 Neon Console
- 进入 "Account settings" → "API keys"
- 点击 "Generate new API key" 创建密钥
- 保存密钥到环境变量
# .env
NEON_API_KEY=your_api_key_here
初始化客户端
import { createClient } from "@neondatabase/api-client";
const client = createClient({
apiKey: process.env.NEON_API_KEY,
});
常用操作
列出所有项目
async function listProjects() {
const response = await client.listProjects();
response.projects.forEach((project) => {
console.log(`ID: ${project.id}`);
console.log(`Name: ${project.name}`);
console.log(`Region: ${project.region_id}`);
});
}
创建新项目
async function createProject() {
const project = await client.createProject({
project: {
name: "my-new-project",
region_id: "aws-us-east-2", // 选择区域
pg_version: 16, // PostgreSQL 版本
},
});
console.log("Project created:", project.id);
console.log("Connection string:", project.connection_uris[0].connection_uri);
}
管理分支
async function manageBranches(projectId: string) {
// 列出所有分支
const branches = await client.listProjectBranches({ projectId });
// 创建新分支
const newBranch = await client.createProjectBranch({
projectId,
branch: {
name: "feature-branch",
parent_id: branches.branches[0].id, // 从主分支创建
},
});
console.log("Branch created:", newBranch.branch.id);
// 删除分支
await client.deleteProjectBranch({
projectId,
branchId: newBranch.branch.id,
});
}
获取项目详情
async function getProjectInfo(projectId: string) {
const project = await client.getProject({ projectId });
console.log("Project info:", {
name: project.project.name,
region: project.project.region_id,
createdAt: project.project.created_at,
settings: project.project.settings,
});
}
管理 Endpoints
Endpoint 是 Neon 中的计算实例,每个分支可以有多个 Endpoint。
async function manageEndpoints(projectId: string, branchId: string) {
// 列出分支的所有 Endpoints
const endpoints = await client.listProjectBranchEndpoints({
projectId,
branchId,
});
// 更新 Endpoint 配置
await client.updateProjectEndpoint({
projectId,
endpointId: endpoints.endpoints[0].id,
endpoint: {
autoscaling_limit_min_cu: 0.25,
autoscaling_limit_max_cu: 2,
suspend_timeout_seconds: 300,
},
});
}
实际应用场景
Neon 的 Serverless 特性和分支管理功能,使其在多种场景下都能发挥独特优势。
开发环境:独立数据库分支
传统开发中,多个开发者共享同一个开发数据库容易产生冲突。使用 Neon,可以为每个开发者创建独立的数据库分支。
// 脚本:为开发者创建个人分支
import { createClient } from "@neondatabase/api-client";
async function setupDeveloperBranch(developerName: string) {
const client = createClient({
apiKey: process.env.NEON_API_KEY!,
});
// 从主分支创建开发者分支
const branch = await client.createProjectBranch({
projectId: process.env.NEON_PROJECT_ID!,
branch: {
name: `dev-${developerName}`,
parent_id: mainBranchId,
},
});
console.log(`Branch for ${developerName}:`, branch.endpoints[0].host);
return branch;
}
// 开发者 Alice 获得独立分支
await setupDeveloperBranch("alice");
优势
- 每个开发者有独立的数据库环境,互不干扰
- 可以自由修改 schema 和数据,不影响他人
- 创建和删除分支成本极低
生产环境:弹性应对流量波动
对于流量有明显峰谷的应用,Neon 的自动扩缩容可以显著降低成本。
// 配置生产环境的自动扩缩容
async function configureProduction() {
const client = createClient({ apiKey: process.env.NEON_API_KEY! });
await client.updateProjectEndpoint({
projectId: process.env.NEON_PROJECT_ID!,
endpointId: productionEndpointId,
endpoint: {
// 低流量时使用 0.5 CU
autoscaling_limit_min_cu: 0.5,
// 高峰时最多扩展到 4 CU
autoscaling_limit_max_cu: 4,
// 30 分钟无活动后暂停(适用于非 24/7 应用)
suspend_timeout_seconds: 1800,
},
});
}
适用场景
- 内部工具:工作时间访问频繁,下班后自动暂停
- 营销活动:活动期间流量激增,自动扩容应对
- 定时任务:只在特定时间运行,其他时间暂停节省成本
测试环境:快速复制生产数据
使用时间点恢复功能,快速复制生产数据到测试环境进行调试和验证。
# 从生产分支的最新状态创建测试分支
neonctl branches create \
--project-id my-project \
--parent production \
--name test-reproduce-bug
# 从昨天的数据创建分支,用于复现历史问题
neonctl branches create \
--project-id my-project \
--parent production \
--timestamp "2024-12-07T10:00:00Z" \
--name test-yesterday-data
使用场景
- Bug 复现:使用生产数据在测试环境中复现问题
- 性能测试:使用真实数据规模测试查询性能
- 数据迁移:在测试分支上验证迁移脚本,确认无误后应用到生产
多区域部署
Neon 支持在多个云区域创建项目,实现地理分布式部署。
// 为不同地区的用户创建区域化数据库
async function createRegionalProjects() {
const client = createClient({ apiKey: process.env.NEON_API_KEY! });
const regions = [
{ name: "us-east", region_id: "aws-us-east-2" },
{ name: "eu-west", region_id: "aws-eu-west-1" },
{ name: "ap-south", region_id: "aws-ap-southeast-1" },
];
for (const region of regions) {
await client.createProject({
project: {
name: `myapp-${region.name}`,
region_id: region.region_id,
pg_version: 16,
},
});
}
}
优势
- 降低延迟,用户连接到最近的数据中心
- 满足数据合规要求(如 GDPR 要求数据存储在欧盟)
- 提高可用性,某个区域故障时可切换到其他区域