向量数据

PostgreSQL 扩展:使用 pgvector 将 PostgreSQL 变成向量数据库

A visual representation of a vector, represented in a graph.

作者:Matvey AryeAvthar Sewrathan

pgvector 是一个 PostgreSQL 扩展,它提供了用于处理高维空间中向量的强大功能。它引入了专门的数据类型、运算符和函数,使您能够直接在 PostgreSQL 数据库中高效地存储、操作和分析向量数据。

Timescale 于 2023 年 5 月开始支持该扩展,我们已经用它做了一些很酷的事情。使用它将允许您查询和分析存储在 Timescale 中的其他结构化数据 alongside 的向量数据。如果您正在寻找向量数据库,请知道 PostgreSQL 就是您所需要的。

对于 AI 和向量数据,Timescale Cloud 平台 包含 pgvector 扩展以及 Timescale 团队开发的两个新的开源 PostgreSQL 扩展:pgai,它将更多 AI 工作流引入 PostgreSQL,使开发人员更容易构建搜索和检索增强生成 (RAG) 应用程序;以及 pgvectorscale,它使开发人员能够构建更可扩展的 AI 应用程序,具有更高的性能嵌入搜索和经济高效的存储。您可以在本文中了解有关这两个扩展的更多信息.

让我们逐步了解主要功能和用例。我们还将介绍在 TimescaleDB 中分析关系数据和时间序列数据的一些示例。

什么是向量?

向量是指多维空间中数据点的数学表示。它们通常是数值数组或列表,用于捕捉实体的基本特征或属性。在机器学习和数据科学中,向量以一种可以实现高效计算和分析的方式编码信息。

向量可以表示单词、句子或文档,从而实现语义搜索,即使确切的单词不同,也能识别出相似的含义。这可用于查找具有相似内容的文档或根据文本的上下文回答查询。通过将视觉数据转换为向量,向量数据库(例如带有 pgvector 扩展的 PostgreSQL)可以实现对相似图像或视频的搜索。这在人脸识别、目标检测和基于内容的图像检索等应用中很有用。

在时间序列和其他类型的数据中,向量可以表示正常的行为模式,通过识别与正常行为显著偏差的向量来检测异常。

了解 pgvector:启用向量操作

pgvector 扩展是用于存储、修改和查询向量的强大工具。此功能支持相似性和语义搜索、检索增强生成、图像搜索、推荐系统、自然语言处理 (NLP) 和计算机视觉等应用程序。

以下是 pgvector 的一些关键功能和用例

  • 向量存储:pgvector 扩展允许您将高维向量直接存储在 PostgreSQL 表中。它提供了一个专用于向量表示的数据类型,可以高效地存储和检索向量数据。

  • 相似性搜索:使用 pgvector,您可以根据向量相似性度量(例如余弦相似度或欧几里得距离)执行相似性搜索。搜索类似的向量有助于实现基于内容的推荐系统、k 最近邻搜索和聚类等应用程序。

  • 语义搜索:大型语言模型 (LLM) 嵌入是一种从其他类型数据(例如文本、图像等)创建向量的方法。这些嵌入表示基础数据的含义。因此,使用相似性搜索查找类似的向量将返回具有相似语义含义或内容的数据,从而有效地识别共享共同主题或主题的数据点,而与它们的原始格式(文本、图像等)无关。

  • 自然语言处理 (NLP) 和文本分析:向量嵌入非常强大,因为它们捕获了文本的潜在含义。像词嵌入或文档嵌入这样的技术使您能够捕获文本中表达的想法。然后,您可以对文本数据执行基于向量的操作,例如相似性搜索、聚类或分类。

  • 计算机视觉:pgvector 扩展可以处理图像的向量表示,并支持基于相似性的图像搜索。您可以使用卷积神经网络 (CNN) 或图像嵌入将图像转换为向量表示。这些功能使您能够在数据库中执行基于内容的图像检索、图像相似性匹配、对象识别和图像聚类。

A visual representation of a vector, represented in a graph.

