NeonPostgreSQL无服务器数据库技能Skill neon-postgres

Neon PostgreSQL 无服务器数据库技能指南,提供基于云原生架构的PostgreSQL数据库服务,支持自动扩缩、分支管理、连接池优化,专为现代无服务器应用和边缘计算场景设计。关键词:Neon PostgreSQL,无服务器数据库,Serverless,数据库分支,连接池,自动扩缩,云原生,边缘计算,PostgreSQL托管,Drizzle ORM集成。

Serverless 0 次安装 0 次浏览 更新于 3/2/2026

name: neon-postgres description: Neon PostgreSQL 无服务器数据库 - 连接池、分支、无服务器驱动程序和优化。适用于部署到 Neon 或构建无服务器应用程序。

Neon PostgreSQL 技能

具有分支、自动扩缩和即时配置功能的无服务器 PostgreSQL。

快速开始

创建数据库

  1. 访问 console.neon.tech
  2. 创建一个新项目
  3. 复制连接字符串

安装

# npm
npm install @neondatabase/serverless

# pnpm
pnpm add @neondatabase/serverless

# yarn
yarn add @neondatabase/serverless

# bun
bun add @neondatabase/serverless

连接字符串

# 直接连接(用于迁移、脚本)
DATABASE_URL=postgresql://user:password@ep-xxx.us-east-1.aws.neon.tech/dbname?sslmode=require

# 池化连接(用于应用程序)
DATABASE_URL_POOLED=postgresql://user:password@ep-xxx-pooler.us-east-1.aws.neon.tech/dbname?sslmode=require

核心概念

概念 指南
无服务器驱动程序 reference/serverless-driver.md
连接池 reference/pooling.md
分支 reference/branching.md
自动扩缩 reference/autoscaling.md

示例

模式 指南
Next.js 集成 examples/nextjs.md
边缘函数 examples/edge.md
数据库迁移 examples/migrations.md
分支工作流 examples/branching-workflow.md

模板

模板 用途
templates/db.ts 数据库连接
templates/neon.config.ts Neon 配置

连接方法

HTTP(无服务器 - 推荐)

最佳适用:边缘函数、无服务器、一次性查询

import { neon } from "@neondatabase/serverless";

const sql = neon(process.env.DATABASE_URL!);

// 简单查询
const posts = await sql`SELECT * FROM posts WHERE published = true`;

// 带参数查询
const post = await sql`SELECT * FROM posts WHERE id = ${postId}`;

// 插入数据
await sql`INSERT INTO posts (title, content) VALUES (${title}, ${content})`;

WebSocket(连接池)

最佳适用:长连接、事务处理

import { Pool } from "@neondatabase/serverless";

const pool = new Pool({ connectionString: process.env.DATABASE_URL });

const client = await pool.connect();
try {
  await client.query("BEGIN");
  await client.query("INSERT INTO posts (title) VALUES ($1)", [title]);
  await client.query("COMMIT");
} catch (e) {
  await client.query("ROLLBACK");
  throw e;
} finally {
  client.release();
}

与 Drizzle ORM 集成

HTTP 驱动程序

// src/db/index.ts
import { neon } from "@neondatabase/serverless";
import { drizzle } from "drizzle-orm/neon-http";
import * as schema from "./schema";

const sql = neon(process.env.DATABASE_URL!);
export const db = drizzle(sql, { schema });

WebSocket 驱动程序

// src/db/index.ts
import { Pool } from "@neondatabase/serverless";
import { drizzle } from "drizzle-orm/neon-serverless";
import * as schema from "./schema";

const pool = new Pool({ connectionString: process.env.DATABASE_URL });
export const db = drizzle(pool, { schema });

分支功能

Neon 分支是数据库的写时复制克隆。

CLI 命令

# 安装 Neon CLI
npm install -g neonctl

# 登录
neonctl auth

# 列出分支
neonctl branches list

# 创建分支
neonctl branches create --name feature-x

# 获取连接字符串
neonctl connection-string feature-x

# 删除分支
neonctl branches delete feature-x

分支工作流

# 为功能创建分支
neonctl branches create --name feature-auth --parent main

# 获取分支的连接字符串
export DATABASE_URL=$(neonctl connection-string feature-auth)

