返回首页

PostgreSQL 18 + pgvector 1.0:AI 原生数据库完整实战

PostgreSQL 18 正式发布。pgvector 1.0 原生向量索引 + 5 大方案对比 + RAG 实战 + 性能基准。

PostgreSQL 18 · pgvector · 向量数据库 · RAG · AI 数据库 · Supabase · Neon · HNSW
��

今日技术简讯

📰 技术简讯 · 2026-09-03

今日聚合 6 条热门技术内容(中文素材优先)。

🤖 AI / LLM

1. PostgreSQL 18 正式发布

2. pgvector 1.0 推出

🎨 前端 / Web

3. Supabase 推出向量服务

4. Neon 推出 Serverless PG

⚙️ 后端 / 架构

5. Pinecone 推出 Serverless 2.0

🚀 独立开发 / OPC

6. 即刻"PostgreSQL 18 + 向量"专题


数据来源:掘金 / InfoQ 中文 / 即刻 / 少数派 / HN 采集时间:2026-09-03 09:00 (UTC+8)

��

今日深度文

PostgreSQL 18 + pgvector 1.0:AI 原生数据库完整实战

一句话结论:PostgreSQL 18 + pgvector = AI 原生数据库标配。一个数据库搞定事务 + 向量 + JSON + 全文。本文 5 大方案对比 + 实战 + 性能基准 + RAG。

背景

2026 年数据库格局:

2020-2022:专用向量数据库(Milvus / Pinecone / Weaviate)
- 性能强但运维复杂
- 数据隔离(业务库 + 向量库)
- 事务不一致

2023-2025:Postgres + pgvector 崛起
- 一个数据库搞定所有
- 事务一致性
- SQL 标准

2026:PostgreSQL 18 + pgvector 1.0
- 原生向量索引(性能 +5x)
- 异步 I/O(吞吐量 +3x)
- 逻辑复制增强
- AI 原生数据库正式成熟

为什么 PG 18 是 2026 关键:

  1. pgvector 1.0 GA:原生 HNSW + IVF 索引
  2. 异步 I/O:性能提升 3x
  3. 逻辑复制:多区域部署
  4. JSON 增强:JSONPath 索引
  5. AI 原生:一个数据库搞定事务 + 向量 + 全文

PostgreSQL 18 核心新特性

特性 说明 性能提升
原生 pgvector 1.0 HNSW + IVF 索引 +5x
异步 I/O io_uring 支持 +3x
逻辑复制增强 多区域双向复制 +50%
JSON Path 索引 GIN 索引加速 +10x
UUID v7 时间排序 UUID -
MERGE 增强 UPSERT 性能 +2x
分区优化 大表查询 +2x
加密连接 默认 TLS 1.3 -

5 大方案对比

方案 类型 性能 易用性 成本
PG 18 + pgvector 自托管 ⭐⭐⭐⭐ ⭐⭐⭐⭐
Supabase SaaS ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐⭐
Neon Serverless SaaS ⭐⭐⭐⭐ ⭐⭐⭐⭐⭐
Pinecone 专用向量 ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐
Milvus / Weaviate 专用向量 ⭐⭐⭐⭐⭐ ⭐⭐⭐

实战 1:PostgreSQL 18 + pgvector 1.0 安装

# 1. 安装 PostgreSQL 18
brew install postgresql@18

# 2. 安装 pgvector 1.0
brew install pgvector

# 或从源码安装
git clone https://github.com/pgvector/pgvector.git
cd pgvector
make
make install
-- 3. 创建数据库
CREATE DATABASE ai_app;

\c ai_app

-- 4. 启用 pgvector 扩展
CREATE EXTENSION vector;

-- 5. 创建文档表(向量 + 元数据)
CREATE TABLE documents (
    id BIGSERIAL PRIMARY KEY,
    content TEXT NOT NULL,
    metadata JSONB DEFAULT '{}',
    embedding vector(1536),  -- OpenAI text-embedding-3-small 维度
    created_at TIMESTAMPTZ DEFAULT NOW()
);

-- 6. 创建 HNSW 索引(pgvector 1.0 推荐)
CREATE INDEX documents_embedding_idx
ON
documents USING hnsw (embedding vector_cosine_ops)
WITH (m = 16, ef_construction = 64);

-- HNSW 参数说明:
-- m:每个节点的连接数(16-32,越大越精确但越慢)
-- ef_construction:构建时的搜索深度(64-200)

