ServBay 中使用 pgvector PostgreSQL 扩展指南
pgvector
是 PostgreSQL 数据库的一个强大第三方扩展,它为 PostgreSQL 添加了向量数据类型以及高效的向量索引方法,如 IVFFlat 和 HNSW。这使得 PostgreSQL 能够原生支持向量存储和相似度搜索,是构建 AI 应用、推荐系统、图像识别和自然语言处理等需要处理高维向量数据的理想选择。
ServBay 作为一款集成的本地 Web 开发环境,已经预置了 PostgreSQL 及 pgvector
扩展,极大地简化了在本地开发环境中启用和使用向量数据库的过程。本文将详细介绍如何在 ServBay 中利用 pgvector
。
什么是 pgvector?它为何重要?
在许多现代应用场景中,数据不再仅仅是结构化的文本和数字。特别是随着人工智能和机器学习的发展,数据常常被表示为高维向量,也称为“embeddings”。这些向量捕捉了数据的语义信息或特征,例如图片的视觉特征、文本的含义或用户的偏好。
pgvector
扩展使得 PostgreSQL 能够直接存储这些向量,并执行高效的向量相似度搜索(也称为“最近邻搜索”)。这意味着您可以使用熟悉的 SQL 语言来查找与给定向量最相似的数据项,而无需将向量数据存储在单独的向量数据库中,从而简化了技术栈。
前提条件
在开始使用 pgvector
之前,请确保您满足以下条件:
- 已在 macOS 上安装并运行 ServBay。
- 在 ServBay 的“软件包”(Packages)列表中已启用 PostgreSQL 软件包。如果尚未启用,请在 ServBay 应用界面中找到 PostgreSQL 并将其状态设置为“已启用”。
在 ServBay 的 PostgreSQL 中启用 pgvector 扩展
ServBay 已经将 pgvector
扩展文件预置在 PostgreSQL 的安装目录中。您无需手动下载或编译。您只需在您希望使用 pgvector
的特定数据库中启用它即可。
以下是在 ServBay 的 PostgreSQL 数据库中启用 pgvector
的步骤:
连接到 PostgreSQL 数据库: 您可以使用
psql
命令行工具连接到 ServBay 提供的 PostgreSQL 实例。ServBay 的 PostgreSQL 默认配置通常允许本地连接,默认用户可能是postgres
或servbay
,默认端口为5432
。如果您的 ServBay 配置有所不同,请查阅 ServBay 的数据库配置说明。打开终端,使用以下命令连接(请根据您的实际配置调整用户名和数据库名):
bashpsql -U servbay -d your_database_name -h localhost -p 5432
1-U servbay
: 指定用户名为servbay
(或postgres
)。-d your_database_name
: 指定要连接的数据库名称。如果数据库不存在,您可能需要先创建它(例如CREATE DATABASE servbay_demo_db;
)。-h localhost
: 指定主机为本地。-p 5432
: 指定端口为 5432(ServBay 的默认 PostgreSQL 端口)。
创建
vector
扩展: 连接成功后,在psql
提示符下执行以下 SQL 命令来启用pgvector
扩展:sqlCREATE EXTENSION vector;
1如果扩展已存在,此命令可能会返回一个提示,表示它已存在。
验证安装: 您可以通过列出已安装的扩展来验证
pgvector
是否已成功启用:sql\dx
1在输出列表中,您应该能看到名为
vector
的扩展及其版本信息。List of installed extensions Name | Version | Schema | Description ----------+---------+------------+-------------------------------------------------------------- plpgsql | 1.0 | pg_catalog | PL/pgSQL procedural language vector | 0.7.0 | public | vector data type and ivfflat and hnsw access methods (2 rows)
1
2
3
4
5
6(注意:版本号可能因 ServBay 集成的 pgvector 版本而异)
配置与使用 pgvector
启用 pgvector
扩展后,您就可以在数据库中创建和管理向量数据了。
创建包含向量数据的表
首先,您需要创建一个表来存储您的向量数据。pgvector
提供了一个新的数据类型 VECTOR(dimensions)
,其中 dimensions
是向量的维度。
以下是一个示例,创建一个名为 embeddings
的表,用于存储 3 维的向量:
CREATE TABLE embeddings (
id SERIAL PRIMARY KEY,
-- 定义一个 3 维的向量列
vector VECTOR(3)
);
2
3
4
5
接下来,您可以插入一些示例向量数据:
INSERT INTO embeddings (vector) VALUES
('[0.1, 0.2, 0.3]'),
('[0.4, 0.5, 0.6]'),
('[0.7, 0.8, 0.9]'),
('[0.15, 0.25, 0.35]'),
('[0.6, 0.5, 0.4]'); -- 添加更多数据以便后续查询示例更明显
2
3
4
5
6
注意:向量值需要用方括号 []
括起来,元素之间用逗号分隔。
创建向量索引以提高查询性能
对于包含大量向量数据的表,创建索引对于提高向量相似度搜索的性能至关重要。pgvector
支持 IVFFlat 和 HNSW 两种主要的索引类型。选择哪种索引取决于您的具体需求(如查询速度、索引构建时间、内存使用、召回率等)。
- IVFFlat (Inverted File Index with Flat compression): 适用于数据集较大但对召回率要求稍低的场景。构建速度相对较快。
- HNSW (Hierarchical Navigable Small World): 通常提供更高的召回率和更快的查询速度,但索引构建可能更慢,内存使用更高。
以下是为 embeddings
表的 vector
列分别创建 IVFFlat 和 HNSW 索引的示例:
创建 IVFFlat 索引:
sql-- 在创建 IVFFlat 索引之前,通常需要运行 ANALYZE 命令来收集统计信息 ANALYZE embeddings; -- 创建 IVFFlat 索引 -- WITH (lists = 100): 指定倒排列表的数量。这个值需要根据数据集的大小进行调整。 -- lists 越多,索引构建越慢,查询时需要扫描的列表越多(可能慢),但召回率可能更高。 -- 官方建议 lists = sqrt(行数)。 CREATE INDEX idx_ivfflat_vector ON embeddings USING ivfflat (vector) WITH (lists = 100);
1
2
3
4
5
6
7
8创建 HNSW 索引:
sql-- 创建 HNSW 索引 -- WITH (m = 16, ef_construction = 200): HNSW 索引的参数。 -- m: 每个节点的最大连接数。影响索引的连通性和查询效率/内存。 -- ef_construction: 构建索引时使用的搜索范围。影响索引构建时间/内存和最终的索引质量(召回率)。 -- 这些参数需要根据实际数据和性能需求进行调优。 CREATE INDEX idx_hnsw_vector ON embeddings USING hnsw (vector) WITH (m = 16, ef_construction = 200);
1
2
3
4
5
6注意: 索引参数 (如
lists
,m
,ef_construction
) 对索引性能和召回率有显著影响。选择合适的值需要理解您的数据和查询模式,并可能需要进行实验。建议查阅 pgvector 官方文档 了解更详细的参数说明和调优建议。
使用 pgvector 进行向量查询
pgvector
提供了一系列操作符来计算向量之间的距离,从而进行相似度搜索。常用的距离操作符包括:
<->
: L2 距离 (欧几里得距离)。常用于衡量向量之间的直线距离。<#>
: 内积 (Inner Product)。与余弦相似度相关,常用于衡量方向上的相似性。<=>
: 余弦距离 (Cosine Distance)。1 - 余弦相似度
。常用于衡量向量方向的相似性,不受向量长度影响。
以下是一些常用的向量查询示例:
最近邻查询 (Nearest Neighbor Search)
查找与给定查询向量最相似(即距离最小)的向量。通常使用 ORDER BY
结合距离操作符,并使用 LIMIT
限制结果数量。
- 查询与向量
[0.2, 0.3, 0.4]
L2 距离最近的 5 个向量:sqlSELECT id, vector, -- 计算与查询向量的 L2 距离 vector <-> '[0.2, 0.3, 0.4]' AS distance FROM embeddings ORDER BY distance -- 按距离升序排序(距离越小越相似) LIMIT 5;
1
2
3
4
5
6
7
8
9
10
向量相似度查询 (Similarity Search)
与最近邻查询类似,但可能更侧重于展示相似度分数。
- 查询与向量
[0.2, 0.3, 0.4]
余弦距离最近的 5 个向量,并显示距离:sqlSELECT id, vector, -- 计算与查询向量的余弦距离 vector <=> '[0.2, 0.3, 0.4]' AS cosine_distance FROM embeddings ORDER BY cosine_distance -- 按距离升序排序(距离越小越相似) LIMIT 5;
1
2
3
4
5
6
7
8
9
10
可视化向量数据 (可选)
可视化高维向量数据有助于理解数据的分布和聚类情况。对于 2D 或 3D 向量,可以直接绘制散点图。对于更高维度的向量,通常需要使用降维技术(如 PCA 或 t-SNE)将其投影到 2D 或 3D 空间再进行可视化。
这里提供一个使用 Python 和 Matplotlib 库可视化 3 维向量数据的简单示例。
准备 Python 环境: 您需要在 ServBay 环境外部或内部设置一个 Python 环境。如果您使用 ServBay 提供的 Python 软件包,请确保已启用它。您还需要安装连接 PostgreSQL 的库
psycopg2
和绘图库matplotlib
:bash# 如果使用系统默认的 Python 或自行安装的 Python pip install psycopg2 matplotlib # 如果使用 ServBay 的 Python,可能需要通过 ServBay 的命令行工具或直接访问其 bin 目录下的 pip # /Applications/ServBay/软件包/python/bin/pip install psycopg2 matplotlib
1
2
3
4
5请根据您的 Python 环境路径调整
pip
命令。创建 Python 脚本: 创建一个 Python 文件(例如
visualize_vectors.py
),复制以下代码。请根据您的 ServBay PostgreSQL 配置修改连接参数 (dbname
,user
,password
,host
,port
)。pythonimport psycopg2 import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D # 导入用于创建 3D 散点图的模块 # 数据库连接参数 - 请根据您的 ServBay 配置修改 db_params = { "dbname": "your_database_name", # 替换为您的数据库名 "user": "servbay", # 替换为您的 ServBay PostgreSQL 用户名 (通常是 servbay 或 postgres) "password": "", # 替换为您的数据库密码 (本地连接可能为空) "host": "localhost", # ServBay PostgreSQL 通常运行在 localhost "port": "5432" # ServBay PostgreSQL 的默认端口 } conn = None cur = None try: # 连接到 PostgreSQL 数据库 conn = psycopg2.connect(**db_params) cur = conn.cursor() # 查询向量数据 # 注意:psycopg2 默认会将 vector 类型的 '[x, y, z]' 字符串读取为字符串。 # 需要手动解析或依赖 pgvector 较新版本和适配的 psycopg2 驱动来自动处理。 # 这里的示例假设读取到的是字符串,并进行简单解析。 cur.execute("SELECT vector FROM embeddings") vectors_raw = cur.fetchall() # 解析向量字符串,转换为数字列表 vectors = [] for row in vectors_raw: # 去掉方括号,按逗号分割,转换为浮点数 vec_str = row[0].strip('[]') coords = [float(c) for c in vec_str.split(',')] vectors.append(coords) if not vectors: print("未查询到向量数据。") exit() # 提取向量坐标 # 确保所有向量维度一致,这里假设都是 3 维 if any(len(v) != 3 for v in vectors): print("警告:向量维度不一致或不是 3 维,无法绘制 3D 图。") # 可以选择绘制 2D 图或退出 exit() x = [v[0] for v in vectors] y = [v[1] for v in vectors] z = [v[2] for v in vectors] # 创建 3D 散点图 fig = plt.figure() ax = fig.add_subplot(111, projection='3d') ax.scatter(x, y, z) ax.set_xlabel('Dimension 1') ax.set_ylabel('Dimension 2') ax.set_zlabel('Dimension 3') ax.set_title('3D Vector Visualization') plt.show() except psycopg2.Error as e: print(f"数据库连接或查询错误: {e}") except Exception as e: print(f"发生错误: {e}") finally: # 关闭数据库连接 if cur: cur.close() if conn: conn.close()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74运行脚本: 在终端中运行该 Python 脚本:
bashpython visualize_vectors.py
1脚本将连接到您的 PostgreSQL 数据库,读取向量数据,并使用 Matplotlib 绘制一个 3D 散点图窗口。
常见问题 (FAQ)
- 问:我在
\dx
输出中没有看到vector
扩展怎么办? 答:首先确认您已正确执行了CREATE EXTENSION vector;
命令并且没有报错。如果仍然没有,请检查您的 ServBay PostgreSQL 软件包是否已正确安装和启用。pgvector
扩展文件应该位于 PostgreSQL 的share/extension
子目录中。如果文件确实丢失,您可能需要尝试重新安装或更新 ServBay 的 PostgreSQL 软件包。 - 问:连接数据库时提示认证失败怎么办? 答:请检查您在
psql
命令或 Python 脚本中使用的用户名、密码、主机和端口是否与 ServBay 的 PostgreSQL 配置一致。对于本地连接,ServBay 的默认用户通常是servbay
或postgres
,并且可能没有设置密码。 - 问:向量索引参数
lists
,m
,ef_construction
如何选择? 答:这些参数对性能和召回率影响很大,没有一概而论的最佳值。通常需要根据您的数据集大小、维度、查询延迟要求和召回率目标进行实验和调优。pgvector
官方文档提供了更详细的指导和建议。
总结
pgvector
将强大的向量数据库能力引入了成熟稳定的 PostgreSQL 系统,为开发者在本地进行 AI 和向量相关的应用开发提供了便利。ServBay 通过预置 pgvector
扩展,进一步简化了环境搭建过程。
按照本文的指南,您可以在 ServBay 的 PostgreSQL 中轻松启用 pgvector
,创建存储向量的表,利用高效的索引加速查询,并执行各种向量相似度搜索。结合 ServBay 提供的其他开发工具和环境,您可以更高效地构建和测试您的现代 Web 应用和数据密集型项目。