向量数据库已死?PostgreSQL 这个新功能,让闭源尬住了
一实习生用47分钟在现有Postgres里实现了向量搜索 ---- 完全免费
整个向量数据库市场都在集体屏息。
泡沫刚刚破灭。
还记得去年所有人都在说你需要专门的向量数据库吗?当 Pinecone 融资1.38亿美元、Weaviate 成为独角兽时?当每个创业公司的融资PPT第三页都写着“由[某向量数据库]驱动”时?
PostgreSQL 刚刚发布了 pgvector 0.8.0,其新功能让专用向量数据库看起来像是昂贵的过度设计。对于价值数十亿美元的向量数据库行业来说,这个时机再糟糕不过了。
这是真实发生的故事。
场景重现:我们是如何走到今天的?
当 ChatGPT 在2022年底爆发时,企业突然发现他们需要地方来存储嵌入向量,以实现检索增强生成。一夜之间,存储和搜索数百万个高维向量成为了必备能力。
专用向量数据库的推销话术很简单:你的传统数据库处理不了这个。你需要专门的基础设施。你需要我们。
仅在2023年4月,Pinecone 和 Chroma 就完成了巨额融资轮。信息很明确:向量数据库是未来,如果你想构建AI应用,最好跟上潮流。
但有个问题。
大多数公司已经有一个数据库了。一个非常好的数据库。PostgreSQL 几十年来一直是Web应用的主力,每天为从 Instagram 到 Spotify 的公司处理数十亿事务。
于是开发者们问了那个显而易见的问题:我们能在Postgres里直接做向量搜索吗?
向量数据库厂商说不行。他们写博客文章解释为什么你需要专门的基础设施。他们把 HNSW 算法和近似最近邻搜索说得像火箭科学一样复杂。
然后 pgvector 出现了,并且说:实际上,你可以。
真正的变革:pgvector 0.8.0 带来了什么
这次更新增加了迭代索引扫描和智能查询规划。这些不是花哨的功能,而是那种彻底改变游戏规则的、看似枯燥的基础设施改进。
让我用程序员能理解的方式解释这些功能到底做了什么:
1. 迭代索引扫描:告别“零结果”尴尬
以前,当你通过元数据过滤向量时(比如“显示价格低于50美元的类似产品”),如果过滤器太严格,你可能会得到零个结果。现在,pgvector 可以增量扫描,直到找到足够匹配项。
# 以前:过滤太严格可能导致没有结果
# 现在:自动找到最接近的匹配项
query = """
SELECT product_name, price,
embedding <=> %s as similarity
FROM products
WHERE price < 50 AND category = 'electronics'
ORDER BY similarity
LIMIT 10;
"""
2. 智能查询规划:Postgres现在更“聪明”了
PostgreSQL 现在知道何时使用你的常规索引而不是向量索引。有时,在过滤条件上使用 B-tree 索引比扫描向量更快。Postgres 会自动判断选择最优策略。
# Postgres会自动选择最佳查询计划:
# 1. 先用价格索引过滤
# 2. 再在结果集中进行向量搜索
# 全部自动完成,无需手动优化
实战演示:用pgvector构建产品推荐系统
让我用一个完整的例子展示如何在现有产品表中添加向量搜索。
步骤1:启用扩展并修改表结构
# 首先启用pgvector扩展
import psycopg2
conn = psycopg2.connect(
host="localhost",
database="your_db",
user="your_user",
password="your_password"
)
cur = conn.cursor()
# 启用pgvector扩展
cur.execute("CREATE EXTENSION IF NOT EXISTS vector;")
# 为现有产品表添加向量列
cur.execute("""
ALTER TABLE products
ADD COLUMN IF NOT EXISTS embedding vector(1536);
""")
conn.commit()
步骤2:创建混合索引
# 创建向量索引(支持余弦相似度)
cur.execute("""
CREATE INDEX IF NOT EXISTS idx_product_embedding
ON products USING hnsw (embedding vector_cosine_ops);
""")
# 常规索引仍然有效
cur.execute("""
CREATE INDEX IF NOT EXISTS idx_product_price
ON products(price);
""")
# 复合索引也很容易创建
cur.execute("""
CREATE INDEX IF NOT EXISTS idx_product_category_price
ON products(category, price);
""")
conn.commit()
步骤3:执行智能查询
deffind_similar_products(product_id, max_price=None, category_filter=None):
"""
查找类似产品,支持价格和类别过滤
"""
# 1. 获取目标产品的向量
cur.execute("""
SELECT embedding FROM products WHERE id = %s;
""", (product_id,))
target_embedding = cur.fetchone()[0]
# 2. 构建动态查询
query = """
SELECT id, name, price, category,
(embedding <=> %s) as similarity
FROM products
WHERE id != %s
"""
params = [target_embedding, product_id]
# 动态添加过滤器
if max_price:
query += " AND price <= %s"
params.append(max_price)
if category_filter:
query += " AND category = %s"
params.append(category_filter)
query += " ORDER BY similarity LIMIT 10;"
# 3. 执行查询(Postgres会自动选择最优执行计划)
cur.execute(query, params)
return cur.fetchall()
# 使用示例:查找类似但更便宜的电子产品
similar = find_similar_products(
product_id=123,
max_price=50,
category_filter='electronics'
)
成本对比:数字不会说谎
让我们算一笔实实在在的经济账。
专用向量数据库方案(以 Pinecone 为例)
费用:每月每百万向量约70美元 基础设施:需要单独部署和管理 数据同步:主数据库和向量存储之间的同步复杂性 学习成本:需要学习新的查询语言和API
PostgreSQL + pgvector 方案
扩展费用:完全免费 基础设施:你已经为Postgres付费了 数据同步:零同步,因为所有数据都在一处 学习成本:你的团队已经熟悉SQL
# 假设你有100万产品向量
pinecone_cost = 70# 美元/月
# 使用pgvector的成本计算
pgvector_cost = 0# 扩展本身免费
# 额外存储成本(可以忽略不计)
additional_storage = 1000000 * 1536 * 4 / (1024**3) # 约5.7GB
storage_cost = 5.7 * 0.1# 约0.57美元/月(按云存储价格估算)
print(f"专用方案月成本: ${pinecone_cost}")
print(f"pgvector方案月成本: ${storage_cost:.2f}")
print(f"每月节省: ${pinecone_cost - storage_cost:.2f}")
print(f"每年节省: ${(pinecone_cost - storage_cost) * 12:.2f}")
架构对比:简单 vs 复杂
传统方案:双数据库架构
用户查询
↓
应用服务器
↓
├──> PostgreSQL(结构化数据:用户、订单、产品)
└──> Pinecone(向量数据:产品嵌入)
↓
数据同步服务(复杂度高,延迟问题)
↓
最终一致性问题(数据不同步的风险)
pgvector方案:一体化架构
用户查询
↓
应用服务器
↓
PostgreSQL(所有数据:结构化+向量)
↓
原子操作、强一致性、简化运维
性能真相:差距正在迅速缩小
向量数据库公司喜欢谈论基准测试。但他们没告诉你的是:
pgvector 0.7.0 已经支持:
半精度向量(存储减半) 支持高达4000维的索引 二值量化支持高达64000维
真正的瓶颈往往不是搜索速度:
应用服务器和向量数据库之间的网络延迟 Postgres 和向量存储之间的数据同步延迟 不理解过滤条件的查询规划
# 性能对比测试框架
import time
defbenchmark_search(conn, query_func, iterations=100):
"""基准测试函数"""
times = []
for i in range(iterations):
start = time.time()
query_func()
times.append(time.time() - start)
return {
'avg': sum(times) / len(times),
'p95': sorted(times)[int(len(times) * 0.95)],
'p99': sorted(times)[int(len(times) * 0.99)]
}
# 对于大多数应用(百万级向量),pgvector性能完全足够
# 而且避免了网络往返开销
何时你确实需要专用向量数据库?
我不是说向量数据库已经死了。确实存在需要它们的合理场景:
超大规模向量:如果你有数十亿个嵌入向量 纯向量工作负载:如果90%的查询都是纯向量相似度搜索,几乎没有过滤 需要完全托管的基础设施:如果你无法自己运维Postgres
但关键是:大多数公司不符合这些情况。大多数公司有:
数百万(不是数十亿)向量 复杂的过滤需求(价格、类别、时间范围等) 现有的PostgreSQL基础设施
对他们来说,pgvector 不是妥协,而是更好的选择。
如何迁移到 pgvector?
如果你已经在使用专用向量数据库,迁移路径很清晰:
defmigrate_from_pinecone_to_pgvector():
"""
从Pinecone迁移到pgvector的步骤
"""
# 1. 导出Pinecone中的所有向量
pinecone_vectors = export_from_pinecone()
# 2. 在Postgres中创建对应表
setup_pgvector_tables()
# 3. 批量导入数据
batch_size = 1000
for i in range(0, len(pinecone_vectors), batch_size):
batch = pinecone_vectors[i:i+batch_size]
import_to_pgvector(batch)
# 4. 创建索引
create_vector_indexes()
# 5. 双写运行一段时间,验证结果一致性
run_parallel_and_compare()
# 6. 切换流量,停用Pinecone
switch_traffic_and_decommission()
行业影响:技术选型的本质
市场已经不再单纯关注“向量数据库”这个概念,因为说实话,谁真的关心数据库类型呢?重要的是:你能否快速构建AI应用,并且不用烧钱就能维护它?
向量数据库厂商看到了这个趋势。Weaviate 现在称自己为“AI原生数据库”,Pinecone 变成了“知识平台”。他们正在向上游移动,添加向量存储之外的功能。
这可能是明智之举。因为在“做一个好数据库”这件事上跟Postgres竞争,是一场必输的战斗。
Postgres有:
30年的持续开发 数百万用户 一个向量数据库无法匹敌的生态系统
最佳实践指南
如果你决定使用 pgvector,以下是最佳实践:
# 1. 选择合适的距离度量
# 根据你的使用场景选择:
# - vector_cosine_ops: 余弦相似度(推荐)
# - vector_l2_ops: 欧几里得距离
# - vector_ip_ops: 内积
# 2. 优化索引参数
cur.execute("""
CREATE INDEX idx_optimized
ON products USING hnsw (embedding vector_cosine_ops)
WITH (m = 16, ef_construction = 64);
""")
# 3. 定期维护索引
cur.execute("VACUUM ANALYZE products;")
# 4. 监控性能
cur.execute("""
SELECT * FROM pg_stat_user_indexes
WHERE indexrelname LIKE '%vector%';
""")
# 5. 备份策略(和普通Postgres表一样)
# pg_dump 完全支持向量列
写在最后
向量数据库的炒作周期已经结束。不是因为向量数据库不好,而是因为对于大多数用例来说,它们没有必要。
PostgreSQL + pgvector 让你能够利用已有的事务、备份和安全功能,同时添加向量能力。这种组合很难被击败。
在你签署下一个 Pinecone 合同之前,问自己三个问题:
我们真的需要另一个数据库吗? 我们的数据规模真的超出了pgvector的能力范围吗? 我们是在解决实际问题,还是仅仅在追赶潮流?
因为很可能,你已经拥有了所需的一切。它一直在你的基础设施中,安静地为你的应用程序提供动力,而其他人却在追逐新的热门技术。
Postgres 刚刚提醒我们:为什么“枯燥”的技术最终会获胜。
你在实际项目中是怎么做向量搜索的?是否也遇到过专用方案过度设计的问题?欢迎在评论区分享你的经验和看法~
🏴☠️宝藏级🏴☠️ 原创公众号『数据STUDIO』内容超级硬核。公众号以Python为核心语言,垂直于数据科学领域,包括可戳👉Python|MySQL|数据分析|数据可视化|机器学习与数据挖掘|爬虫等,从入门到进阶!
长按👇关注- 数据STUDIO -设为星标,干货速递