在 AutoDL 容器内安装 PostgreSQL + pgvector

pgvector 是 PostgreSQL 的扩展插件 ,编译它需要 PostgreSQL 的开发环境(pg_config 工具),但 AutoDL 容器默认没有安装 PostgreSQL。

一、在 AutoDL 容器内安装 PostgreSQL + pgvector

复制代码
# 1. 更新包列表并安装 PostgreSQL 及开发包
sudo apt-get update
sudo apt-get install -y postgresql postgresql-contrib postgresql-server-dev-all

# 2. 启动 PostgreSQL 服务
service postgresql start

# 3. 切换到 postgres 用户
su - postgres

# 4. 进入 pgvector 目录编译安装
cd /root/autodl-tmp/pgvector
make
sudo make install

# 5. 启用扩展
psql -c "CREATE EXTENSION IF NOT EXISTS vector;"

注意:AutoDL 容器重启后数据会丢失。

AutoDL 特别注意

  1. 容器重启数据会丢失 → 重要数据存 /root/autodl-pub
  2. PostgreSQL 服务不会自动启动 → 每次重启容器需手动 service postgresql start
  3. 端口限制 → AutoDL 默认只开放特定端口,数据库建议用本地连接或配置自定义端口
    postgres 用户没有权限访问 /root/autodl-tmp/pgvector 目录,因为这是 root 用户创建的目录。
复制代码
# 退出 postgres 用户,回到 root
exit

# 在 root 用户下执行编译安装
cd /root/autodl-tmp/pgvector
make
make install

# 然后切换到 postgres 用户启用扩展
su - postgres
psql -c "CREATE EXTENSION IF NOT EXISTS vector;"

make install 会把编译好的文件安装到系统目录(如 /usr/share/postgresql/),postgres 用户可以直接使用。

pgvector 安装验证完整步骤


1. 检查 PostgreSQL 服务状态

复制代码
# 查看服务状态
service postgresql status

# 或
pg_isready

2. 检查 pgvector 扩展是否安装成功

复制代码
# 切换到 postgres 用户
su - postgres

# 查看已安装的扩展
psql -c "\dx" | grep vector

输出:

复制代码
 vector  | 0.8.1   | public     | vector data type and ivfflat and hnsw access methods

3. 检查 vector 数据类型是否可用

复制代码
# 查看 vector 类型
psql -c "\dT" | grep vector

输出:

复制代码
 public | vector    | 

4. 创建测试数据库并验证向量功能

复制代码
# 创建测试数据库
psql -c "CREATE DATABASE vector_test;"

# 连接测试数据库
psql -d vector_test

# 在 psql 交互界面中执行以下命令:

-- 1. 启用扩展
CREATE EXTENSION IF NOT EXISTS vector;

-- 2. 创建测试表(带向量列)
CREATE TABLE test_vectors (
    id SERIAL PRIMARY KEY,
    name TEXT,
    embedding vector(3)  -- 3维向量
);

-- 3. 插入测试数据
INSERT INTO test_vectors (name, embedding) VALUES
    ('向量1', '[1, 2, 3]'),
    ('向量2', '[4, 5, 6]'),
    ('向量3', '[7, 8, 9]');

-- 4. 查询数据
SELECT * FROM test_vectors;

-- 5. 测试向量相似度搜索(余弦相似度)
SELECT name, embedding, 
       embedding <-> '[1, 2, 3]' AS distance
FROM test_vectors
ORDER BY distance
LIMIT 2;

-- 6. 退出 psql
\q

5.创建测试数据库并验证

复制代码
# 创建数据库
createdb vector_test

# 连接数据库并启用扩展
psql -d vector_test -c "CREATE EXTENSION IF NOT EXISTS vector;"

# 检查扩展是否成功
psql -d vector_test -c "\dx" | grep vector

# 检查 vector 类型
psql -d vector_test -c "\dT" | grep vector

6.直接执行以下命令测试向量功能:

复制代码
psql -d vector_test << 'SQL'
-- 1. 创建测试表
CREATE TABLE test_vectors (
    id SERIAL PRIMARY KEY, 
    name TEXT, 
    embedding vector(3)
);

-- 2. 插入测试数据
INSERT INTO test_vectors (name, embedding) VALUES 
    ('向量1', '[1, 2, 3]'), 
    ('向量2', '[4, 5, 6]'), 
    ('向量3', '[7, 8, 9]');

-- 3. 查询所有数据
SELECT * FROM test_vectors;

-- 4. 测试向量相似度搜索(余弦距离)
SELECT name, embedding <-> '[1, 2, 3]' AS distance 
FROM test_vectors 
ORDER BY distance 
LIMIT 2;

-- 5. 测试内积相似度
SELECT name, embedding <#> '[1, 2, 3]' AS inner_product 
FROM test_vectors 
ORDER BY inner_product DESC 
LIMIT 2;

