PGVector是一个用于向量化数据的PostgreSQL扩展。它提供了一种有效存储和查询向量数据的方法,以便在数据库中进行相似度搜索和相关操作。
PGVector扩展使用了PGSQL的数据类型和函数,可以轻松地将向量数据存储在数据库表中,并使用SQL查询进行向量操作。它支持向量的插入、更新和删除,以及向量之间的相似度计算和搜索。
PGVector还提供了一些内置的向量操作函数,如向量的加法、减法、乘法和除法,以及向量的归一化和距离计算。这些函数可以用于构建复杂的向量操作和查询。
使用PGVector扩展,可以将向量数据存储在数据库中,并利用数据库的强大查询功能进行高效的向量操作和相似度搜索。它适用于各种应用场景,如自然语言处理、图像处理、推荐系统等。
下面介绍PGVector 数据库的安装和使用
1.安装
因为官方支持docker模式安装,我们这里就以docker安装模式来介绍。
1.1获取docker 镜像
docker pull ankane/pgvector完成docker 镜像下载
当然你也可以下载官方源码自己编译打包镜像,相关命令行如下。
git clone --branch v0.4.4 https://github.com/pgvector/pgvector.gitcd pgvectordocker build --build-arg PG_MAJOR=15 -t myuser/pgvector .我们打开dockerfile文件查看
ARG PG_MAJOR=15FROM postgres:$PG_MAJORARG PG_MAJORCOPY . /tmp/pgvectorRUN apt-get update && \ apt-get install -y --no-install-recommends build-essential postgresql-server-dev-$PG_MAJOR && \ cd /tmp/pgvector && \ make clean && \ make OPTFLAGS="" && \ make install && \ mkdir /usr/share/doc/pgvector && \ cp LICENSE README.md /usr/share/doc/pgvector && \ rm -r /tmp/pgvector && \ apt-get remove -y build-essential postgresql-server-dev-$PG_MAJOR && \ apt-get autoremove -y && \ rm -rf /var/lib/apt/lists/*从上面代码可以看出,pgvector 其实是在postgres 数据库原有的基础上面编译打包增加了PG数据库支持向量部分的插件,从而让postgres 数据库实现了向量数据库的支持。
1.2启动
docker run -d --name pgvector -e POSTGRES_USER=root -e POSTGRES_PASSWORD=123456 -p 5432:5432 ankane/pgvector:latest测试一下数据库是正常使用
以上说明pgvector 数据库是正常的。
2.使用
启用扩展名(在每个想要使用的数据库中进行一次)
CREATE EXTENSION vector;创建一个三维向量列
CREATE TABLE items (id bigserial PRIMARY KEY, embedding vector(3));插入向量
INSERT INTO items (embedding) VALUES ('[1,2,3]'), ('[4,5,6]');获取距离相邻的L2数据
SELECT * FROM items ORDER BY embedding <-> '[3,1,2]' LIMIT 5;我们使用数据库客户端工具操作以上命令
通过以上操作我们就可以实现向量数据库的访问了。
3.支持的语言
我们知道一个强大的数据库需要支持多种开发语言,这样的数据库才能给大众使用,也就是服务于更多使用者或者生态。只有开发者支持的生态这块软件才有它生命周期。pgvector目前支持的开发语言也很多,具体可以看下面一张图:
目前主流的开发语言它都是可以支持的。这样编程语言客户端的支持有利用打造它自己的数据库生态。
下面就以官方的Java的例子跑起来,让大家感受一下。
3.1 pgvector-java客户端调用案例
github下载代码https://github.com/pgvector/pgvector-java,把代码导入的IntelliJ IDEA项目中。
项目默认是Scala构建工程的,我们需要修改增加POM.XML
<!--?xml version="1.0" encoding="UTF-8"?--> 4.0.0 com.example pgvector-java 1.0.0 1.8 1.8 UTF-8 com.pgvector pgvector 0.1.2 org.springframework spring-jdbc 5.3.10 修改测试代码JDBCJava.java,将数据库连接地址改成远程地址
dataSource.setUrl("jdbc:postgresql://192.168.210.16:5432/postgres"); dataSource.setUsername("root"); dataSource.setPassword("123456");完整的代码
package com.pgvector;import java.sql.*;import java.util.List;import java.util.Map;import com.pgvector.PGvector;import org.springframework.jdbc.core.JdbcTemplate;import org.springframework.jdbc.datasource.DriverManagerDataSource;public class SpringJDBC { public static void main(String[] args) { DriverManagerDataSource dataSource = new DriverManagerDataSource(); dataSource.setUrl("jdbc:postgresql://192.168.210.16:5432/postgres"); dataSource.setUsername("root"); dataSource.setPassword("123456"); JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource); jdbcTemplate.execute("CREATE EXTENSION IF NOT EXISTS vector"); jdbcTemplate.execute("DROP TABLE IF EXISTS spring_items"); jdbcTemplate.execute("CREATE TABLE spring_items (id bigserial PRIMARY KEY, embedding vector(3))"); Object[] insertParams = new Object[] { new PGvector(new float[] {1, 1, 1}), new PGvector(new float[] {2, 2, 2}), new PGvector(new float[] {1, 1, 2}), new PGvector() }; jdbcTemplate.update("INSERT INTO spring_items (embedding) VALUES (?), (?), (?), (?)", insertParams); Object[] neighborParams = new Object[] { new PGvector(new float[] {1, 1, 1}) }; List运行程序

我们查看一下数据库
新增加一个spring_items向量表,查看他的数据
和程序代码插入的数据是对的上的。
3.2 pgvector-python客户端调用案例
github下载代码https://github.com/pgvector/pgvector-python,把代码导入的IntelliJ IDEA项目中。
修改项目环境依赖
执行 pip 依赖库的安装
pip install -r requirements.txt执行pgvector 依赖库安装
pip install pgvector我们找一个能测试的代码,就以test 文件夹下test_asyncpg.py 为案例,修改代码增加数据库 连接相关信息
conn = await asyncpg.connect(host="192.168.210.16", port=5432, user="root", password="123456",database='postgres')完整的代码如下:
import asyncioimport asyncpgimport numpy as npfrom pgvector.asyncpg import register_vectorimport pytestclass TestAsyncpg: @pytest.mark.asyncio async def test_works(self): conn = await asyncpg.connect(host="192.168.210.16", port=5432, user="root", password="123456",database='postgres') await conn.execute('CREATE EXTENSION IF NOT EXISTS vector') await conn.execute('DROP TABLE IF EXISTS item') await conn.execute('CREATE TABLE item (id bigserial primary key, embedding vector(3))') await register_vector(conn) embedding = np.array([1.5, 2, 3]) await conn.execute("INSERT INTO item (embedding) VALUES ($1), (NULL)", embedding) res = await conn.fetch("SELECT * FROM item ORDER BY id") assert res[0]['id'] == 1 assert res[1]['id'] == 2 assert np.array_equal(res[0]['embedding'], embedding) assert res[0]['embedding'].dtype == np.float32 assert res[1]['embedding'] is None # ensures binary format is correct text_res = await conn.fetch("SELECT embedding::text FROM item ORDER BY id LIMIT 1") assert text_res[0]['embedding'] == '[1.5,2,3]' await conn.close() @pytest.mark.asyncio async def test_pool(self): async def init(conn): await register_vector(conn) pool = await asyncpg.create_pool(host="192.168.210.16", port=5432, user="root", password="123456",database='postgres', init=init) async with pool.acquire() as conn: await conn.execute('CREATE EXTENSION IF NOT EXISTS vector') await conn.execute('DROP TABLE IF EXISTS item') await conn.execute('CREATE TABLE item (id bigserial primary key, embedding vector(3))') embedding = np.array([1.5, 2, 3]) await conn.execute("INSERT INTO item (embedding) VALUES ($1), (NULL)", embedding) res = await conn.fetch("SELECT * FROM item ORDER BY id") assert res[0]['id'] == 1 assert res[1]['id'] == 2 assert np.array_equal(res[0]['embedding'], embedding) assert res[0]['embedding'].dtype == np.float32 assert res[1]['embedding'] is None代码修改后我们运行测试一下
检查数据库
我查一下数据是不是代码你新增的向量数据1.5, 2, 3
结果打开后发现是的。
总结:pgvector在原有的postgressql 基础上增加了向量数据库的支持,对熟悉postgressql 小伙伴非常友好,学习成本较低 很容易上手。而且项目支持的客户端编程语言也较为丰富,而且相关DEMO案例也较为齐全,个人觉的作为向量数据库也是有较大发展前景的。
参考文献:
https://github.com/pgvector/pgvector