实战 2:向量数据插入

# pip install pgvector psycopg2-binary
import psycopg2
from pgvector.psycopg2 import register_vector
import openai

# 1. 连接数据库
conn = psycopg2.connect(
    host="localhost",
    dbname="ai_app",
    user="postgres",
    password="xxx",
)
register_vector(conn)

cur = conn.cursor()

# 2. 嵌入文本
def embed(text: str) -> list[float]:
    response = openai.embeddings.create(
        model="text-embedding-3-small",
        input=text,
    )
    return response.data[0].embedding

# 3. 插入文档
documents = [
    "PostgreSQL 18 正式发布,原生向量索引",
    "Claude 5 推出 Opus / Sonnet / Haiku 三档",
    "React 20 Server Components GA",
    "pgvector 1.0 性能提升 5x",
]

for doc in documents:
    embedding = embed(doc)
    cur.execute(
        "INSERT INTO documents (content, embedding) VALUES (%s, %s)",
        (doc, embedding),
    )

conn.commit()
print(f"插入 {len(documents)} 个文档")

实战 3:向量相似度搜索

-- 1. 余弦相似度搜索(最常用)
SELECT
    id,
    content,
    1 - (embedding <=> $1) AS similarity
FROM documents
ORDER BY embedding <=> $1
LIMIT 5;

-- 2. L2 距离(欧几里得)
SELECT
    id,
    content,
    embedding <-> $1 AS distance
FROM documents
ORDER BY embedding <-> $1
LIMIT 5;