-- 6. 测试余弦相似度
SELECT name, embedding <=> '[1, 2, 3]' AS cosine_similarity 
FROM test_vectors 
ORDER BY cosine_similarity DESC 
LIMIT 2;
SQL

echo "pgvector 全部验证完成!"

输出:

复制代码
 id | name  | embedding 
----+-------+-----------
  1 | 向量1 | [1,2,3]
  2 | 向量2 | [4,5,6]
  3 | 向量3 | [7,8,9]
(3 rows)

 name  |     distance      
-------+-------------------
 向量1 |                 0
 向量2 | 5.196152422706632
(2 rows)

 name  | inner_product 
-------+---------------
 向量1 |           -14
 向量2 |           -32
(2 rows)

 name  |  cosine_similarity   
-------+----------------------
 向量3 |  0.04058805443332969
 向量2 | 0.025368153802923787
(2 rows)

常用向量操作速查表

运算符 说明 用途
<-> 欧几里得距离 越小越相似
<#> 负内积 越大越相似
<=> 余弦距离 越小越相似(0=完全相同)
<+> L1 距离 曼哈顿距离

二、创建向量索引(提升查询速度)

复制代码
psql -d vector_test << 'SQL'
-- IVFFlat 索引(适合大数据量)
CREATE INDEX ON test_vectors USING ivfflat (embedding vector_cosine_ops) WITH (lists = 100);

-- 或 HNSW 索引(更准确但占用更多内存)
-- CREATE INDEX ON test_vectors USING hnsw (embedding vector_cosine_ops);
SQL

先说问题:为什么需要索引?

想象有一个 图书馆 ,里面有 100 万本书(向量数据)。

没有索引时:

有人问:"找一本和《哈利波特》最相似的书"

图书管理员只能 一本一本对比,看完100万本才能告诉你答案 😫

耗时:几小时甚至几天

有索引时:

图书管理员先看 分类目录,直接锁定"魔法类→奇幻小说→英国作家"区域

只需要对比 几百本 就能找到最相似的

耗时:几秒钟


两种索引方式对比

IVFFlat 索引 ------ "分区查找法"

复制代码
把100万个向量分成 100 个"簇"(类似100个书架)

        ┌─────────────────────────────────┐
        │          整个向量空间            │
        │   ┌───┐ ┌───┐ ┌───┐ ┌───┐      │
        │   │簇1│ │簇2│ │簇3│ │簇4│ ...  │
        │   └───┘ ───┘ ───┘ ───┘      │
        └─────────────────────────────────┘

查询时:
1. 先确定你的查询向量属于哪个"簇"
2. 只在这个簇里找最相似的
3. 忽略其他99个簇
特点 说明
速度 快(比不索引快10-100倍)
准确度 可能漏掉一些相似向量(近似搜索)
内存占用
适用场景 数据量大(>10万条),追求速度
参数 lists 分多少个簇,一般设为 数据量/1000

生活类比:

就像找对象,先看"年龄段→城市→职业"筛选,再在这个小圈子里找最合适的,而不是全网海选。


HNSW 索引 ------ "朋友圈推荐法"

复制代码
建立一个多层"社交网络"

        第3层(顶层):  A────B────C
                       │    │    │
        第2层(中层):  D─E─F─G─H─I
                       │ │ │ │ │ │
        第1层(底层):  J-K-L-M-N-O-P...(所有数据)

查询时:
1. 从顶层开始,找最近的"朋友"
2. 逐层向下,范围越来越精确
3. 最后在底层找到最相似的几个
特点 说明
速度 更快(比IVFFlat还快)
准确度 更高(更接近精确搜索)
内存占用 大(需要建图结构)
适用场景 对准确度要求高,内存充足
构建时间 ⏱️ 较慢(建索引花时间)

生活类比:

就像通过朋友介绍朋友,层层推荐,最后找到最匹配的人。比大海捞针快,比分区查找准。


两种索引怎么选?

复制代码
┌────────────────────────────────────────────────────────────┐
│                    选择指南                                 │
├────────────────────────────────────────────────────────────┤
│  数据量 < 1万条     →  不用索引,直接暴力搜索就行           │
│  数据量 1万-10万    →  IVFFlat 足够                        │
│  数据量 > 10万      →  HNSW 更优(如果内存够)              │
│  要求100%准确       →  不用索引,或 HNSW + 高参数           │
│  内存有限           →  IVFFlat                             │
│  追求极致速度       →  HNSW                                │
└────────────────────────────────────────────────────────────┘

实际创建命令(带注释)

复制代码
-- ========== IVFFlat 索引 ==========
-- 假设你有 10万条数据,lists 设为 100(10万/1000)
CREATE INDEX ON 你的表名 
USING ivfflat (embedding vector_cosine_ops) 
WITH (lists = 100);

