在 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 "   密码:你的强密码"
相关推荐
番茄去哪了2 小时前
苍穹外卖day07---Redis缓存优化与购物车功能实现
java·数据库·ide·spring boot·spring·maven·mybatis
切糕师学AI2 小时前
MongoDB 是什么?
数据库·mongodb
学历真的很重要2 小时前
【系统架构师】第三章 数据库系统知识 - 数据库基础到关系代数(详细版)
数据库·学习·职场和发展·系统架构·系统架构师
亓才孓2 小时前
【MyBatis Plus】Wrapper接口
java·开发语言·数据库·spring boot·mybatis
nudt_qxx2 小时前
Ubuntu 26.04 LTS“坚毅浣熊”(Resolute Raccoon) 新特性前瞻
linux·数据库·ubuntu
tianzhiyi1989sq2 小时前
C++工具库之PugiXML使用指南
java·数据库·c++
人道领域2 小时前
MyBatisPlus高效开发实战指南
java·开发语言·数据库
小李独爱秋3 小时前
模拟面试:解释一下数据库的主从复制的原理,或者说:怎么做的数据库的数据同步?
数据库·sql·mysql·面试·职场和发展·职场发展
梵克之泪3 小时前
一次性查找多个文件,批量文件搜索复制高效方案:咕嘎批量文件查找移动存储系统使用指南,告别手动查找
数据库