PG Vector 入门教程
项目介绍
PG Vector 是 PostgreSQL 的一个开源扩展,专注于在PostgreSQL数据库中存储和查询向量数据。它提供了高效的向量相似度搜索功能,使PostgreSQL能够处理机器学习和AI应用中的向量数据。
主要功能
- 向量存储:在PostgreSQL中存储向量数据
- 向量相似度搜索:支持余弦相似度、欧氏距离和曼哈顿距离等多种相似度计算
- 索引支持:为向量数据创建索引,提高查询性能
- 与PostgreSQL集成:无缝集成到PostgreSQL生态系统
- 多语言支持:支持多种编程语言的客户端库
项目特点
- 开源免费:完全开源,可自由使用和定制
- 高性能:针对向量搜索进行了优化
- 易于集成:与PostgreSQL无缝集成
- 可靠性:基于PostgreSQL的稳定性和可靠性
- 灵活性:支持多种向量相似度计算方法
安装与配置
安装步骤
- 安装PostgreSQL(如果尚未安装)
# Ubuntu/Debian
sudo apt update
sudo apt install postgresql postgresql-contrib
# CentOS/RHEL
sudo yum install postgresql-server postgresql-contrib
sudo postgresql-setup --initdb
sudo systemctl start postgresql
# macOS
brew install postgresql
brew services start postgresql- 安装PG Vector扩展
# 从源码编译安装
git clone https://github.com/pgvector/pgvector.git
cd pgvector
make
make install
# 或者使用包管理器(某些系统)
sudo apt install postgresql-15-pgvector- 启用PG Vector扩展
-- 连接到PostgreSQL
psql -U postgres
-- 创建扩展
CREATE EXTENSION vector;基本配置
- 创建包含向量列的表
-- 创建产品表,包含向量列
CREATE TABLE products (
id SERIAL PRIMARY KEY,
name TEXT NOT NULL,
description TEXT,
price DECIMAL(10, 2),
embedding VECTOR(1536) -- 1536维向量
);- 为向量列创建索引
-- 创建余弦相似度索引
CREATE INDEX products_embedding_idx ON products USING ivfflat (embedding vector_cosine_ops) WITH (lists = 100);
-- 或者创建欧氏距离索引
CREATE INDEX products_embedding_idx ON products USING ivfflat (embedding vector_l2_ops) WITH (lists = 100);核心概念
1. 向量类型(Vector Type)
PG Vector提供了vector数据类型,用于存储向量数据。向量的维度在创建表时指定。
2. 相似度函数(Similarity Functions)
vector_cosine_distance(a, b):计算两个向量的余弦距离vector_l2_distance(a, b):计算两个向量的欧氏距离vector_dot_product(a, b):计算两个向量的点积
3. 操作符(Operators)
<->:计算欧氏距离<#>:计算负点积(用于排序)<=>:计算余弦距离
4. 索引(Index)
PG Vector支持使用ivfflat索引类型为向量列创建索引,提高查询性能。
5. 列表参数(Lists Parameter)
创建索引时的lists参数控制索引的粒度,影响查询性能和内存使用。
基本使用
插入向量数据
-- 插入产品数据
INSERT INTO products (name, description, price, embedding)
VALUES
('Smartphone', 'A high-end smartphone with advanced features', 999.99, '[0.1, 0.2, 0.3, ..., 0.9]'),
('Laptop', 'A powerful laptop for gaming and productivity', 1499.99, '[0.2, 0.3, 0.4, ..., 0.8]'),
('Headphones', 'Noise-canceling headphones with excellent sound quality', 299.99, '[0.3, 0.4, 0.5, ..., 0.7]');向量相似度搜索
-- 余弦相似度搜索
SELECT id, name, description, price, embedding <=> '[0.15, 0.25, 0.35, ..., 0.85]' AS similarity
FROM products
ORDER BY similarity ASC
LIMIT 3;
-- 欧氏距离搜索
SELECT id, name, description, price, embedding <-> '[0.15, 0.25, 0.35, ..., 0.85]' AS distance
FROM products
ORDER BY distance ASC
LIMIT 3;
-- 点积搜索
SELECT id, name, description, price, vector_dot_product(embedding, '[0.15, 0.25, 0.35, ..., 0.85]') AS dot_product
FROM products
ORDER BY dot_product DESC
LIMIT 3;更新和删除向量数据
-- 更新向量数据
UPDATE products
SET embedding = '[0.12, 0.22, 0.32, ..., 0.92]'
WHERE id = 1;
-- 删除向量数据
DELETE FROM products
WHERE id = 1;高级特性
1. 批量插入向量数据
import psycopg2
import numpy as np
# 连接到PostgreSQL
conn = psycopg2.connect(
host="localhost",
database="postgres",
user="postgres",
password="your-password"
)
cur = conn.cursor()
# 生成随机向量
def generate_vector(dim):
return np.random.rand(dim).tolist()
# 批量插入数据
products = []
for i in range(1000):
name = f"Product {i}"
description = f"Description for product {i}"
price = 100 + i * 10
embedding = generate_vector(1536)
products.append((name, description, price, embedding))
# 执行批量插入
cur.executemany(
"INSERT INTO products (name, description, price, embedding) VALUES (%s, %s, %s, %s)",
products
)
conn.commit()
cur.close()
conn.close()2. 使用索引提高性能
-- 创建索引(在数据插入后)
CREATE INDEX products_embedding_idx ON products USING ivfflat (embedding vector_cosine_ops) WITH (lists = 100);
-- 验证索引是否使用
EXPLAIN ANALYZE
SELECT id, name, description, price, embedding <=> '[0.15, 0.25, 0.35, ..., 0.85]' AS similarity
FROM products
ORDER BY similarity ASC
LIMIT 3;3. 结合其他PostgreSQL功能
-- 结合全文搜索
CREATE TABLE documents (
id SERIAL PRIMARY KEY,
title TEXT NOT NULL,
content TEXT,
embedding VECTOR(1536)
);
-- 创建全文搜索索引
CREATE INDEX documents_content_idx ON documents USING gin(to_tsvector('english', content));
-- 结合向量搜索和全文搜索
SELECT id, title, content, embedding <=> '[0.1, 0.2, 0.3, ..., 0.9]' AS similarity
FROM documents
WHERE to_tsvector('english', content) @@ to_tsquery('english', 'machine learning')
ORDER BY similarity ASC
LIMIT 5;实际应用案例
案例1:产品推荐系统
场景:基于用户偏好推荐相关产品。
实现步骤:
- 创建产品表和用户表
- 为产品和用户生成向量嵌入
- 使用向量相似度计算推荐产品
- 部署推荐系统
示例:
-- 创建用户表
CREATE TABLE users (
id SERIAL PRIMARY KEY,
name TEXT NOT NULL,
preferences TEXT,
embedding VECTOR(1536)
);
-- 插入用户数据
INSERT INTO users (name, preferences, embedding)
VALUES ('John Doe', 'I like high-quality electronics with good sound quality', '[0.1, 0.2, 0.3, ..., 0.9]');
-- 基于用户向量推荐产品
SELECT p.id, p.name, p.description, p.price, p.embedding <=> u.embedding AS similarity
FROM products p, users u
WHERE u.id = 1
ORDER BY similarity ASC
LIMIT 3;案例2:语义搜索引擎
场景:构建基于语义的文档搜索引擎。
实现步骤:
- 创建文档表
- 为文档生成向量嵌入
- 实现语义搜索接口
- 部署搜索引擎
示例:
import psycopg2
from sentence_transformers import SentenceTransformer
# 加载嵌入模型
model = SentenceTransformer('all-MiniLM-L6-v2')
# 连接到PostgreSQL
conn = psycopg2.connect(
host="localhost",
database="postgres",
user="postgres",
password="your-password"
)
cur = conn.cursor()
# 创建文档表
cur.execute("""
CREATE TABLE IF NOT EXISTS documents (
id SERIAL PRIMARY KEY,
title TEXT NOT NULL,
content TEXT,
embedding VECTOR(384)
);
""")
# 插入文档数据
documents = [
("Introduction to Machine Learning", "Machine learning is a subset of artificial intelligence that focuses on building systems that can learn from data."),
("Deep Learning Fundamentals", "Deep learning is a branch of machine learning that uses neural networks with many layers."),
("Natural Language Processing", "Natural language processing is a field of AI that focuses on the interaction between computers and human language.")
]
for title, content in documents:
# 生成嵌入
embedding = model.encode(content).tolist()
# 插入数据
cur.execute(
"INSERT INTO documents (title, content, embedding) VALUES (%s, %s, %s)",
(title, content, embedding)
)
conn.commit()
# 语义搜索
query = "What is deep learning?"
query_embedding = model.encode(query).tolist()
cur.execute("""
SELECT id, title, content, embedding <=> %s AS similarity
FROM documents
ORDER BY similarity ASC
LIMIT 2;
""", (query_embedding,))
results = cur.fetchall()
print("Search results:")
for row in results:
id, title, content, similarity = row
print(f"Title: {title}")
print(f"Content: {content[:100]}...")
print(f"Similarity: {similarity}")
print()
cur.close()
conn.close()案例3:图像相似性搜索
场景:基于图像相似性搜索相关图片。
实现步骤:
- 创建图像表
- 为图像生成向量嵌入
- 实现图像相似性搜索接口
- 部署图像搜索系统
示例:
import psycopg2
from PIL import Image
import numpy as np
from tensorflow.keras.applications.resnet50 import ResNet50, preprocess_input
from tensorflow.keras.preprocessing import image
# 加载图像嵌入模型
model = ResNet50(weights='imagenet', include_top=False, pooling='avg')
# 连接到PostgreSQL
conn = psycopg2.connect(
host="localhost",
database="postgres",
user="postgres",
password="your-password"
)
cur = conn.cursor()
# 创建图像表
cur.execute("""
CREATE TABLE IF NOT EXISTS images (
id SERIAL PRIMARY KEY,
name TEXT NOT NULL,
description TEXT,
embedding VECTOR(2048)
);
""")
# 生成图像嵌入
def get_image_embedding(img_path):
img = image.load_img(img_path, target_size=(224, 224))
x = image.img_to_array(img)
x = np.expand_dims(x, axis=0)
x = preprocess_input(x)
embedding = model.predict(x)[0].tolist()
return embedding
# 插入图像数据
images = [
("cat.jpg", "A photo of a cat"),
("dog.jpg", "A photo of a dog"),
("car.jpg", "A photo of a car")
]
for name, description in images:
# 生成嵌入
embedding = get_image_embedding(name)
# 插入数据
cur.execute(
"INSERT INTO images (name, description, embedding) VALUES (%s, %s, %s)",
(name, description, embedding)
)
conn.commit()
# 图像相似性搜索
query_image = "query_cat.jpg"
query_embedding = get_image_embedding(query_image)
cur.execute("""
SELECT id, name, description, embedding <-> %s AS distance
FROM images
ORDER BY distance ASC
LIMIT 2;
""", (query_embedding,))
results = cur.fetchall()
print("Similar images:")
for row in results:
id, name, description, distance = row
print(f"Name: {name}")
print(f"Description: {description}")
print(f"Distance: {distance}")
print()
cur.close()
conn.close()总结与展望
PG Vector作为PostgreSQL的一个强大扩展,为在PostgreSQL中存储和查询向量数据提供了全面的工具和功能。通过本文的介绍,你应该已经了解了PG Vector的核心概念、基本使用方法和高级特性。
关键优势
- 开源免费,可自由使用和定制
- 高性能,针对向量搜索进行了优化
- 易于集成,与PostgreSQL无缝集成
- 可靠性,基于PostgreSQL的稳定性和可靠性
- 灵活性,支持多种向量相似度计算方法
应用前景
- 产品推荐系统
- 语义搜索引擎
- 图像相似性搜索
- 自然语言处理应用
- 个性化推荐系统
未来发展
PG Vector团队持续改进扩展,未来可能会:
- 支持更多的向量相似度计算方法
- 优化索引性能,支持更大规模的向量数据
- 提供更多的向量处理函数
- 增强与机器学习框架的集成
- 提供更多行业特定的解决方案
通过不断学习和实践,你可以利用PG Vector构建更加智能、高效的向量搜索和推荐系统,为各种场景提供有价值的AI解决方案。