Pgvector 存储代表语义含义的向量。因此,在意义上相似的物体在向量空间中会“更靠近”。这使得人们在搜索 SUV 时能够找到汽车和卡车,而不是西瓜和苹果,即使 SUV 和卡车是不同的词。

使用 pgvector 处理向量数据

通过利用 pgvector 扩展,开发人员可以高效地存储和查询 PostgreSQL 中的向量数据,从而更容易使用 LLM 构建生成式 AI 应用程序,以及需要相似性搜索、推荐系统、NLP 和其他涉及向量操作的任务的 AI 应用程序。

  • 安装:您可以在 Timescale 的云数据库服务或自托管的 PostgreSQL 实例上使用 pgvector

  • 向量数据类型:pgvector 引入了一种称为 vector 的新数据类型,它表示高维向量。您可以在数据库表中定义 vector-type 列来存储向量数据。例如,您可以在名为 documents 的表中使用 embedding 列(类型为 vector)来存储每个文档的 LLM 嵌入作为向量。

    CREATE TABLE documents (
     id BIGINT PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
     content TEXT,
     author_id BIGINT,
     embedding VECTOR(1538)
    );
    
    

  • 索引和向量搜索: pgvector 提供针对向量数据近似最近邻搜索优化的索引机制。可以使用 CREATE INDEX 命令在向量列上创建索引,指定 hnsw 索引类型和 vector_cosine_ops 运算符类。这可以使用余弦距离相似度指标对向量数据进行快速相似度搜索。然后可以使用 <=> 运算符在查询中执行相似度搜索。

    CREATE INDEX ON documents USING hnsw (embedding vector_cosine_ops);
    
    --find the closest 5 elements to a given query
    SELECT * FROM documents ORDER BY embedding <=> '[10.5, 11.0,...]' LIMIT 5;.
    
    

  • 向量函数: pgvector 有一组内置函数来操作和执行向量数据的运算。这些函数允许您计算向量相似性,执行向量运算等等。例如,可以使用 cosine_distance 函数计算两个向量之间的余弦相似度。其他有用的函数是 vector_norm() 用于获取欧几里得范数,以及 vector_dims() 用于确定向量包含多少个维度。

  • 向量聚合: pgvector 有 avg(vector)sum(vector) 聚合函数,用于计算向量上的分析。

  • 与其他 PostgreSQL 功能的集成: pgvector 与 PostgreSQL 的其他功能无缝集成,例如事务管理、查询优化和安全性。这种集成使您能够利用 PostgreSQL 的强大功能来完成复杂的数据处理任务。将 pgvector 数据与其他数据类型(如关系型、时间序列和地理空间数据)进行连接,是丰富向量查询数据的强大方法。例如,您可以返回通过相似性搜索找到的文档的作者信息。

WITH matching_docs as (
  --find 5 closest matches 
  SELECT * 
  FROM documents 
  ORDER BY embedding <=> '[10.5, 11.0,...]' 
  LIMIT 5
)
SELECT d.content, a.first_name, a.last_name
FROM matching_docs d 
INNER JOIN author a ON (a.id = d.author_id).

为什么要将 pgvector 与 Timescale 一起使用?

Timescale 是为时间序列数据、事件和分析而设计的 PostgreSQL++。它为存储、检索和 分析大量时间序列数据 提供了坚实的基础,这得益于其基于时间的时间聚合、 数据保留策略 以及 超表连续聚合 等功能。

许多现实世界的 AI 应用程序都有检索或分析需求,这些需求同时包括向量数据和相似性搜索的时间方面。一些此类工作负载的示例(其中时间至关重要)包括新闻、法律文件和财务报表的嵌入。

在这种情况下,用户通常希望在特定时间范围内找到类似的文档。另一个常见用途是时间加权,其中用户可能不使用严格的时间过滤器,但仍然更喜欢更新或更旧的数据。对于此类工作负载,Timescale 可以显着提高数据摄取和查询速度,这得益于 超表 — 表的自动基于时间的分区。Timescale 特别擅长优化根据时间过滤数据的查询,使这些查询能够更有效地运行。