# 开发功能...

# 完成后,通过应用迁移合并
neonctl branches delete feature-auth

CI/CD 集成

# .github/workflows/preview.yml
name: Preview
on: pull_request

jobs:
  preview:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Create Neon Branch
        uses: neondatabase/create-branch-action@v5
        id: branch
        with:
          project_id: ${{ secrets.NEON_PROJECT_ID }}
          api_key: ${{ secrets.NEON_API_KEY }}
          branch_name: preview-${{ github.event.pull_request.number }}

      - name: Run Migrations
        env:
          DATABASE_URL: ${{ steps.branch.outputs.db_url }}
        run: npx drizzle-kit migrate

连接池

何时使用连接池

场景 连接类型
边缘/无服务器函数 HTTP (neon)
涉及事务的 API 路由 WebSocket 池
长时间运行的进程 WebSocket 池
一次性查询 HTTP (neon)

池化器 URL

# 不使用池化器(直接连接)
postgresql://user:pass@ep-xxx.aws.neon.tech/db

# 使用池化器(在端点后添加 -pooler)
postgresql://user:pass@ep-xxx-pooler.aws.neon.tech/db

自动扩缩

在 Neon 控制台配置:

  • 最小计算单元:0.25 CU(可缩容至零)
  • 最大计算单元:最高 8 CU
  • 缩容至零延迟:5 分钟(默认)

处理冷启动

import { neon } from "@neondatabase/serverless";

const sql = neon(process.env.DATABASE_URL!, {
  fetchOptions: {
    // 为冷启动增加超时时间
    signal: AbortSignal.timeout(10000),
  },
});

最佳实践

1. 在无服务器环境中使用 HTTP

// 好 - 无服务器环境使用 HTTP
import { neon } from "@neondatabase/serverless";
const sql = neon(process.env.DATABASE_URL!);

// 避免 - 在无服务器环境中使用连接池(可能导致连接耗尽)
import { Pool } from "@neondatabase/serverless";
const pool = new Pool({ connectionString: process.env.DATABASE_URL });

2. 按环境配置连接字符串

# .env.development
DATABASE_URL=postgresql://...@ep-dev-branch...

# .env.production
DATABASE_URL=postgresql://...@ep-main...

3. 使用参数化查询

// 好 - 参数化查询
const result = await sql`SELECT * FROM users WHERE id = ${userId}`;

// 不好 - 字符串拼接(有 SQL 注入风险)
const result = await sql(`SELECT * FROM users WHERE id = '${userId}'`);

4. 错误处理

import { neon, NeonDbError } from "@neondatabase/serverless";

const sql = neon(process.env.DATABASE_URL!);

try {
  await sql`INSERT INTO users (email) VALUES (${email})`;
} catch (error) {
  if (error instanceof NeonDbError) {
    if (error.code === "23505") {
      // 唯一性约束冲突
      throw new Error("邮箱已存在");
    }
  }
  throw error;
}

Next.js App Router

// app/posts/page.tsx
import { neon } from "@neondatabase/serverless";

const sql = neon(process.env.DATABASE_URL!);

export default async function PostsPage() {
  const posts = await sql`SELECT * FROM posts ORDER BY created_at DESC`;

  return (
    <ul>
      {posts.map((post) => (
        <li key={post.id}>{post.title}</li>
      ))}
    </ul>
  );
}

Drizzle + Neon 完整设置

// src/db/index.ts
import { neon } from "@neondatabase/serverless";
import { drizzle } from "drizzle-orm/neon-http";
import * as schema from "./schema";

const sql = neon(process.env.DATABASE_URL!);
export const db = drizzle(sql, { schema });

// src/db/schema.ts
import { pgTable, serial, text, timestamp } from "drizzle-orm/pg-core";

export const posts = pgTable("posts", {
  id: serial("id").primaryKey(),
  title: text("title").notNull(),
  content: text("content"),
  createdAt: timestamp("created_at").defaultNow().notNull(),
});

// drizzle.config.ts
import { defineConfig } from "drizzle-kit";

export default defineConfig({
  schema: "./src/db/schema.ts",
  out: "./src/db/migrations",
  dialect: "postgresql",
  dbCredentials: {
    url: process.env.DATABASE_URL!,
  },
});