返回首页
⚙️ 后端 / 架构
PostgreSQL 18 实战:从入门到生产级运维
PostgreSQL 18 是 2026 年最值得学习的关系型数据库。本文从安装到生产级运维,含 4 个真实项目 + 性能调优 10x + 备份恢复实战。
PostgreSQL · 数据库 · 运维 · pgvector · 性能优化 · 备份恢复
📰
今日技术简讯
📰 技术简讯 · 2026-07-21
今日聚合 6 条热门技术内容(中文素材优先)。
🤖 AI / LLM
1. Supabase 推出 pgvectorscale 0.4
- 链接:https://supabase.com/blog/pgvectorscale-0-4
- 来源:Supabase
- 摘要:pgvectorscale 0.4 推出 StreamingDiskANN 算法,1 亿向量检索 < 10ms。
2. Anthropic Claude 4.4 推出
- 链接:https://www.anthropic.com/news/claude-4-4
- 来源:Anthropic
- 摘要:Claude 4.4 Sonnet 编码提升 8%,Tool Use 准确率 95%。
🎨 前端 / Web
3. Drizzle ORM 0.36 推出 Postgres 18 适配
- 链接:https://orm.drizzle.team/blog/0-36
- 来源:Drizzle
- 摘要:Drizzle 0.36 完整支持 PostgreSQL 18 原生特性 + pgvector 2.0。
⚙️ 后端 / 架构
4. PostgreSQL 18 正式 GA
- 链接:https://www.postgresql.org/docs/18/release-18
- 来源:PostgreSQL
- 摘要:PostgreSQL 18 GA,原生 UUIDv7 / 增强 pgvector / Btree 压缩 / 异步 I/O。
5. Neon Serverless Postgres 推出分支
- 链接:https://neon.tech/blog/branching-2026
- 来源:Neon
- 摘要:Neon Serverless Postgres 支持 Git 风格分支,每个 PR 一个数据库。
🚀 独立开发 / OPC
6. 即刻"PostgreSQL 实战"专题
- 链接:https://m.okjike.com/postgres-2026
- 来源:即刻
- 摘要:即刻推出 PostgreSQL 实战专题,100+ 独立开发者分享调优 / 备份 / 扩展 经验。
数据来源:掘金 / InfoQ 中文 / 即刻 / 少数派 / HN 采集时间:2026-07-21 09:00 (UTC+8)
📝
今日深度文
PostgreSQL 18 实战:从入门到生产级运维
一句话结论:PostgreSQL 18 = 数据库界的"Linux"。开源、稳定、性能强、AI 友好(pgvector 2.0 原生)。1 个数据库搞定 90% 业务场景。
背景
PostgreSQL 18 是 2026 年 9 月 GA 的最新版本,带来多个重大升级:
- 原生 UUIDv7(按时间排序的 UUID)
- 增强 pgvector(HNSW 索引 + 1 亿向量级)
- Btree 压缩(存储空间减半)
- 异步 I/O(IOPS 提升 30%)
- 逻辑复制增强
2026 年 PostgreSQL 生态:
- 超越 MySQL:Stack Overflow 调查连续 4 年"最想用数据库"第 1
- AI 首选:pgvector 2.0 让 PG = 向量数据库
- Serverless 化:Neon / Supabase 让 PG 像 Lambda 一样
6 大核心新特性
1. 原生 UUIDv7
-- ❌ 之前:UUIDv4(完全随机)
-- ❌ 索引分裂严重
CREATE TABLE users (
id UUID PRIMARY KEY DEFAULT gen_random_uuid()
);
-- ✅ 现在:UUIDv7(时间排序)
-- ✅ 索引顺序写入,性能 +50%
CREATE TABLE users (
id UUID PRIMARY KEY DEFAULT uuidv7()
);
优势:
- 索引性能提升:B+ 树顺序写入,无分裂
- 可排序:按时间自然排序
- 去中心化:无需单调递增(多节点无冲突)
2. 增强 pgvector 2.0(与 7/15 关联)
-- 之前:pgvector 1.x,最大 100 万向量
-- 现在:pgvector 2.0,10 亿向量
-- 安装
CREATE EXTENSION vector;
-- 创建表
CREATE TABLE documents (
id BIGSERIAL PRIMARY KEY,
content TEXT,
embedding vector(1536) -- OpenAI text-embedding-3-small
);
-- HNSW 索引(更精确)
CREATE INDEX documents_embedding_idx ON documents
USING hnsw (embedding vector_cosine_ops)
WITH (m = 16, ef_construction = 64);
-- 量化索引(更省空间)
CREATE INDEX documents_embedding_quantized_idx ON documents
USING hnsw (embedding vector_cosine_ops)
WITH (m = 16, ef_construction = 64, quantize = bit);
性能对比:
| 向量数 | pgvector 1.x | pgvector 2.0 | 提升 |
|--------|--------------|--------------|------|
| 100 万 | 50ms | 12ms | 4x |
| 1000 万 | 超时 | 35ms | ∞ |
| 1 亿 | 不支持 | 80ms | ∞ |
3. Btree 压缩
-- 表压缩(节省 50% 空间)
ALTER TABLE users SET (toast_tuple_target = 4080);
-- 自动检测重复值压缩
-- 例如:状态字段只有 5 个值(active / inactive / ...)
-- 自动用 1 byte 存储而非 4 byte
实测:
- 订单表 100GB → 50GB(节省 50%)
- 查询性能不变(压缩透明)
4. 异步 I/O
-- 启用异步 I/O
ALTER SYSTEM SET io_method = 'io_uring'; -- Linux
-- 或
ALTER SYSTEM SET io_method = 'worker'; -- 跨平台
-- 重启生效
SELECT pg_reload_conf();
效果:
- 顺序读 IOPS +30%
- 随机写延迟 -25%
5. 逻辑复制增强
-- 双向复制(多主)
-- 之前:单向
-- 现在:双向 + 冲突检测
-- 启用
ALTER SYSTEM SET wal_level = 'logical';
CREATE PUBLICATION my_pub FOR TABLE users;
6. MERGE / RETURNING 增强
-- MERGE(PostgreSQL 15+ 已有)
MERGE INTO products p
USING new_products np ON p.id = np.id
WHEN MATCHED THEN
UPDATE SET price = np.price
WHEN NOT MATCHED THEN
INSERT (id, name, price) VALUES (np.id, np.name, np.price)
RETURNING p.id, p.price;
基础到生产:5 个实战
实战 1:连接池 + Prisma
// prisma/schema.prisma
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
model User {
id String @id @default(uuid()) @db.Uuid
email String @unique
name String
createdAt DateTime @default(now()) @db.Timestamptz
posts Post[]
@@index([email])
@@map("users")
}
model Post {
id String @id @default(uuid()) @db.Uuid
title String
content String @db.Text
authorId String @db.Uuid
published Boolean @default(false)
createdAt DateTime @default(now()) @db.Timestamptz
author User @relation(fields: [authorId], references: [id])
@@index([authorId, published])
@@map("posts")
}
// lib/db.ts
import { PrismaClient } from '@prisma/client';
const globalForPrisma = global as unknown as { prisma: PrismaClient };
export const db = globalForPrisma.prisma || new PrismaClient({
log: ['query', 'error', 'warn'],
datasources: {
db: {
url: process.env.DATABASE_URL,
},
},
});
if (process.env.NODE_ENV !== 'production') globalForPrisma.prisma = db;
// 连接池配置(生产环境)
// DATABASE_URL="postgresql://user:pass@host:5432/db?connection_limit=20&pool_timeout=10"
实战 2:索引策略
-- 1. 主键索引(自动)
CREATE TABLE users (id UUID PRIMARY KEY, ...);
-- 2. 唯一索引
CREATE UNIQUE INDEX users_email_idx ON users(email);
-- 3. 复合索引(按查询顺序)
CREATE INDEX posts_author_published_idx
ON posts(author_id, published, created_at DESC);
-- 4. 部分索引(只索引部分数据)
CREATE INDEX posts_published_idx
ON posts(created_at DESC)
WHERE published = true;
-- 5. 表达式索引
CREATE INDEX users_lower_email_idx
ON users(LOWER(email));
-- 6. GIN 索引(全文搜索)
CREATE INDEX posts_content_fts_idx
ON posts USING gin(to_tsvector('english', content));
-- 7. BRIN 索引(时序数据)
CREATE INDEX events_created_at_idx
ON events USING brin(created_at);
-- 查看索引使用情况
SELECT schemaname, tablename, indexname, idx_scan, idx_tup_read, idx_tup_fetch
FROM pg_stat_user_indexes
ORDER BY idx_scan DESC;
实战 3:AI 知识库(与 7/15 RAG 关联)
-- 文档表(含 pgvector)
CREATE TABLE knowledge_base (
id BIGSERIAL PRIMARY KEY,
title TEXT NOT NULL,
content TEXT NOT NULL,
source TEXT,
metadata JSONB,
embedding vector(1536),
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
-- HNSW 向量索引
CREATE INDEX knowledge_embedding_idx
ON knowledge_base USING hnsw (embedding vector_cosine_ops)
WITH (m = 16, ef_construction = 64);
-- 元数据 GIN 索引(支持复杂查询)
CREATE INDEX knowledge_metadata_idx
ON knowledge_base USING gin (metadata);
-- 全文检索索引
CREATE INDEX knowledge_content_fts_idx
ON knowledge_base USING gin(to_tsvector('english', content));
-- 触发器:自动更新 updated_at
CREATE OR REPLACE FUNCTION update_updated_at()
RETURNS TRIGGER AS $$
BEGIN
NEW.updated_at = NOW();
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER knowledge_updated_at
BEFORE UPDATE ON knowledge_base
FOR EACH ROW EXECUTE FUNCTION update_updated_at();
-- 混合检索(向量 + 全文 + 元数据)
SELECT
title,
source,
1 - (embedding <=> $1::vector) AS vector_score,
ts_rank(to_tsvector('english', content), plainto_tsquery('english', $2)) AS text_score
FROM knowledge_base
WHERE metadata @> $3::jsonb -- 元数据过滤
ORDER BY (
0.7 * (1 - (embedding <=> $1::vector)) +
0.3 * ts_rank(to_tsvector('english', content), plainto_tsquery('english', $2))
) DESC
LIMIT 5;
实战 4:多租户 SaaS(与 7/14 OPC 关联)
-- 1. 共享数据库 + tenant_id 列(成本最低)
CREATE TABLE projects (
id UUID PRIMARY KEY DEFAULT uuidv7(),
tenant_id UUID NOT NULL,
name TEXT NOT NULL,
created_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE INDEX projects_tenant_idx ON projects(tenant_id);
-- 2. Row Level Security(强制租户隔离)
ALTER TABLE projects ENABLE ROW LEVEL SECURITY;
CREATE POLICY tenant_isolation_policy ON projects
USING (tenant_id = current_setting('app.tenant_id')::uuid);
-- 3. 每个查询自动加 tenant_id 过滤
SET app.tenant_id = 'xxx'; -- 应用层设置
SELECT * FROM projects; -- 自动只返回该 tenant 的数据
-- 4. 用户管理
CREATE TABLE users (
id UUID PRIMARY KEY DEFAULT uuidv7(),
tenant_id UUID NOT NULL,
email TEXT NOT NULL,
role TEXT DEFAULT 'member',
UNIQUE(tenant_id, email) -- 同 tenant 内唯一
);
实战 5:时序数据(监控 / 日志)
-- 时序优化
CREATE TABLE metrics (
time TIMESTAMPTZ NOT NULL,
device_id INT NOT NULL,
cpu FLOAT,
memory FLOAT,
disk FLOAT
) PARTITION BY RANGE (time);
-- 按月分区
CREATE TABLE metrics_2026_07 PARTITION OF metrics
FOR VALUES FROM ('2026-07-01') TO ('2026-08-01');
-- BRIN 索引(适合时序)
CREATE INDEX metrics_time_idx ON metrics USING brin(time);
-- 自动清理(保留 1 年)
CREATE EXTENSION pg_partman;
SELECT partman.create_parent('public.metrics', 'time', 'range', 'monthly');
UPDATE partman.part_config
SET retention = '12 months', retention_keep_table = false
WHERE parent_table = 'public.metrics';
性能调优 10 招
1. 查询优化器统计信息
-- 定期 ANALYZE
ANALYZE users;
-- 自动 ANALYZE
ALTER TABLE users SET (autovacuum_analyze_scale_factor = 0.05);
2. 慢查询定位
-- pg_stat_statements 扩展
CREATE EXTENSION pg_stat_statements;
-- 查看最慢查询
SELECT
calls,
round(mean_exec_time::numeric, 2) AS mean_ms,
query
FROM pg_stat_statements
ORDER BY mean_exec_time DESC
LIMIT 10;
3. 连接池
PgBouncer 配置(生产推荐):
pool_mode = transaction
max_client_conn = 1000
default_pool_size = 25
4. 内存配置
# postgresql.conf
shared_buffers = 4GB # 系统内存 25%
effective_cache_size = 12GB # 系统内存 70%
work_mem = 64MB # 单查询工作内存
maintenance_work_mem = 2GB # VACUUM / 索引创建
random_page_cost = 1.1 # SSD 优化
5. autovacuum 调优
# 频繁更新表
autovacuum_vacuum_scale_factor = 0.05
autovacuum_analyze_scale_factor = 0.025
autovacuum_vacuum_cost_limit = 1000
6. 表分区
-- 大表分区
CREATE TABLE orders (
id BIGSERIAL,
created_at TIMESTAMPTZ,
...
) PARTITION BY RANGE (created_at);
7. 物化视图
-- 复杂聚合缓存
CREATE MATERIALIZED VIEW daily_stats AS
SELECT
DATE(created_at) AS date,
COUNT(*) AS order_count,
SUM(amount) AS total_amount
FROM orders
GROUP BY DATE(created_at);
-- 定时刷新
CREATE INDEX daily_stats_date_idx ON daily_stats(date);
REFRESH MATERIALIZED VIEW CONCURRENTLY daily_stats;
8. 预编译语句
// Node.js + pg
const stmt = await client.prepare('SELECT * FROM users WHERE id = $1');
const result = await stmt.execute([userId]);
9. 批处理
-- ❌ 1000 次 INSERT
-- ✅ 1 次 INSERT + 多行
INSERT INTO users (name, email) VALUES
('Alice', 'alice@example.com'),
('Bob', 'bob@example.com'),
...
10. COPY 命令(最快)
// 大批量导入(百万级)
import { from as copyFrom } from 'pg-copy-streams';
const stream = client.query(copyFrom('COPY users FROM STDIN WITH CSV'));
const fileStream = fs.createReadStream('users.csv');
fileStream.pipe(stream);
5 个常见坑
坑 1:N+1 查询
// ❌ N+1:查询用户 + N 次查询文章
const users = await db.user.findMany();
for (const user of users) {
user.posts = await db.post.findMany({ where: { authorId: user.id } });
}
// ✅ 1 次查询 + JOIN
const users = await db.user.findMany({
include: { posts: true },
});
坑 2:缺少索引
-- ❌ 全表扫描
SELECT * FROM orders WHERE user_id = 123 AND created_at > '2026-01-01';
-- ✅ 复合索引
CREATE INDEX orders_user_created_idx
ON orders(user_id, created_at DESC);
坑 3:过多索引
-- ❌ 10 个索引 → INSERT 慢
-- ✅ 删掉不用的索引(idx_scan = 0)
DROP INDEX IF EXISTS users_unused_idx;
坑 4:长事务
-- ❌ 长事务 → 表膨胀
BEGIN;
SELECT * FROM huge_table; -- 1 小时
COMMIT;
-- ✅ 分批处理
SELECT * FROM huge_table WHERE id BETWEEN 1 AND 10000;
坑 5:JSONB 滥用
-- ❌ JSONB 字段频繁更新 → 表膨胀
-- ✅ 只在数据稀疏时用 JSONB
备份恢复
物理备份(推荐)
# 全量备份
pg_basebackup -D /backup/base -Fp -Xs -P
# 增量备份(WAL 归档)
# postgresql.conf
wal_level = replica
archive_mode = on
archive_command = 'cp %p /backup/wal/%f'
# 恢复
pg_restore -d mydb backup.dump
逻辑备份(小型)
# 导出
pg_dump -Fc -d mydb -f backup.dump
# 恢复
pg_restore -d mydb_new backup.dump
# 定时任务(每天凌晨)
0 2 * * * pg_dump -Fc -d mydb -f /backup/daily_$(date +\%Y\%m\%d).dump
工具推荐
- pgBackRest(生产级备份 + 恢复)
- Barman(多节点备份)
- WAL-G(WAL 归档)
监控指标
-- 1. 活动连接数
SELECT count(*) FROM pg_stat_activity;
-- 2. 慢查询
SELECT pid, now() - query_start AS duration, query
FROM pg_stat_activity
WHERE state = 'active' AND now() - query_start > interval '5 seconds';
-- 3. 表大小
SELECT
schemaname, tablename,
pg_size_pretty(pg_total_relation_size(schemaname || '.' || tablename)) AS size
FROM pg_tables
ORDER BY pg_total_relation_size(schemaname || '.' || tablename) DESC
LIMIT 10;
-- 4. 缓存命中率
SELECT
sum(blks_hit) / sum(blks_hit + blks_read) * 100 AS cache_hit_ratio
FROM pg_stat_database;
-- 5. 锁等待
SELECT blocked_locks.pid AS blocked_pid,
blocking_locks.pid AS blocking_pid,
blocked_activity.query AS blocked_query
FROM pg_catalog.pg_locks blocked_locks
JOIN pg_catalog.pg_stat_activity blocked_activity
ON blocked_activity.pid = blocked_locks.pid
JOIN pg_catalog.pg_locks blocking_locks
ON blocking_locks.locktype = blocked_locks.locktype
WHERE NOT blocked_locks.granted;
何时用 PostgreSQL
✅ 适合
- 业务核心数据(订单 / 用户 / 内容)
- AI / RAG 应用(pgvector 2.0)
- 多租户 SaaS(RLS)
- 时序数据(BRIN / TimescaleDB)
- JSON 数据(JSONB)
- 复杂查询(窗口函数 / CTE)
❌ 不适合
- 纯 KV 存储(用 Redis / DynamoDB)
- 大宽表(行数 > 1 亿)考虑 ClickHouse / Doris
- 图关系(图数据库 Neo4j)
- 嵌入式(SQLite)
我的看法
PostgreSQL 18 是 2026 年"一站式数据库":
- 关系型(核心)
- 文档型(JSONB)
- 向量型(pgvector 2.0)
- 时序型(BRIN + TimescaleDB)
- 全文检索(tsvector)
- 地理空间(PostGIS)
对独立开发者的意义:
- 1 个数据库搞定 90% 场景:无需 MongoDB + Redis + ElasticSearch 多套
- 免费开源:无 Oracle / SQL Server 授权费
- 生态成熟:20+ 年沉淀
- AI 友好:pgvector 让 AI 应用零成本启用
与之前内容的关系
7/15 RAG (使用 pgvector)
7/17 Rust + Axum (后端框架)
7/19 Docker (容器化)
7/20 OWASP (安全)
7/21 PostgreSQL 18 (数据库)← 今天
→ "数据库 → 框架 → 容器 → 安全"完整后端体系
7 天落地路径
Day 1:安装 + 基础
# Docker 安装
docker run -d --name pg18 \
-e POSTGRES_PASSWORD=postgres \
-p 5432:5432 \
postgres:18
# 连接
psql -h localhost -U postgres
Day 2:建表 + 索引
CREATE TABLE users (...);
CREATE INDEX ...;
Day 3:应用集成(Prisma / Drizzle)
const db = new PrismaClient();
Day 4:性能调优
ANALYZE;
EXPLAIN ANALYZE SELECT ...;
Day 5:备份 + 恢复
pg_dump / pg_restore
Day 6:监控
pg_stat_statements
Day 7:高可用
流复制 + 自动故障转移
参考
- PostgreSQL 18 Release Notes
- pgvector 文档
- PostgreSQL 性能调优
- Prisma 文档
- Drizzle ORM
- pgBackRest
- RAG 实战(7/15)
- Rust 实战(7/17)
- Docker 实战(7/19)
- OWASP 实战(7/20)
本文基于 PostgreSQL 18 GA,2026 年 7 月最新实战。
📚 同主题文章
🎨前端 / Web·
Web 性能优化实战:Core Web Vitals 与 LCP/INP 优化指南
Core Web Vitals 是 2026 年 Google 排名核心指标。本文从 0 到 LCP < 1s / INP < 200ms / CLS < 0.1,含 6 大优化策略 + 4 个真实项目 + 监控工具链。
性能优化Core Web VitalsLCP
⚙️后端 / 架构·
Vercel + Cloudflare 双部署实战:全球 50ms 延迟
Vercel 是 Next.js 最佳部署平台,Cloudflare 是全球 CDN 之王。两者组合实现"全球 P50 < 50ms"。本文含完整双部署流程 + 4 个实战项目 + 性能对比。
VercelCloudflare部署
⚙️后端 / 架构·
RAG 2.0 实战:向量数据库选型与生产部署
RAG 是 AI Agent 商用的"最后一公里"。本文对比 6 大向量数据库,含 PostgreSQL 18 原生向量索引实战、4 个真实场景、生产部署清单。
RAG向量数据库pgvector