理解向量数据库的基础

理解 Embedding、向量相似度与 PGvector

在学习向量数据库时,很多人一上来就看 PGvector、看 SQL、看索引,但真正让人卡住的,往往是最基础的三个问题:

  1. 什么是 embedding
  2. 什么是向量相似度
  3. PGvector 里的 vector 类型和距离运算,到底在解决什么问题

一、什么是 Embedding

先给一句最简洁的定义:

Embedding,就是把文本、图片、音频这类原始内容,转换成一组可以参与计算的数字。

比如,一段文本经过模型编码之后,可能会变成这样一串数字:

[0.12, -0.33, 0.78, 0.05, ...]

这组数字就叫做 embedding,也叫“嵌入向量”。

1. Embedding 的本质是什么

很多人第一次看到向量,会下意识觉得:

“是不是把原文做了某种加密?”

其实不是。

embedding 不是原文的密文,也不是简单的数字编号,而是模型对内容的一种“语义表达”。

换句话说,它试图把“这段内容在说什么”编码进一组数字里。

所以它保存的不是字面形式,而是更偏向:

  • 主题
  • 语义
  • 上下文关系
  • 与其他内容的相似程度

2. 为什么需要 Embedding

传统数据库擅长的是结构化查询,比如:

  • id = 1001
  • status = 'published'
  • price > 100
  • name 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 增加了几项关键能力:

  1. 存储向量
  2. 计算向量距离
  3. 做相似度排序
  4. 构建向量索引(如 HNSWIVFFlat

所以更准确地说:

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 的意思是:

  1. 把表里每一行的 embedding 都拿出来
  2. 分别和查询向量 [0.1, 0.2, 0.29] 计算欧氏距离
  3. 按距离从小到大排序
  4. 取最接近的 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

可以把它拆成四步理解:

  1. 把用户输入转换成查询向量
  2. 拿查询向量和表中每条记录的向量做比较
  3. 按距离或相似度排序
  4. 取前 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;

这个例子表达了三件事:

  1. 向量可以作为数据库字段存储
  2. 查询时可以按向量距离排序
  3. 数据库可以直接返回最相似的内容

这也是 PGvector 最基础、最核心的使用方式。


十、总结

可以把全文压缩成三句话:

1. 什么是 Embedding

Embedding 是把文本、图片等内容转换成数字向量,让语义可以被计算。

2. 什么是向量相似度

向量相似度是通过数学方法比较两个向量是否接近,从而判断两段内容在语义上是否相似。

3. PGvector 在做什么

PGvectorPostgreSQL 可以直接存储向量,并通过距离运算实现相似度检索。

如果只记住一句总纲,可以记成:

内容先被模型转换成 embedding,再存入 PGvectorvector 字段;查询时通过距离运算找出最相近的结果,这就是向量检索最基础的工作方式。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容