-- 查询时需要设置搜索的簇数量(默认40)
SET ivfflat.probes = 50;  -- 越大越准,但越慢


-- ========== HNSW 索引 ==========
CREATE INDEX ON 你的表名 
USING hnsw (embedding vector_cosine_ops) 
WITH (m = 16, ef_construction = 64);

-- m: 每个节点的"朋友"数量,越大越准但占用越多
-- ef_construction: 建索引时的搜索深度,越大建得越好但越慢

-- 查询时设置搜索深度
SET hnsw.ef_search = 40;  -- 越大越准,但越慢

一句话总结

索引类型 一句话解释
IVFFlat "先分区域,再在区域内找" ------ 快,省内存,可能漏
HNSW "朋友介绍朋友" ------ 更快,更准,吃内存
不索引 "一本一本翻" ------ 慢,但100%准确

性能对比示例(100万条向量)

方式 查询时间 准确率 内存占用
不索引 5000ms 100%
IVFFlat 50ms 95%
HNSW 20ms 98%

建议

根据你的 pgvector 0.8.1 版本,两个索引都支持。建议:

复制代码
-- 如果数据量 < 5万条
CREATE INDEX ON test_vectors USING ivfflat (embedding vector_cosine_ops) WITH (lists = 50);

-- 如果数据量 > 5万条 且 内存充足
CREATE INDEX ON test_vectors USING hnsw (embedding vector_cosine_ops);

三、AutoDL 上 Docker 打包 pgvector 完整流程

pgvector 已经在 AutoDL 上配置好了,用 Docker 打包是最方便的离线部署方式!


整体流程

复制代码
┌──────────────┐    ┌──────────────┐    ┌──────────────┐    ──────────────┐
│  AutoDL 容器  │ →  │  创建镜像    │ →  │  保存为tar   │ →  │  下载到本地  │
└──────────────┘    └──────────────┘    ──────────────┘    └──────────────┘
                                                                    ↓
┌──────────────┐    ┌──────────────┐    ──────────────┐    ┌──────────────┐
│  离线服务器   │ ←  │  加载镜像    │ ←  │  上传tar     │ ←  │  本地存储    │
└──────────────┘    └──────────────┘    └──────────────┘    └──────────────┘

步骤 1:在 AutoDL 上创建 Docker 镜像

1.1 先确认 Docker 可用

复制代码
# 检查 Docker 是否安装
docker --version

# 如果没有,安装 Docker
curl -fsSL https://get.docker.com | bash

1.2 创建 Dockerfile

复制代码
cd /root/autodl-tmp

# 创建 Dockerfile
cat > Dockerfile << 'EOF'
FROM pgvector/pgvector:pg16

# 设置环境变量
ENV POSTGRES_PASSWORD=your_password
ENV POSTGRES_DB=vector_test

# 复制 pgvector 扩展文件(如果自定义编译过)
# COPY --chown=postgres:postgres /usr/share/postgresql/14/extension/vector* /usr/share/postgresql/14/extension/
# COPY --chown=postgres:postgres /usr/lib/postgresql/14/lib/vector.so /usr/lib/postgresql/14/lib/

# 复制初始化 SQL 脚本
COPY init.sql /docker-entrypoint-initdb.d/

# 暴露端口
EXPOSE 5432
EOF

# 创建初始化 SQL 脚本
cat > init.sql << 'EOF'
-- 创建扩展
CREATE EXTENSION IF NOT EXISTS vector;

-- 创建测试表
CREATE TABLE IF NOT EXISTS test_vectors (
    id SERIAL PRIMARY KEY, 
    name TEXT, 
    embedding vector(3)
);

-- 插入测试数据
INSERT INTO test_vectors (name, embedding) VALUES 
    ('向量1', '[1, 2, 3]'), 
    ('向量2', '[4, 5, 6]'), 
    ('向量3', '[7, 8, 9]');
EOF

1.3 构建 Docker 镜像

复制代码
# 构建镜像
docker build -t pgvector-offline:1.0 .

# 验证镜像
docker images | grep pgvector

步骤 2:保存镜像为 tar 文件

复制代码
# 保存镜像
docker save -o /root/autodl-pub/pgvector-offline.tar pgvector-offline:1.0

# 查看文件大小
ls -lh /root/autodl-pub/pgvector-offline.tar

# 压缩(可选,减小体积)
gzip /root/autodl-pub/pgvector-offline.tar
# 生成 pgvector-offline.tar.gz

步骤 3:在离线服务器上加载镜像

复制代码
# 解压(如果压缩了)
gunzip pgvector-offline.tar.gz

# 加载镜像
docker load -i pgvector-offline.tar

