社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  DATABASE

为什么越来越多人放弃 MySQL 转而用 PostgreSQL?

JavaGuide • 15 小时前 • 17 次点击  

超越 MySQL,PostgreSQL 新王登基,成为目前最受欢迎的关系型数据库。

这个排名来自 Stack Overflow 2026 年开发者调查:PostgreSQL 的使用比例为 57.9%,MySQL 为 35.1%。

一共有 12,061 人回答了这道题,说的是过去一年大量使用过哪些数据库。其实,PostgreSQL 早在 2023 年这项调查中就已经超过 MySQL 了。

Stack Overflow 2026 数据库调查
Stack Overflow 2026 数据库调查

我自己也有这个感觉:相比前几年,身边用 PostgreSQL 的人越来越多了。

尤其是 AI 时代,PostgreSQL 的优势就更明显了。

做 AI 应用,除了用户、订单这些业务数据,往往还要存文档、做搜索。如果 PostgreSQL 加上扩展就能满足需求,就可以少部署一套搜索服务或向量数据库,也少做一份数据同步。

扩展装进来,仍然用 SQL 查

拿向量来说,它就是一组数字,把这组数字转成字符串,普通数据库也存得下。麻烦在查询上:我们要找距离最近的几组向量,数据多了还希望用索引加速,光把数字存进去可不够。

装上 pgvector 后,可以在原有文档表里加一个向量列,用 SQL 计算向量之间的距离,再根据查询需要建立向量索引。文档编号、作者、部门这些字段还在原来的表里,查询时可以一起使用。

PostgreSQL 的扩展接口允许开发者增加数据类型、函数、运算符,以及索引相关的能力。pgvector 用这些接口实现向量检索。

pgvector 官方功能介绍
pgvector 官方功能介绍

地理信息有类似的扩展 PostGIS,负责位置、距离、区域相关的类型和操作。不过,实际能装什么,还要看你选的数据库服务。托管平台有自己的扩展支持列表,选型时要查具体扩展和版本。

文档里的关键词怎么搜

在技术文档里找函数名、错误码,按关键词查通常就很合适。PostgreSQL 自带全文检索,可以把文字处理成词项,按需建立索引,查询时再匹配、排序。

这里很容易忽略文本处理。比如一个专业名称,被当成完整的词,还是拆成了几个词,会影响哪些文档被找到。中文搜索尤其要选好分词方案,不能直接把英文示例搬过来。先拿几条自己会搜的问题,看分词结果和匹配的文档,再考虑怎么调排序。

如果需要 BM25 相关性评分,可以再看 ParadeDB 的 pg_search 扩展。它把搜索能力接入 PostgreSQL,查到的内容还可以继续关联业务表、筛选和排序。

BM25 可以先理解为一种给关键词搜索结果打分的方法。它会考虑词在文档中的出现情况、词在整批文档里是否常见,以及文档长度等因素。文档里重复出现某个词,并不意味着它就一定应该排在最前面。

项目只需要简单搜索,可以先试内置全文检索;需要 BM25,再考虑装 pg_search。后者是额外安装的扩展。

能在库里搜索,也不意味着任何项目都可以直接撤掉 Elasticsearch。已有的查询语法、分词配置、聚合需求,以及搜索和业务各自的负载,都需要逐项评估。

按意思找资料,交给向量检索

同一个意思,换一种说法,关键词就可能对不上。

假设用户问:“买完以后不想要了,怎么退?”文档标题却是“商品退货申请流程”。如果只按用户输入的几个词去匹配,就可能漏掉这份资料。向量检索可以帮助找到语义接近的内容。

先让嵌入模型,也就是 Embedding 模型,把文本转成向量,可以理解为用一组数字表示这段文本。选什么模型、怎样切分文档,都会影响后面的检索效果。

pgvector 负责保存向量,并按距离查找相近的向量。生成向量需要模型来做,生成回答同样需要模型来做,数据库负责其中的存储和检索。

