pgai迁移指南:从传统向量数据库平滑过渡到PostgreSQL

pgai迁移指南:从传统向量数据库平滑过渡到PostgreSQL

【免费下载链接】pgai Helper functions for AI workflows 【免费下载链接】pgai 项目地址: https://gitcode.com/GitHub_Trending/pg/pgai

你是否正面临向量数据库管理复杂、维护成本高、与现有数据架构脱节的困境?是否在寻找一种能将向量处理能力与关系型数据库完美融合的解决方案?pgai Vectorizer为你提供从传统向量数据库无缝迁移到PostgreSQL的完整路径,让你在熟悉的PostgreSQL环境中高效管理向量数据,消除数据孤岛,简化技术栈。本文将详细介绍迁移的核心优势、准备工作、实施步骤、常见问题及最佳实践,帮助你平稳完成过渡。

为什么选择迁移到PostgreSQL+pgai

传统向量数据库通常作为独立系统存在,需要单独部署、维护和扩展,导致数据分散在多个系统中,增加了架构复杂性和运维成本。而pgai Vectorizer将向量处理能力直接集成到PostgreSQL中,带来多方面优势:

  • 架构简化:无需维护独立的向量数据库,减少系统组件和数据流动环节,降低架构复杂度和潜在故障点。
  • 数据一致性:向量数据与业务数据存储在同一数据库中,可通过事务保证数据一致性,避免跨系统数据同步问题。
  • 降低成本:省去独立向量数据库的许可费用和硬件资源投入,充分利用现有PostgreSQL基础设施。
  • 丰富功能:PostgreSQL强大的查询能力、事务支持、扩展生态系统与pgai的向量处理功能相结合,满足复杂业务场景需求。

pgai Vectorizer采用声明式方法管理向量嵌入,将其视为类似索引的数据库功能,自动处理向量的生成、更新和同步,大幅简化开发流程。其核心功能包括自动为指定文本列生成和维护可搜索的嵌入表、保持嵌入与源数据的异步同步、提供便捷的视图将基表与嵌入无缝连接等。

迁移准备:评估与环境配置

迁移前需对现有向量数据库使用情况进行全面评估,包括数据量、嵌入维度、查询模式、性能要求等,以便制定合适的迁移策略。同时,确保目标PostgreSQL环境满足以下要求:

  • PostgreSQL 14或更高版本,推荐使用PostgreSQL 16以获得最佳性能和兼容性。
  • 已安装pgai Python库,版本需大于0.10.0。旧版本的pgai Vectorizer使用扩展提供功能,而新版本已将向量izer代码整合到pgai Python库中,简化了安装和升级流程。
  • 根据使用的嵌入服务提供商(如OpenAI、Ollama、Voyage AI等),准备相应的API密钥。

环境配置步骤

  1. 安装pgai Python库

    pip install -U pgai
    

    或通过项目依赖文件(如requirements.txt)进行安装。

  2. 配置API密钥

    • Timescale Cloud用户:在Timescale Console > Project Settings中,点击"AI Model API Keys",添加相应的API密钥。API密钥将安全存储在Timescale Cloud中,而非数据库内。
    • 自托管PostgreSQL用户:设置与API密钥名称对应的环境变量,例如使用OpenAI时:
      export OPENAI_API_KEY="你的OpenAI API密钥"
      
  3. 验证环境: 运行以下命令,确保pgai已正确安装并可连接到数据库:

    pgai install -d "postgresql://用户名:密码@主机:端口/数据库名"
    

迁移实施:从扩展到Python库的平滑过渡

如果你之前使用的是pgai扩展版本(ai扩展版本<0.10.0或pgai Python库版本<0.10.0),迁移到新版本的步骤如下:

1. 升级扩展(如已安装)

如果已安装旧版ai扩展,需先升级以分离向量izer目录表和函数,使其保留在数据库的ai模式中,确保向量izer功能继续正常工作:

ALTER EXTENSION ai UPDATE TO '0.10.1';

2. 升级pgai Python库

确保pgai Python库版本大于0.10.0:

pip install -U pgai

3. 使用Python库管理向量izer

通过pgai Python库或CLI管理向量izer,使用以下命令安装必要的数据库对象:

pgai install -d "postgresql://用户名:密码@主机:端口/数据库名"

详细工作流程可参考向量izer API参考

4. 可选:移除扩展

如果你不使用Timescale Cloud且不需要pgai的模型调用功能,可以移除ai扩展:

DROP EXTENSION ai;

[!WARNING] 如果使用Timescale Cloud,需要保留扩展以使用向量izer云函数。

核心API变化:适应新的向量izer配置方式

