pgvector 向量检索支持
pgvector 是一个 PostgreSQL 扩展,专为 PostgreSQL 提供向量(vector)数据类型和相关操作功能。pgvecotr
与 PostgreSQL 的无缝衔接使得 PostgreSQL 可以支持高效的向量存储、计算和检索,将 PostgreSQL 转变为了一个强大的向量数据库,这令得 PostgreSQL 有了闯入时下最火爆的机器学习与人工智能应用开发领域的资格。
什么是 pgvector
?
pgvector
为 PostgreSQL 提供了一个名为 vector
的数据类型,用于存储和操作高维向量。它特别适用于需要进行向量相似度计算和向量检索的场景,例如推荐系统、图像检索、自然语言处理等领域。
安装 pgvector
pgvector
为 PostgreSQL 添加新的数据类型 vector
的方式是在 PostgreSQL 扩展机制中是通过定义一个新类型以及相关函数实现的。我们需要自行安装 pgvector
扩展。
通过源代码安装 pgvector
要将 pgvector
安装在已存在的 postgresql@15
上,可以遵循以下步骤。
-
获取 pgvector:使用以下命令直接从 GitHub 获取
pgvector
。git clone https://github.com/pgvector/pgvector.git
cd pgvector
git checkout v0.7.4 # 确保使用合适版本 -
设置环境变量:确保使用正确版本的 PostgreSQL。
export PATH="/opt/homebrew/opt/postgresql@15/bin:$PATH"
-
编译并安装:在
pgvector
目录下执行。make install
-
在 PostgreSQL 中创建扩展:
进入 PostgreSQL:
psql postgres
然后创建 扩展:
CREATE EXTENSION IF NOT EXISTS vector;
这样,pgvector
应该已成功安装在你的 postgresql@15
上。如果遇到错误,请检查输出信息并确保已满足所有依赖项。
vector
类型支持
-
数据类型定义:
pgvector
在 PostgreSQL 中自定 义了一个定长的浮点(float4)数组类型vector(N)
(通过 C 扩展编写),并在 PostgreSQL 中注册。 -
存储格式:向量数据在数据库内部存储为一个定长的浮点数组,这些数组被组织成紧凑的二进制格式以便高效存储和检索。这个存储结构排布紧凑,使得向量数据操作更为高效。
typedef struct
{
int32 length; // 向量长度
float4 values[]; // 存储浮点数组
} Vector;
向量相似度计算
pgvector
实现了多种常见的向量相似度计算方法,如欧氏距离、余弦相似度和内积。每种方法都被实现为一个 PostgreSQL 函数。
-
欧氏距离:欧氏距离计算会遍历两个向量的每个维度,计算平方和,再取平方根。
float euclidean_distance(const float *a, const float *b, int length) {
float sum = 0.0;
for (int i = 0; i < length; i++) {
float diff = a[i] - b[i];
sum += diff * diff;
}
return sqrt(sum);
} -
余弦相似度:余弦相似度计算两个向量的点积,并归一化向量以计算余弦角度。
float cosine_similarity(const float *a, const float *b, int length) {
float dot_product = 0.0;
float norm_a = 0.0;
float norm_b = 0.0;
for (int i = 0; i < length; i++) {
dot_product += a[i] * b[i];
norm_a += a[i] * a[i];
norm_b += b[i] * b[i];
}
return dot_product / (sqrt(norm_a) * sqrt(norm_b));
} -
内积:内积计算两个向量对应维度的乘积之和。
float dot_product(const float *a, const float *b, int length) {
float result = 0.0;
for (int i = 0; i < length; i++) {
result += a[i] * b[i];
}
return result;
}
向量索引优化
pgvector
支持近似和精确查询。为了提升向量检索的效率,pgvector
支持了多种索引算法,其中包括 HNSW
(Hierarchical Navigable Small World)和 IVFFlat
(Inverted File with Flat Quantization)。这些索引结构可以高效处理高维向量数据。
-
HNSW:Hierarchical Navigable Small World,是一种基于图的索引结构,构建了一个多层次的导航图。高层次的图具备更少的节点,主要用于加速搜索过程。HNSW 使用随机跳跃的方式进行邻近搜索,通过在不同层的图结构中进行搜索,快速找到相似向量。在插入新向量时,会将其加入到不同层,逐级构建连接。相比于传统的 KNN 方法,HNSW 在高维数据中表现出更好的查询性能和准确性,尤其在动态数据更新时。
CREATE INDEX ON items USING hnsw (embedding vector_l2_ops);
-
IVFFlat:Inverted File with Flat Quantization,是一种基于聚类的索引方法,先将向量数据集划分为多个簇,然后对每个簇使用平面(Flat)来存储向量。在构建索引时,首先使用聚类算法(如 K-means)对数据进行簇划分。在查询时,首先确定查询向量所属的簇,然后在该簇内进行线性搜索,以找到近似最近邻。在处理特别大的数据集时,IVFFlat 可以显著减少搜索空间,提高查询速度。
CREATE INDEX ON items USING ivfflat (embedding) WITH (lists=100);
lists
: 设置聚类的数量,较高的lists
通常会提升查询精度但也会增加索引创建和查询时间。可以根据数据规模和查询性能要求进行调整。