做 RAG,也就是检索增强生成时,一次文档问答通常会经过这些步骤:

  1. 把文档切成合适的片段,为每个片段生成向量,连同原文和来源信息一起保存。
  2. 用户提问时,用兼容的嵌入模型把问题也转成向量。
  3. 检索可能相关的片段,把片段原文和用户问题一起交给大模型。
  4. 大模型根据这些资料组织回答,应用按需要展示引用来源。

这里交给大模型的是检索出来的文字。向量帮助我们找到文字,不需要把那一长串数字当作资料塞进提示词。

RAG 中向量检索与模型回答的分工
RAG 中向量检索与模型回答的分工

文档和问题的向量还得处在可以比较的空间里。两个模型都输出相同数量的数字,也不意味着可以混着检索。更换嵌入模型时,要考虑已有向量怎么重新生成、怎样区分新旧数据。

向量相近,也不保证资料一定能回答问题。退货和换货可能很接近,用户问的却只是退货;产品旧版说明和新版说明可能很接近,适用条件却已经变了。版本、状态等明确条件,仍然需要参与筛选。

因此,关键词搜索和向量搜索经常会配合起来用。明确的产品型号、函数名、错误码,适合保留字面匹配能力;用户换了一种说法,向量检索可以补充候选。

两路各查一批结果,再去重、融合排序,就是混合检索。一种常见方法是 RRF,主要根据候选在各路结果中的名次计算融合分数,避免直接把量纲不同的关键词分数和向量距离相加。Supabase 的混合检索文档提供了把两路查询放到 PostgreSQL 中组合的示例。

不过,多查一路也会多一份开销。是否采用混合检索,应该看它能不能找回原来漏掉的资料,以及会不会引入更多无关结果。只查订单号的功能,就没必要把这套流程全部加上。

和业务数据放在一起,能少做哪些工作

这些检索能力能和原来的业务数据放在一起,才是我觉得 PostgreSQL 实用的地方。

一个知识库的文档通常有归属:属于哪个团队,是否已发布,是哪个产品版本,当前用户能不能看。检索时,除了“和问题像不像”,这些条件也得满足。

假设文档切分后放在 document_chunks 表里。现在要查当前团队已发布的资料,按向量距离找出 5 条,可以把条件直接写进 SQL:

SELECT id, document_id, content
FROM document_chunks
WHERE tenant_id = $1
  AND status = 'published'
ORDER BY embedding <=> $2::vector
LIMIT 5;

这里的两个参数由数据库驱动绑定:$1 是团队编号,$2 是问题向量。表里的 embedding 列已经存好了文档向量,问题向量要与它使用匹配的模型配置和维度。 <=> 算的是余弦距离,越小排得越靠前。

团队编号得由后端根据登录身份确定。要是任由客户端传一个编号,就能查别人的资料了。团队内还有文档级授权的话,也要加上相应检查。SQL 写出了筛选条件,具体先扫描什么、在哪一步过滤,仍然要看执行计划。

不同来源的文档,还可能有各自的附加属性,结构不太固定的部分可以放进 JSONB。像团队编号、发布状态这些经常要查、要关联的字段,可以单独建列。

文档更新时,同一个库也能省掉一些同步工作。

假设一份说明文档从第 7 版改到第 8 版,原文和向量分属两套系统。原文更新成功了,向量同步却失败,检索就可能继续按照旧内容找资料。重试怎么做、旧数据什么时候清理、两边怎样核对,都需要应用处理。

如果它们都在 PostgreSQL 中,可以先为第 8 版生成好向量,再把新原文、新向量和版本信息放进同一个数据库事务提交。这样可以避免数据库里出现“原文已更新,对应向量却只更新了一半”的状态。

如果第 8 版的向量还没生成完,用户又提交了第 9 版呢?

所以,向量生成任务要记住自己处理的是哪个版本。写回时,可以通过带版本条件的更新或行锁,在同一个事务里完成版本检查和数据写入;如果用户已经提交第 9 版,就不能让第 8 版的任务覆盖新结果。也可以先保存待处理版本,等片段和向量全部准备好,再在事务中切换当前可检索的版本。