迁移到pgai Python库后,create_vectorizer API发生了一些变化,主要包括新增的loadingdestination顶级参数,以提供更大的灵活性。

新旧API对比

旧版扩展API(示例)

SELECT ai.create_vectorizer(
    'blog'::regclass,
    name => 'blog_embeddings',
    column => 'contents',
    embedding => ai.embedding_openai('text-embedding-ada-002', 1536),
    target_table => 'blog_contents_embeddings'
);

新版Python库API(示例)

SELECT ai.create_vectorizer(
    'blog'::regclass,
    name => 'blog_embeddings',
    loading => ai.loading_column('contents'),  -- 新增:指定数据加载方式
    embedding => ai.embedding_openai('text-embedding-3-small', 1536),
    destination => ai.destination_table('blog_contents_embeddings')  -- 新增:指定嵌入存储目标
);

关键变化详解

  • loading参数:必需的顶级参数,指定如何加载数据到向量izer。除了从列加载数据(ai.loading_column()),还支持从文件加载数据(ai.loading_uri())。例如:

    loading => ai.loading_uri('s3://bucket/path/to/documents/*')
    
  • destination参数:必需的顶级参数,指定嵌入的存储位置。支持两种存储方式:

    • 表目标:使用ai.destination_table()将嵌入存储在单独的表中,这是旧版的默认行为。
    • 列目标:使用ai.destination_column()将嵌入存储在源表的特定列中,适用于无需分块的短文本场景。
  • 分块函数变化ai.chunking_character_text_splitterai.chunking_recursive_character_text_splitter不再接受chunk_column参数,该参数现在通过loading => ai.loading_column()指定。

数据迁移:从外部向量数据库导入数据

如果从其他外部向量数据库(如 Pinecone、Weaviate 等)迁移,可通过以下步骤将向量数据导入到PostgreSQL:

1. 导出外部向量数据库数据

根据源向量数据库的提供的工具或API,将向量数据导出为结构化格式(如CSV、JSON等),确保包含原始文本、向量嵌入及相关元数据。

2. 创建目标表结构

在PostgreSQL中创建源数据表和嵌入存储表。例如,对于博客数据:

-- 创建源数据表
CREATE TABLE blog(
    id        SERIAL PRIMARY KEY,
    title     TEXT,
    authors   TEXT,
    contents  TEXT,
    metadata  JSONB 
);

-- 创建嵌入存储表(如果使用表目标方式)
CREATE TABLE blog_contents_embeddings_store(
    embedding_uuid UUID NOT NULL PRIMARY KEY DEFAULT gen_random_uuid(),     
    id INT,  -- 关联到blog表的主键
    chunk_seq INT NOT NULL, 
    chunk TEXT NOT NULL,
    embedding vector(768) NOT NULL,  -- 嵌入维度需与源数据匹配
    UNIQUE (id, chunk_seq),
    FOREIGN KEY (id) REFERENCES public.blog(id) ON DELETE CASCADE
);

3. 导入数据到PostgreSQL

使用COPY命令或pg_dump/pg_restore等工具将导出的源数据导入到PostgreSQL的源表中。对于向量嵌入数据,可直接插入到创建的嵌入存储表。

4. 配置向量izer同步

创建向量izer以确保后续数据变更能自动同步嵌入:

SELECT ai.create_vectorizer(
    'blog'::regclass,
    name => 'blog_embeddings',
    loading => ai.loading_column('contents'),
    embedding => ai.embedding_ollama('nomic-embed-text', 768),  -- 与源嵌入模型匹配
    destination => ai.destination_table('blog_contents_embeddings_store'),
    formatting => ai.formatting_python_template('$title - by $authors - $chunk')  -- 注入上下文
);

验证与优化:确保迁移后系统平稳运行

迁移完成后,需进行全面验证以确保系统功能正常、性能达标。同时,可根据实际需求进行优化。

验证步骤

  1. 检查向量数据完整性: 查询嵌入视图,确认嵌入数据与源数据正确关联:

    SELECT b.id, b.title, be.chunk, be.embedding 
    FROM blog b
    JOIN blog_contents_embeddings be ON b.id = be.id
    LIMIT 10;
    
  2. 测试语义搜索功能: 使用示例查询测试语义搜索是否正常工作:

    -- 生成查询嵌入(以Ollama为例)
    SELECT ai.ollama_embed('nomic-embed-text', '人工智能在数据库中的应用') AS query_embedding \gset
    
    -- 执行语义搜索
    SELECT 
       chunk,
       embedding <=> :'query_embedding' AS distance
    FROM blog_contents_embeddings
    ORDER BY distance
    LIMIT 5;
    
  3. 监控向量izer状态: 通过ai.vectorizer_status视图监控向量izer的运行状态和待处理项:

    SELECT * FROM ai.vectorizer_status;
    

    示例输出: | id | source_table | target_table | view | pending_items | |----|--------------|--------------------------------------|---------------------------------|---------------| | 1 | public.blog | public.blog_contents_embeddings_store | public.blog_contents_embeddings | 0 | pending_items为0表示所有嵌入已处理完成。