# 验证镜像
docker images | grep pgvector

# 运行容器
docker run -d \
  --name postgres-vector \
  -e POSTGRES_PASSWORD=你的强密码 \
  -e POSTGRES_DB=vector_test \
  -p 5432:5432 \
  -v /data/postgres_data:/var/lib/postgresql/data \
  --restart always \
  pgvector-offline:1.0

# 验证连接
docker exec -it postgres-vector psql -U postgres -d vector_test -c "\dt"

步骤 4:验证离线环境

复制代码
# 进入容器
docker exec -it postgres-vector psql -U postgres -d vector_test

# 执行测试查询
SELECT * FROM test_vectors;

-- 测试向量搜索
SELECT name, embedding <-> '[1, 2, 3]' AS distance 
FROM test_vectors 
ORDER BY distance 
LIMIT 2;

-- 退出
\q

完整一键脚本(AutoDL 上执行)

创建 package_pgvector.sh

复制代码
#!/bin/bash

echo "开始打包 pgvector Docker 镜像..."

cd /root/autodl-tmp

# 1. 创建 Dockerfile
cat > Dockerfile << 'EOF'
FROM pgvector/pgvector:pg16
ENV POSTGRES_PASSWORD=auto_password
ENV POSTGRES_DB=vector_test
COPY init.sql /docker-entrypoint-initdb.d/
EXPOSE 5432
EOF

# 2. 创建初始化 SQL
cat > init.sql << 'EOF'
CREATE EXTENSION IF NOT EXISTS vector;
CREATE TABLE IF NOT EXISTS test_vectors (
    id SERIAL PRIMARY KEY, 
    name TEXT, 
    embedding vector(3)
);
INSERT INTO test_vectors (name, embedding) VALUES 
    ('向量1', '[1, 2, 3]'), 
    ('向量2', '[4, 5, 6]'), 
    ('向量3', '[7, 8, 9]');
EOF

# 3. 构建镜像
docker build -t pgvector-offline:1.0 .

# 4. 保存镜像
docker save -o /root/autodl-pub/pgvector-offline.tar pgvector-offline:1.0

# 5. 压缩
gzip /root/autodl-pub/pgvector-offline.tar

# 6. 显示结果
echo "打包完成!"
echo "文件位置:/root/autodl-pub/pgvector-offline.tar.gz"
ls -lh /root/autodl-pub/pgvector-offline.tar.gz

执行脚本:

复制代码
chmod +x package_pgvector.sh
./package_pgvector.sh

离线服务器部署脚本

创建 deploy_pgvector.sh

复制代码
#!/bin/bash

echo "开始部署 pgvector 离线环境..."

# 1. 加载镜像
docker load -i pgvector-offline.tar.gz

# 2. 创建数据目录
mkdir -p /data/postgres_data
chown -R 999:999 /data/postgres_data

# 3. 运行容器
docker run -d \
  --name postgres-vector \
  -e POSTGRES_PASSWORD=你的强密码 \
  -e POSTGRES_DB=vector_test \
  -p 5432:5432 \
  -v /data/postgres_data:/var/lib/postgresql/data \
  --restart always \
  pgvector-offline:1.0

# 4. 等待启动
sleep 5

# 5. 验证
docker exec -it postgres-vector psql -U postgres -d vector_test -c "SELECT version();"

echo "   部署完成!"
echo "   连接信息:"
echo "   主机:localhost"
echo "   端口:5432"
echo "   数据库:vector_test"
echo "   用户名:postgres"
echo "   密码:你的强密码"
相关推荐
zzb15803 小时前
RAG from Scratch-优化-query
java·数据库·人工智能·后端·spring·mybatis
一只鹿鹿鹿3 小时前
信息安全等级保护安全建设防护解决方案(总体资料)
运维·开发语言·数据库·面试·职场和发展
堕2743 小时前
MySQL数据库《基础篇--数据库索引(2)》
数据库·mysql
wei_shuo3 小时前
数据库优化器进化论:金仓如何用智能下推把查询时间从秒级打到毫秒级
数据库·kingbase·金仓
雷工笔记4 小时前
Navicat Premium 17 软件安装记录
数据库
wenlonglanying4 小时前
Ubuntu 系统下安装 Nginx
数据库·nginx·ubuntu
数据库小组4 小时前
10 分钟搞定!Docker 一键部署 NineData 社区版
数据库·docker·容器·database·数据库管理工具·ninedata·迁移工具
爬山算法4 小时前
MongoDB(38)如何使用聚合进行投影?
数据库·mongodb
l1t5 小时前
Deep Seek总结的APSW 和 SQLite 的关系
数据库·sqlite
Pocker_Spades_A5 小时前
基于代价模型的连接条件下推:复杂SQL查询的性能优化实践
数据库·sql·性能优化