此外,复杂系统使用许多不同类型的数据工作负载,例如时间序列、事件、历史、实时和结构化关系数据。将这些不同类型的数据存储在一个数据库中具有许多操作优势。它通过将备份、恢复和安全等任务合并到一个系统中来简化操作管理,从而降低复杂性。

此外,使用连接组合不同的数据类型可以实现更复杂的数据分析。通过将所有内容都保存在同一个数据库中,您可以避免数据孤岛,加快工作流程,并为您的用户提供更快的洞察力。

如何在 Timescale 中使用 pgvector

步骤 1. 在 PostgreSQL 实例上设置 pgvectortimescaledb。您可以通过 Timescale 上的云托管数据库(推荐)或自托管实例来执行此操作。

然后,您需要执行以下操作

CREATE EXTENSION vector;
CREATE EXTENSION timescaledb;

步骤 2. 创建包含向量列的 Timescale 超表:在您的数据库中创建一个常规表,它将作为超表的基础。使用 TimescaleDB 提供的 create_hypertable 函数将该表转换为超表。指定时间列和其他相关选项。

CREATE TABLE documents (
  id BIGINT GENERATED ALWAYS AS IDENTITY,
  created_at TIMESTAMPTZ,
  content TEXT,
  embedding VECTOR(1538)
);

SELECT create_hypertable('documents', 'created_at');

步骤 3. 将向量数据插入超表:使用常规的 SQL INSERT 语句将数据插入超表,包括指定向量列中的向量数据。确保向量数据采用 pgvector 预期格式。您需要从嵌入模型(例如, OpenAI 文本嵌入-3 模型 或,如果您愿意,开源 句子转换器)中获取向量表示。

INSERT INTO documents (created_at, content,embedding)
VALUES ('2023-06-01 00:00:00', 'the quick', '[1,2,3]'),
       ('2023-06-02 00:00:00', 'brown fox', '[4,5,6]'),
       ('2023-06-03 00:00:00', 'jumped over' '[7,8,9]');

步骤 4. 查询和分析向量数据。使用 SQL 查询对存储在超表中的向量数据执行各种操作。您可以将 TimescaleDB 的时间序列函数与 pgvector 的向量函数结合起来进行分析和查询。

您可以执行的查询示例包括

  • 相似度搜索:使用 pgvector 提供的 <=> 运算符查找与给定查询向量相似的向量。将其与其他列(如时间)上的过滤器结合起来。

  • 聚合和分组:使用 TimescaleDB 的时间序列聚合函数对时间间隔或其他维度上的向量数据进行聚合。

  • 过滤和选择:使用常规 SQL 过滤器和条件根据特定标准选择特定向量数据。

-- Similarity search
SELECT *
FROM documents
ORDER BY data <=> '[1,2,3]'::vector
LIMIT 5;

-- Similarity search filtered by time
SELECT *
FROM documents
WHERE time >= '2023-06-02 00:00:00' AND time < '2023-06-03 00:00:00'
ORDER BY data <=> '[1,2,3]'::vector
LIMIT 5;

-- Aggregation and grouping,
SELECT time_bucket('30 day', created_at) AS day, length(data) AS avg_data_length
FROM sensor_data
GROUP BY day
ORDER BY day;

-- Filtering and selection
SELECT *
FROM sensor_data
WHERE time >= '2023-06-02 00:00:00' AND time < '2023-06-03 00:00:00';

步骤 6. 优化和性能。根据数据的规模和复杂性,考虑通过使用 CREATE INDEX 命令(使用 hnsw 索引类型和 vector_cosine_ops 运算符类)在 vector 列上创建索引,优化查询的性能。根据您的工作负载和资源需求调整 TimescaleDB 和 PostgreSQL 的配置参数,以实现最佳性能。

CREATE INDEX ON documents USING hnsw (embedding vector_cosine_ops);

下一步

想要详细了解 pgvector 以及如何使用它?请阅读以下资源

在成熟的生产就绪型云 PostgreSQL 平台上开始使用 pgvector: 立即注册 Timescale(并获得 90 天免费试用)。