性能优化

  1. 创建向量索引: 对于大规模向量数据,创建向量索引可显著提升查询性能。pgai支持自动创建索引,可在创建向量izer时配置:

    SELECT ai.create_vectorizer(
        'blog'::regclass,
        loading => ai.loading_column('contents'),
        embedding => ai.embedding_ollama('nomic-embed-text', 768),
        destination => ai.destination_table('blog_contents_embeddings'),
        indexing => ai.indexing_hnsw(min_rows => 10000, opclass => 'vector_cosine_ops')  -- HNSW索引
    );
    

    在Timescale Cloud上,当向量数据达到100,000行时,会自动创建vectorscale索引。

  2. 调整分块策略: 根据文本长度和语义特点,调整分块参数以优化嵌入质量和查询精度。例如:

    SELECT ai.create_vectorizer(
        'blog'::regclass,
        loading => ai.loading_column('contents'),
        embedding => ai.embedding_ollama('nomic-embed-text', 768),
        chunking => ai.chunking_recursive_character_text_splitter(
            chunk_size => 1000,  -- 块大小(字符)
            chunk_overlap => 200  -- 块重叠(字符)
        ),
        destination => ai.destination_table('blog_contents_embeddings')
    );
    
  3. 优化查询语句: 利用PostgreSQL的查询优化功能,为频繁的语义查询创建合适的索引、使用查询重写规则等。例如,结合元数据过滤的查询:

    SELECT 
       chunk,
       embedding <=> :'query_embedding' AS distance,
       metadata->>'category' AS category
    FROM blog_contents_embeddings
    WHERE metadata->>'category' = 'technology'
    ORDER BY distance
    LIMIT 5;
    

常见问题与解决方案

迁移过程中可能遇到各种问题,以下是一些常见问题及解决方法:

问题1:迁移后出现psycopg.errors.DuplicateTable: relation "vectorizer" already exists错误

原因:可能是旧版ai扩展未正确升级。 解决方案:确保已运行ALTER EXTENSION ai UPDATE TO '0.10.1'命令升级扩展,该命令会将向量izer目录表和函数从扩展中分离出来。

问题2:向量izer工作器无法连接到嵌入服务

原因:API密钥配置不正确或环境变量未正确设置。 解决方案

  • 对于自托管环境,检查环境变量是否正确设置,例如:
    echo $OPENAI_API_KEY  # 确认输出正确的API密钥
    
  • 对于Timescale Cloud用户,检查在项目设置中是否正确添加了API密钥,可参考Timescale添加API密钥步骤

问题3:嵌入生成速度慢

原因:嵌入服务API调用速度慢、网络延迟高或向量izer工作器配置不当。 解决方案

  • 检查网络连接,确保与嵌入服务的通信顺畅。
  • 对于自托管环境,可调整向量izer工作器的并发设置,提高处理效率。
  • 考虑使用本地嵌入模型(如通过Ollama部署的模型)减少网络延迟。

问题4:语义搜索结果相关性低

原因:分块策略不当、嵌入模型不匹配或上下文注入不足。 解决方案

  • 调整分块大小和重叠度,确保每个块包含完整的语义信息。
  • 使用与源数据相同或相似的嵌入模型,保持嵌入空间一致性。
  • 通过formatting参数注入更多上下文信息,如标题、作者等:
    formatting => ai.formatting_python_template('Title: $title\nAuthors: $authors\nContent: $chunk')
    

总结与展望

通过pgai Vectorizer将向量数据迁移到PostgreSQL,你可以充分利用PostgreSQL的强大功能和生态系统,简化架构,降低成本,同时保持高效的向量处理能力。迁移过程主要包括环境准备、扩展升级、数据导入、API适配和系统优化等步骤。遵循本文所述的方法和最佳实践,可确保迁移平稳进行,最小化对业务的影响。

未来,pgai将持续增强Vectorizer功能,包括支持更多嵌入模型、优化分块算法、提升查询性能等,为PostgreSQL用户提供更强大的向量数据管理能力。如有任何问题或需要进一步帮助,可参考官方文档或查看更多常见问题解答

迁移到PostgreSQL+pgai,让向量数据管理更简单、高效、经济!

【免费下载链接】pgai Helper functions for AI workflows 【免费下载链接】pgai 项目地址: https://gitcode.com/GitHub_Trending/pg/pgai

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值