数据库事务只负责数据库内的提交。外部模型超时、生成失败、任务重试,还是要由应用处理。通常可以先完成模型调用,再用短事务写入结果,避免在等待模型响应时一直占着事务。

文档与向量更新的事务边界
文档与向量更新的事务边界

Supabase 和 Neon,让应用更容易搭起来

Supabase 把 PostgreSQL 和用户认证、文件存储、实时订阅、数据 API 等服务组合在一起。应用需要登录、上传文件、展示处理进度时,可以接入这些服务。

Supabase 选择 Postgres 的说明
Supabase 选择 Postgres 的说明
Supabase 选择 Postgres 的原文细节
Supabase 选择 Postgres 的原文细节

比如用户上传 PDF,文件本身交给对象存储,相关元数据放在 PostgreSQL 中。应用处理完文档,再保存片段、向量和处理状态。这里仍然要设计谁能上传、谁能读取,但不用自己从头实现一套文件存储服务。

如果需要改表结构,可以从 Neon 的数据库分支开始试。比如给文档表加一列、调整索引,先在分支上执行迁移,再跑应用里的查询,看哪里需要跟着改。分支上的修改不会写回原库,让 AI 帮忙写迁移代码时,也可以把验证放在这里。

Neon 主分支与开发分支
Neon 主分支与开发分支

用这个功能需要 Neon,普通 PostgreSQL 没有自带数据库分支。另外,分出来的数据还是原来的数据,并不会自动脱敏。哪些内容能给开发者或 AI 看,仍然要自己管好权限。

真要选型,还得拿自己的数据跑一遍

前面说少维护几套系统,但放进同一个库后,CPU、内存和 I/O 也得一起分。建向量索引、批量更新文档的时候,资源可能被占走,业务查询也会受影响。只测搜索本身的速度,看不出这部分代价。

pgvector 的检索结果也需要检查。它可以做精确检索,按选定的距离完整查找;也可以用 HNSW、IVFFlat 等近似索引加速,但可能漏掉距离更近的候选。这里的“精确”只是指距离计算和查找过程,嵌入模型有没有表达好文档的意思,是另一个问题。

再看前面的 SQL,写了 LIMIT 5,并不一定能拿到 5 条。近似索引扫描得到的候选里,可能有不少属于其他团队,或者还没发布,被 WHERE 条件过滤掉了。库里即使还有符合条件的资料,这次扫描没找到,也不会出现在结果里。

pgvector 从 0.8.0 起支持迭代索引扫描,默认关闭,需要显式启用。开启后可以继续寻找候选,但仍受扫描上限等配置限制。过滤后数据很少的场景,也可以评估利用普通索引缩小范围,再做精确检索。具体采用哪条路径,要结合数据分布和执行计划判断。

近似向量检索过滤后可能不足五条
近似向量检索过滤后可能不足五条

因此,验证时可以把检索效果和运行成本放在一起看:

  • 准备真实问题和预期资料,检查该找的内容有没有找到,不能只看“返回了 5 条”。
  • 带上实际的团队、权限、版本等条件,检查过滤后的结果数量和相关性。
  • 在并发查询、文档更新、索引维护同时发生时,观察响应时间和业务查询是否受影响。

如果检索负载已经很重,需要独立扩容,或者专门的搜索系统明显更适合业务,就可以把对应部分拆出去。少维护系统的收益,要和资源竞争、调优及故障影响放在一起算。

从零做一个需要检索能力的 AI 应用,可以先考虑 PostgreSQL:业务数据继续用 SQL 管,搜索和向量能力按需求接上,再用实际数据确认效果和成本。能满足需求,就省下一部分搭系统、同步数据的工作。

已经跑得好好的 MySQL 项目,就按自己的需求来。加个 AI 功能,不一定要连数据库也换掉。

图片

⭐️推荐阅读:

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/203398