理解 Embedding、向量相似度与 PGvector
在学习向量数据库时,很多人一上来就看 PGvector、看 SQL、看索引,但真正让人卡住的,往往是最基础的三个问题:
- 什么是
embedding - 什么是向量相似度
-
PGvector里的vector类型和距离运算,到底在解决什么问题
一、什么是 Embedding
先给一句最简洁的定义:
Embedding,就是把文本、图片、音频这类原始内容,转换成一组可以参与计算的数字。
比如,一段文本经过模型编码之后,可能会变成这样一串数字:
[0.12, -0.33, 0.78, 0.05, ...]
这组数字就叫做 embedding,也叫“嵌入向量”。
1. Embedding 的本质是什么
很多人第一次看到向量,会下意识觉得:
“是不是把原文做了某种加密?”
其实不是。
embedding 不是原文的密文,也不是简单的数字编号,而是模型对内容的一种“语义表达”。
换句话说,它试图把“这段内容在说什么”编码进一组数字里。
所以它保存的不是字面形式,而是更偏向:
- 主题
- 语义
- 上下文关系
- 与其他内容的相似程度
2. 为什么需要 Embedding
传统数据库擅长的是结构化查询,比如:
id = 1001status = 'published'price > 100name LIKE '%postgres%'
这类查询本质上都是在比对“值”。
但很多智能搜索场景,真正想找的并不是“值相同”,而是“意思相近”。
例如:
- 用户搜“怎么退货”,希望找到“退款申请流程”
- 用户问“Postgres 能做语义检索吗”,希望找到“PGvector 向量搜索”相关内容
- 用户输入“数据库事务能力”,希望系统理解这和
ACID、一致性、回滚有关
这时候,如果还是靠关键词精确匹配,效果往往一般;而 embedding 的价值,就是把“语义”变成“可比较的数字表示”。
3. 一个直观例子
来看两组句子。
第一组:
- 怎么退货
- 退款流程怎么走
虽然字面不完全一样,但语义非常接近,所以它们对应的 embedding 往往也比较接近。
第二组:
- 怎么退货
- 今天天气不错
这两句话的主题几乎没有关系,所以对应的向量通常会离得更远。
这就是 embedding 最核心的作用:
把“语义接近”这件事,变成可以用数学方法衡量的东西。
4. 一句话记忆
如果只记一句话,可以记成:
Embedding是把内容的语义信息压缩成一组数字向量。
二、什么是向量相似度
有了 embedding 之后,下一步就是比较:
两个向量到底像不像。
这就是“向量相似度”。
1. 它本质上在比较什么
本质上,是在比较两组数字之间的关系。
但别被“数字”这个形式带偏,向量相似度真正想回答的问题其实是:
- 这两段内容是不是在讲相近的话题
- 它们的语义方向是否接近
- 它们是否可以被认为是“相似内容”
比如有三条内容:
- A:
PostgreSQL 是关系型数据库 - B:
PGvector 是 Postgres 的向量扩展 - C:
Redis 是内存数据库
如果查询是:
Postgres 向量检索
那么查询向量通常会更接近 A 和 B,而离 C 更远。
2. 向量相似度为什么重要
因为 AI 搜索和推荐系统,很多时候不需要“完全一样”,而是需要“最相关”。
这类场景包括:
- 语义搜索
- RAG 知识检索
- 推荐系统召回
- 相似文章发现
- 图片相似搜索
- 商品描述去重
这些场景背后的关键动作,其实都是:
给定一个查询向量,找出数据库里最接近它的若干条记录。
3. 常见的三种度量方式
(1)欧氏距离 L2
欧氏距离可以理解成:
两个点在空间中的直线距离。
距离越小,说明两个向量越接近。
它更像是在看“离得有多远”。
(2)余弦距离 / 余弦相似度
余弦更关注的是“方向是否接近”,而不是绝对长度。
这在文本场景里很常见,因为很多时候我们关心的是:
两段内容表达的方向、主题、语义是否一致。
所以在文本语义检索中,余弦距离经常是默认优先考虑的方案。
(3)内积 Inner Product
内积通常可以理解为一种“匹配强度”。
它在推荐系统、召回排序等场景也很常见,尤其是在某些模型训练目标就是围绕内积来构建时。
4. 一个极简例子
假设有三个二维向量:
- A:
[1, 2] - B:
[1.1, 2.1] - C:
[9, 9]
直觉上:
- A 和 B 很接近
- A 和 C 很远
所以如果拿 A 作为查询条件,B 更可能被判断为“相似结果”。
这个例子虽然很简单,但已经足够说明向量检索的基本思想:
通过比较距离或方向,找出最接近的内容。
5. 一句话记忆
可以这样记:
向量相似度,就是用数学方法判断两个
embedding在语义上有多接近。
三、PGvector 是什么
理解了 embedding 和“相似度”之后,再看 PGvector 就会顺很多。
PGvector 不是一个独立的数据库,而是 PostgreSQL 的一个扩展。
它给 PostgreSQL 增加了几项关键能力:
- 存储向量
- 计算向量距离
- 做相似度排序
- 构建向量索引(如
HNSW、IVFFlat)
所以更准确地说:
PGvector是让PostgreSQL具备向量检索能力的扩展。
这也是为什么很多团队会选择 PostgreSQL + PGvector 这套组合:
- 继续用熟悉的 SQL
- 不用单独维护一套向量数据库
- 业务字段和向量字段可以放在同一张表里
- 可以把“结构化过滤”和“向量搜索”组合起来用
四、PGvector 的 vector 类型是什么
PGvector 最核心的能力之一,就是提供了一个新的字段类型:vector。
1. vector(n) 的含义
例如:
embedding VECTOR(3)
表示这个字段里存的是一个 3 维向量。
如果你使用的 embedding 模型输出是 768 维,那么字段通常会定义成:
embedding VECTOR(768)
如果模型输出是 1536 维,那就定义成:
embedding VECTOR(1536)
也就是说,维度必须和你使用的模型保持一致。
2. 一个最小建表示例
CREATE EXTENSION IF NOT EXISTS vector;
CREATE TABLE documents (
id BIGSERIAL PRIMARY KEY,
content TEXT,
embedding VECTOR(3)
);
这个表里:
-
content用来存原始文本 -
embedding用来存这段文本对应的向量
3. 插入向量数据
INSERT INTO documents (content, embedding) VALUES
('PostgreSQL 是关系型数据库', '[0.1, 0.2, 0.3]'),
('PGvector 支持向量检索', '[0.11, 0.19, 0.31]'),
('Redis 是内存数据库', '[0.9, 0.8, 0.7]');
这一步的意义是:
数据库里存的已经不只是文本本身,还包括文本对应的语义表示。
这也是后续“相似度搜索”能够成立的基础。
五、PGvector 的距离运算在做什么
向量入库之后,下一步就是检索。
PGvector 提供了几种常见的距离运算符,用来比较表中向量和查询向量之间的关系。
1. 欧氏距离:<->
SELECT id, content
FROM documents
ORDER BY embedding <-> '[0.1, 0.2, 0.29]'
LIMIT 2;
这段 SQL 的意思是:
- 把表里每一行的
embedding都拿出来 - 分别和查询向量
[0.1, 0.2, 0.29]计算欧氏距离 - 按距离从小到大排序
- 取最接近的 2 条记录
距离越小,通常说明越相似。
2. 余弦距离:<=>
SELECT id, content
FROM documents
ORDER BY embedding <=> '[0.1, 0.2, 0.29]'
LIMIT 2;
这类写法在文本语义检索里非常常见。
原因很简单:文本 embedding 往往更适合比较“方向上的接近程度”,而不是数值本身的绝对差距。
所以如果你做的是:
- 语义搜索
- 知识库检索
- RAG 召回
通常会优先考虑余弦距离。
3. 内积:<#>
SELECT id, content
FROM documents
ORDER BY embedding <#> '[0.1, 0.2, 0.29]'
LIMIT 2;
内积经常出现在推荐和召回场景中。
它更像是在计算一种“匹配程度”或“打分关系”。
是否选择内积,通常和你使用的模型训练方式、向量归一化方式有关。
六、如何理解向量检索的 SQL
向量检索最典型的写法就是:
ORDER BY embedding <=> query_vector
LIMIT K
可以把它拆成四步理解:
- 把用户输入转换成查询向量
- 拿查询向量和表中每条记录的向量做比较
- 按距离或相似度排序
- 取前
K条结果
这就是常说的:
-
Top K检索 - 最近邻搜索
- 相似度搜索
所以从数据库的角度看,向量检索其实并不神秘,它本质上就是:
对
vector列做距离排序,然后返回最接近的若干条记录。
七、把三者串起来理解
到这里,可以把整条链路完整地连起来了。
第一步:原始内容
比如有一段文本:
PostgreSQL 支持事务
第二步:生成 Embedding
通过模型把这段文本转换成向量,例如:
[0.12, -0.33, 0.78, 0.05, ...]
第三步:写入 PostgreSQL
把文本和向量一起存入数据库:
- 原文存在
content - 向量存在
embedding
第四步:生成查询向量
用户输入一个问题,比如:
Postgres 的事务能力
系统会把这个问题也转换成一个查询向量。
第五步:执行向量检索
数据库使用:
embedding <-> query_vector- 或
embedding <=> query_vector - 或
embedding <#> query_vector
去比较相似度,并返回最接近的结果。
这就是向量检索最核心的工作路径。
八、初学者最容易混淆的几个点
1. Embedding 不是原文
它不是文本本身,而是文本的数字化语义表示。
2. 向量检索不是精确匹配
它不是在找“完全一样的词”,而是在找“意思接近的内容”。
3. PGvector 不是独立数据库
它是 PostgreSQL 的扩展,而不是一个新的数据库产品。
4. vector 维度不能随便写
它必须和你的 embedding 模型输出维度一致。
5. 不是所有场景都默认用同一种距离
- 文本语义检索:常见优先考虑余弦距离
- 某些推荐场景:可能更偏内积
- 一些数值空间任务:可能会考虑欧氏距离
具体选型,最好结合模型特性和效果测试来决定。
九、一个最小可运行示例
下面这个例子,可以把前面的概念串成一条完整的链路:
CREATE EXTENSION IF NOT EXISTS vector;
CREATE TABLE articles (
id BIGSERIAL PRIMARY KEY,
title TEXT NOT NULL,
content TEXT NOT NULL,
embedding VECTOR(3)
);
INSERT INTO articles (title, content, embedding) VALUES
('PostgreSQL 简介', '关系型数据库', '[0.1, 0.2, 0.3]'),
('PGvector 简介', 'PostgreSQL 向量扩展', '[0.11, 0.19, 0.29]'),
('Redis 简介', '内存数据库', '[0.9, 0.8, 0.7]');
SELECT id, title
FROM articles
ORDER BY embedding <=> '[0.1, 0.2, 0.31]'
LIMIT 2;
这个例子表达了三件事:
- 向量可以作为数据库字段存储
- 查询时可以按向量距离排序
- 数据库可以直接返回最相似的内容
这也是 PGvector 最基础、最核心的使用方式。
十、总结
可以把全文压缩成三句话:
1. 什么是 Embedding
Embedding 是把文本、图片等内容转换成数字向量,让语义可以被计算。
2. 什么是向量相似度
向量相似度是通过数学方法比较两个向量是否接近,从而判断两段内容在语义上是否相似。
3. PGvector 在做什么
PGvector 让 PostgreSQL 可以直接存储向量,并通过距离运算实现相似度检索。
如果只记住一句总纲,可以记成:
内容先被模型转换成
embedding,再存入PGvector的vector字段;查询时通过距离运算找出最相近的结果,这就是向量检索最基础的工作方式。