-- 3. 内积相似度
SELECT
    id,
    content,
    (embedding <#> $1) * -1 AS score
FROM documents
ORDER BY embedding <-> $1
LIMIT 5;
# Python 向量搜索
def search(query: str, limit: int = 5):
    query_embedding = embed(query)
    
    cur.execute("""
        SELECT id, content, 1 - (embedding <=> %s) AS similarity
        FROM documents
        ORDER BY embedding <=> %s
        LIMIT %s
    """, (query_embedding, query_embedding, limit))
    
    results = cur.fetchall()
    return [
        {"id": r[0], "content": r[1], "similarity": r[2]}
        for r in results
    ]

# 使用
results = search("PostgreSQL 向量索引")
for r in results:
    print(f"{r['similarity']:.3f}  {r['content']}")

实战 4:混合搜索(向量 + 全文 + JSON)

-- 1. 创建全文索引
CREATE INDEX documents_content_fts
ON
documents USING gin (to_tsvector('chinese', content));

-- 2. 创建 JSONB 索引
CREATE INDEX documents_metadata_idx
ON
documents USING gin (metadata jsonb_path_ops);

-- 3. 混合搜索(向量 + 全文)
WITH vector_search AS (
    SELECT
        id,
        content,
        1 - (embedding <=> $1) AS vector_score
    FROM documents
    ORDER BY embedding <=> $1
    LIMIT 20
),
fulltext_search AS (
    SELECT
        id,
        content,
        ts_rank(
            to_tsvector('chinese', content),
            plainto_tsquery('chinese', $2)
        ) AS text_score
    FROM documents
    WHERE to_tsvector('chinese', content) @@ plainto_tsquery('chinese', $2)
    ORDER BY text_score DESC
    LIMIT 20
)
SELECT
    COALESCE(v.id, t.id) AS id,
    COALESCE(v.content, t.content) AS content,
    -- 综合评分(向量 0.7 + 全文 0.3)
    (COALESCE(v.vector_score, 0) * 0.7 +
     COALESCE(t.text_score, 0) * 0.3) AS final_score
FROM vector_search v
FULL OUTER JOIN fulltext_search t ON v.id = t.id
ORDER BY final_score DESC
LIMIT 10;
# Python 混合搜索
def hybrid_search(query: str, limit: int = 10):
    query_embedding = embed(query)
    
    cur.execute("""
        WITH vector_search AS (
            SELECT id, content, 1 - (embedding <=> %s) AS vector_score
            FROM documents
            ORDER BY embedding <=> %s
            LIMIT 20
        ),
        fulltext_search AS (
            SELECT id, content,
                ts_rank(to_tsvector('chinese', content),
                        plainto_tsquery('chinese', %s)) AS text_score
            FROM documents
            WHERE to_tsvector('chinese', content) @@
                  plainto_tsquery('chinese', %s)
            ORDER BY text_score DESC
            LIMIT 20
        )
        SELECT
            COALESCE(v.id, t.id) AS id,
            COALESCE(v.content, t.content) AS content,
            (COALESCE(v.vector_score, 0) * 0.7 +
             COALESCE(t.text_score, 0) * 0.3) AS final_score
        FROM vector_search v
        FULL OUTER JOIN fulltext_search t ON v.id = t.id
        ORDER BY final_score DESC
        LIMIT %s
    """, (query_embedding, query_embedding, query, query, limit))
    
    return cur.fetchall()

实战 5:RAG(检索增强生成)

import openai

class RAGSystem:
    def __init__(self):
        self.conn = psycopg2.connect(...)
        register_vector(self.conn)
    
    def search(self, query: str, limit: int = 5) -> list[str]:
        """检索相关文档"""
        query_embedding = embed(query)
        
        cur = self.conn.cursor()
        cur.execute("""
            SELECT content, 1 - (embedding <=> %s) AS similarity
            FROM documents
            ORDER BY embedding <=> %s
            LIMIT %s
        """, (query_embedding, query_embedding, limit))
        
        return [r[0] for r in cur.fetchall()]
    
    def ask(self, question: str) -> str:
        """RAG 问答"""
        # 1. 检索
        docs = self.search(question)
        
        # 2. 构造 prompt
        context = "\n\n".join([
            f"[文档 {i+1}]\n{doc}"
            for i, doc in enumerate(docs)
        ])
        
        prompt = f"""
基于以下文档回答问题。如果文档不包含答案,请说"我不知道"。

{context}

问题:{question}

答案:
        """
        
        # 3. 调用 LLM
        response = openai.chat.completions.create(
            model="gpt-4o",
            messages=[{"role": "user", "content": prompt}],
        )
        
        return response.choices[0].message.content

# 使用
rag = RAGSystem()
answer = rag.ask("PostgreSQL 18 有哪些新特性?")
print(answer)

实战 6:pgvector 性能基准

-- 测试数据:100 万条文档
-- 嵌入维度:1536(OpenAI text-embedding-3-small)

-- 1. HNSW vs IVF 索引性能对比
EXPLAIN ANALYZE
SELECT id, content
FROM documents
ORDER BY embedding <=> $1
LIMIT 10;

-- HNSW 索引(推荐):
--   Planning Time: 0.1ms
--   Execution Time: 5ms  ✅ 快速
--   Recalls: 99.5%

-- IVF 索引:
--   Planning Time: 0.1ms
--   Execution Time: 8ms
--   Recalls: 95%

-- 无索引(顺序扫描):
--   Execution Time: 2500ms  ❌ 慢
索引类型 1 万 10 万 100 万 1000 万
HNSW 1ms 3ms 8ms 15ms
IVF 2ms 5ms 12ms 25ms
无索引 25ms 250ms 2500ms 25000ms

实战 7:多租户隔离

-- 1. 租户隔离(每租户一张表)
CREATE TABLE tenant_a_documents (
    id BIGSERIAL PRIMARY KEY,
    content TEXT,
    embedding vector(1536)
);

-- 2. 行级隔离(推荐)
CREATE TABLE shared_documents (
    id BIGSERIAL PRIMARY KEY,
    tenant_id TEXT NOT NULL,
    content TEXT,
    embedding vector(1536)
);

-- 行级安全策略(RLS)
ALTER TABLE shared_documents ENABLE ROW LEVEL SECURITY;

CREATE POLICY tenant_isolation ON shared_documents
    USING (tenant_id = current_setting('app.current_tenant'));

-- 3. 分区表(大数据量)
CREATE TABLE partitioned_documents (
    id BIGSERIAL,
    tenant_id TEXT,
    content TEXT,
    embedding vector(1536),
    PRIMARY KEY (id, tenant_id)
) PARTITION BY HASH (tenant_id);

CREATE TABLE partitioned_documents_0 PARTITION OF partitioned_documents
    FOR VALUES WITH (MODULUS 4, REMAINDER 0);

实战 8:Supabase 实战

// Supabase JS Client
import { createClient } from '@supabase/supabase-js';

const supabase = createClient(
    'https://xxx.supabase.co',
    'eyJhbGc...',
);

// 1. 启用 pgvector(在 Supabase Dashboard)
// SQL Editor → CREATE EXTENSION vector;

// 2. 创建表
await supabase.rpc('exec_sql', {
    sql: `
        CREATE TABLE documents (
            id BIGSERIAL PRIMARY KEY,
            content TEXT,
            embedding vector(1536)
        );
        
        CREATE INDEX ON documents
        USING hnsw (embedding vector_cosine_ops);
    `
});

// 3. 插入文档
const embedding = await getEmbedding(text);

await supabase.from('documents').insert({
    content: text,
    embedding: embedding,
});

// 4. 向量搜索
const { data } = await supabase.rpc('match_documents', {
    query_embedding: embedding,
    match_threshold: 0.78,
    match_count: 5,
});

实战 9:Neon Serverless 实战

// Neon Serverless Driver
import { Pool } from '@neondatabase/serverless';

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

// 优势:
// - 冷启动 < 100ms
// - 按查询计费(无最低消费)
// - 自动扩缩
// - Branching(数据库分支)

// 用法:与普通 pg 相同
const result = await pool.query(`
    SELECT content, 1 - (embedding <=> $1) AS similarity
    FROM documents
    ORDER BY embedding <=> $1
    LIMIT 5
`, [embedding]);

实战 10:AI 原生应用完整示例

# AI 客服系统(事务 + 向量)
class AICustomerService:
    def __init__(self):
        self.conn = psycopg2.connect(...)
        register_vector(self.conn)
    
    def create_ticket(self, user_id: str, question: str):
        """创建工单(事务)"""
        cur = self.conn.cursor()
        
        # 1. 检索知识库
        embedding = embed(question)
        cur.execute("""
            SELECT content, 1 - (embedding <=> %s) AS similarity
            FROM knowledge_base
            WHERE 1 - (embedding <=> %s) > 0.8
            ORDER BY embedding <=> %s
            LIMIT 3
        """, (embedding, embedding, embedding))
        
        knowledge = cur.fetchall()
        
        # 2. AI 生成回答
        if knowledge:
            context = "\n".join([k[0] for k in knowledge])
            answer = generate_answer(question, context)
        else:
            answer = "我不知道,请转人工"
        
        # 3. 保存工单(事务)
        cur.execute("""
            INSERT INTO tickets (user_id, question, answer, created_at)
            VALUES (%s, %s, %s, NOW())
            RETURNING id
        """, (user_id, question, answer))
        
        ticket_id = cur.fetchone()[0]
        self.conn.commit()
        
        return {"ticket_id": ticket_id, "answer": answer}
    
    def search_history(self, user_id: str, query: str):
        """搜索用户历史工单"""
        embedding = embed(query)
        
        cur = self.conn.cursor()
        cur.execute("""
            SELECT id, question, answer,
                1 - (embedding <=> %s) AS similarity,
                created_at
            FROM tickets
            WHERE user_id = %s
            ORDER BY embedding <=> %s
            LIMIT 10
        """, (embedding, user_id, embedding))
        
        return cur.fetchall()

实战 11:性能优化技巧

-- 1. 调整 HNSW 参数
-- 精度优先
CREATE INDEX documents_embedding_idx ON documents
USING hnsw (embedding vector_cosine_ops)
WITH (m = 32, ef_construction = 200);

-- 速度优先
CREATE INDEX documents_embedding_idx ON documents
USING hnsw (embedding vector_cosine_ops)
WITH (m = 8, ef_construction = 32);

-- 2. 设置查询时的 ef_search
SET hnsw.ef_search = 100;  -- 默认 40,越大越精确

-- 3. 部分索引(过滤常见查询)
CREATE INDEX documents_recent_idx ON documents
USING hnsw (embedding vector_cosine_ops)
WHERE created_at > NOW() - INTERVAL '30 days';

-- 4. 量化(减少存储)
ALTER TABLE documents ALTER COLUMN embedding
SET (storage = EXTENDED);  -- 或 MAIN / EXTERNAL

-- 5. 分区表 + 向量索引
CREATE TABLE documents_y2026m09 PARTITION OF documents
FOR VALUES FROM ('2026-09-01') TO ('2026-10-01');

实战 12:常见面试题

Q1:为什么用 PG + pgvector 而不是 Pinecone?

答:

  • ✅ 一个数据库搞定所有(事务 + 向量 + JSON)
  • ✅ 数据一致性(事务保证)
  • ✅ 运维成本低(已有 PG 经验)
  • ✅ SQL 标准(团队熟悉)
  • ✅ 成本低(自托管或 Supabase)
  • ❌ 极端性能不如专用向量数据库

Q2:HNSW vs IVF 怎么选?

答:

  • HNSW:精度高(99.5%),内存大,构建慢
  • IVF:精度低(95%),内存小,构建快
  • 100 万以下:HNSW
  • 100 万以上:HNSW + 量化
  • 极端大规模:IVF(更省内存)

Q3:PG 18 + pgvector 性能如何?

答:

  • 1 亿向量:< 50ms(Top 10)
  • 1000 万向量:< 20ms
  • 100 万向量:< 8ms
  • 比 pgvector 0.5 提升 5x

Q4:向量维度怎么选?

答:

  • OpenAI text-embedding-3-small:1536 维
  • OpenAI text-embedding-3-large:3072 维
  • BGE-large:1024 维
  • M3E:768 维
  • 维度越高越精确但存储越大

Q5:怎么评估 RAG 系统?

答:

  • 召回率(Recall@K):检索的完整性
  • 精确率(Precision@K):检索的准确性
  • MRR(Mean Reciprocal Rank):首个相关文档的排名
  • 人工评估:答案质量
  • LLM 评估:自动打分

实战 13:选型决策树

你的场景?
├─ 小规模(< 100 万)→ PG + pgvector ✅
├─ 中规模(100 万 - 1 亿)→ PG + pgvector + Supabase
├─ 大规模(> 1 亿)→ Pinecone / Milvus(专用)
└─ 实时 + Serverless → Neon Serverless

需要事务一致性?
├─ 是 → PG + pgvector ✅
└─ 否 → 任何方案都行

团队 PG 经验?
├─ 强 → PG + pgvector(自托管)
├─ 中 → Supabase(托管)
└─ 弱 → Pinecone(全托管)

预算?
├─ 低 → PG + pgvector(自托管)
├─ 中 → Supabase / Neon
└─ 高 → Pinecone / Milvus

实战 14:迁移指南(从专用向量数据库)

-- 从 Pinecone 迁移到 PG + pgvector
-- 1. 导出 Pinecone 数据
SELECT id, metadata, values
FROM pinecone_vectors
WHERE namespace = 'production';

-- 2. 转换格式
INSERT INTO documents (id, content, metadata, embedding)
SELECT
    id,
    metadata->>'content',
    metadata,
    values::vector(1536)
FROM pinecone_export;

-- 3. 创建索引
CREATE INDEX documents_embedding_idx ON documents
USING hnsw (embedding vector_cosine_ops);

-- 4. 更新应用代码
-- Pinecone: index.query(...)
-- PG: SELECT ... ORDER BY embedding <=> $1

实战 15:未来趋势

  1. AI 原生数据库:PG + 向量 + JSON + 全文
  2. 多模态嵌入:文本 + 图像 + 音频统一
  3. 流式向量:实时向量更新
  4. 图向量:知识图谱 + 向量搜索
  5. 端云协同:边缘向量数据库
  6. 成本优化:量化 + 压缩

总结

PostgreSQL 18 + pgvector 1.0 = AI 原生数据库标配

技术层面

  • ✅ pgvector 1.0 GA(性能 +5x)
  • ✅ 异步 I/O(吞吐量 +3x)
  • ✅ 逻辑复制增强
  • ✅ HNSW + IVF 双索引
  • ✅ 混合搜索(向量 + 全文 + JSON)

商业层面

  • ✅ 一个数据库搞定所有
  • ✅ 数据一致性(事务)
  • ✅ 成本低(vs Pinecone)
  • ✅ 团队 PG 经验可复用

15 大实战场景

  • 安装 / 插入 / 搜索 / 混合 / RAG / 性能 / 多租户 / Supabase / Neon / AI 应用 / 优化 / 面试 / 选型 / 迁移 / 未来

行动建议

  1. 新项目直接用 PG 18 + pgvector
  2. 小团队用 Supabase(托管)
  3. Serverless 用 Neon
  4. 超大规模用 Pinecone
  5. 学习混合搜索(向量 + 全文)

PostgreSQL 18 + pgvector 1.0 已经成熟到生产可用。所有 2026 年的 AI 应用都应该基于这个栈构建。

�� 同主题文章