点击关注公众号,Java干货及时送达

最近帮几个刚入行的朋友做技术指导,发现一个普遍现象:很多人从大学学完MySQL之后,就再也没碰过别的数据库了。
到了工作中,遇到一些复杂业务场景,用MySQL去硬撑,搞得焦头烂额。
说实话,PostgreSQL这几年在企业级应用中的普及速度非常快。
2026年DB-Engines排名显示,PostgreSQL稳坐全球第四大数据库的宝座,仅次于Oracle、MySQL和SQL Server。
今天,我就用一篇文章跟大家一起聊聊PostgreSQL,希望对你会有所帮助。
最近建了一些AI技术交流群,加我微信:li_su223,备注:AI,即可进群交流和学习,获取最新咨询。
一、先说一个扎心的事实
有些小伙伴在工作中可能会说:“我用MySQL用了好几年了,感觉也挺好的啊,为什么要学PostgreSQL?”
我举个简单的例子:假如你的电商系统需要查询“2024年每个季度销售额排名前3的商品”,用MySQL写这个SQL起码20行起步,各种嵌套子查询、窗口函数疯狂套娃。
而PostgreSQL原生就支持RANK()窗口函数,10行代码轻松搞定。
这不叫花里胡哨,这叫生产力。
数据库的选型,决定着你未来无数个加班的夜晚是不是真的在“用代码解决问题”,还是在“跟数据库做斗争”。
而且,国内外很多大厂都已经在从MySQL向PostgreSQL迁移了。
Apple、Instagram、Uber、Reddit,甚至阿里巴巴的部分业务线,都在逐步拥抱PostgreSQL。
这背后是有原因的——简单来说,MySQL适合80%的普通场景,而PostgreSQL适合剩下那20%复杂至极、对数据一致性要求极高的“硬骨头”。
二、PostgreSQL到底是什么?
PostgreSQL是一个功能强大的开源关系型数据库管理系统,它起源于1986年加州大学伯克利分校的POSTGRES项目。
经过近40年的发展,它已经成长为全球最先进的开源数据库之一。
它的核心特性有这么几个:
完全开源:遵循PostgreSQL许可证,可以自由使用、修改和分发。 高度可扩展:支持自定义数据类型、函数、操作符和索引方法。 标准兼容性强:对SQL:2023标准的兼容度超过90%,完整支持窗口函数、公共表表达式(CTE)、全文搜索等高级SQL特性。 多版本并发控制(MVCC) :读写互不阻塞,完美解决了高并发场景下的锁争用问题。 丰富的扩展生态:提供PostGIS(地理信息系统)、pgvector(向量检索)、TimescaleDB(时序数据)等行业级扩展。
PostgreSQL和MySQL两者最根本的差异,我用一张图帮你理清楚:

简单来说,一个擅长“全都要”,什么都能干;另一个擅长“一招鲜”,在特定场景下做到极致。
三、环境搭建
咱们先把环境弄起来。
PostgreSQL可以在Linux、Windows、macOS等各种操作系统上运行。
生产环境建议内存至少8GB以上。
3.1 Windows用户
对于Windows新手,推荐使用官方图形化安装包。
步骤如下:
访问postgresql.org/download,下载Windows安装包 双击运行,一路Next 设置安装路径(默认C:\Program Files\PostgreSQL\16) 设置超级用户(postgres)密码——切记记住这个密码! 设置端口(默认5432,一般不改) 选择区域,建议选Chinese (Simplified)或English_United States 安装完成后勾选Launch Stack Builder可以跳过 打开CMD或PowerShell,输入 psql -U postgres,输入密码,看到postgres=#提示符即为成功
3.2 macOS用户
macOS推荐使用Homebrew安装:
# 安装PostgreSQLbrew install postgresql# 启动服务brew services start postgresql# 连接数据库psql postgres如果不习惯用命令行,也可以去官网下载.dmg安装包,拖拽到Applications即可。
3.3 Linux用户(Ubuntu/Debian)
Ubuntu用户推荐从官方仓库安装,确保版本最新:
# 添加官方仓库sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list'wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -# 更新并安装sudo apt updatesudo apt install postgresql postgresql-contrib# 启动服务sudo systemctl start postgresql# 切换到postgres用户sudo -i -u postgrespsql3.4 安装验证
无论哪个系统,安装完成后可以用下面这个命令快速验证:
SELECTversion();看到类似“PostgreSQL 16.x”的输出,恭喜你,安装成功了!
四、基础SQL全掌握
4.1 数据库基本操作
-- 创建数据库CREATEDATABASE mydb;-- 查看所有数据库\l-- 切换到指定数据库\c mydb-- 创建用户并授权CREATEUSER myuser WITHPASSWORD'mypass';GRANTALLPRIVILEGESONDATABASE mydb TO myuser;-- 删除数据库(生产环境慎用)DROPDATABASE mydb;4.2 数据类型详解
PostgreSQL支持的数据类型非常丰富,远超MySQL:
| 数值类型 | ||
| 字符串类型 | ||
| 日期时间 | ||
| 布尔类型 | ||
| JSON类型 | ||
| 数组类型 | ||
| 网络地址 |
4.3 创建表和约束
-- 创建商品表CREATETABLE products (idSERIAL PRIMARY KEY, -- 自增主键nameVARCHAR(200) NOTNULL, -- 商品名,非空 price NUMERIC(10,2) CHECK (price > 0), -- 价格必须大于0 stock INTEGERDEFAULT0, -- 库存,默认0categoryVARCHAR(50), tags TEXT[], -- 数组类型存标签 created_at TIMESTAMPTZ DEFAULTNOW() -- 带时区的时间戳);4.4 基本的增删改查
-- 插入数据INSERTINTO products (name, price, stock, category, tags)VALUES ('机械键盘', 399.00, 50, '外设', ARRAY['键盘', '电竞']), ('无线鼠标', 129.00, 100, '外设', ARRAY['鼠标', '无线']);-- 查询数据SELECT * FROM products WHERE price BETWEEN100AND500;-- 更新数据UPDATE products SET stock = stock - 1WHEREid = 1;-- 删除数据DELETEFROM products WHERE stock = 0;五、MVCC多版本并发控制
有些小伙伴在工作中可能会问:PostgreSQL和MySQL在并发性能上到底有什么本质区别?为什么说PostgreSQL更适合高并发写场景?
这就是MVCC(Multi-Version Concurrency Control)的功劳。
PostgreSQL的并发承诺非常简单:读永远不阻塞写,写永远不阻塞读。
5.1 MVCC核心原理
PostgreSQL中,每个事务都会获得一个唯一的事务ID,称为XID。

MVCC的核心区别在于:MySQL通过锁机制实现,读数据时可能会被写操作阻塞;而PostgreSQL通过快照隔离实现,永远不会有读写互锁。
XMIN和XMAX是两个隐藏字段,每个数据行都有。插入时写入XMIN(创建这个版本的事务ID),更新/删除时写入XMAX(删除这个版本的事务ID),通过比较XID就可以判断事务的可见性。
5.2 事务隔离级别
PostgreSQL支持四种隔离级别,默认是READ COMMITTED,同时也提供了严格的SERIALIZABLE级别:
READ UNCOMMITTED:实际上等同于READ COMMITTED READ COMMITTED(默认):查询只能看到已提交的数据 REPEATABLE READ:保证在同一事务内多次查询结果一致 SERIALIZABLE:最高隔离级别,使用可序列化快照隔离(SSI),能真正防止幻读和写偏序异常
如果两个事务同时修改同一行,PostgreSQL会如何处理?

这在SERIALIZABLE隔离级别下会抛错误,应用层可以选择重试或者放弃。
六、PostgreSQL的索引武器库
有些小伙伴在工作中可能会遇到这样的情况:明明给字段建了索引,慢查询还是一堆。这是因为PostgreSQL的索引体系比MySQL复杂得多,也强大得多——索引类型不同,适用场景完全不同。
6.1 索引类型全家桶
MySQL主要依赖B-tree索引,而PostgreSQL提供了丰富的索引武器库:
| B-tree | =<<=>>=ORDER BY | |
| Hash | ||
| GIN | ||
| GiST | ||
| BRIN | ||
| Bloom |
B-tree是默认索引类型,但也是水最深的。比如查询LIKE '%keyword%'就不会走B-tree索引,这时候需要考虑GIN或全文搜索。
GIN索引实战:加速JSONB查询
PostgreSQL的JSONB类型配上GIN索引,查询性能可以提升几百倍:
-- 创建含JSONB字段的表CREATETABLE products (idSERIAL PRIMARY KEY, details JSONB);-- 插入测试数据INSERTINTO products (details) VALUES('{"name": "Laptop", "specs": {"cpu": "i7", "ram": "16GB"}, "tags": ["electronics", "sale"]}'),('{"name": "Keyboard", "specs": {"switch": "mechanical", "connection": "wired"}, "tags": ["peripherals"]}');-- 不加索引的查询(慢)SELECT * FROM products WHERE details -> 'specs' ->> 'cpu' = 'i7';-- 创建GIN索引CREATEINDEX idx_products_details ON products USING GIN (details);-- 索引后的快速查询(快300倍)SELECT details -> 'name'ASname, details -> 'specs'AS specsFROM productsWHERE details @> '{"specs": {"cpu": "i7"}}';这里的@>是JSONB包含操作符,利用GIN索引快速定位。
6.2 表达式索引和部分索引
PostgreSQL支持两种高级索引,MySQL需要复杂配置才能实现:
-- 表达式索引:按小写邮箱查询,避免写函数导致索引失效CREATEINDEX idx_users_lower_email ONusers (lower(email));-- 现在可以直接走索引SELECT * FROMusersWHERElower(email) = 'someone@example.com';-- 部分索引:只为活跃用户建索引,大大减少索引体积CREATEINDEX idx_users_active ONusers (email) WHERE active = true;这两个特性的价值在于精准索引——不是所有数据都需要加速,只索引你最常查的那部分,存储和写入成本都降下来了。
6.3 执行计划分析
用EXPLAIN ANALYZE查看SQL的实际执行计划:
EXPLAIN (ANALYZE, BUFFERS) SELECT * FROM products WHERE price < 100;输出中重点关注Seq Scan(全表扫描,慢)还是Index Scan(索引扫描,快)。
如果想在图形界面操作,可以用pgAdmin执行可视化诊断。
七、JSONB与全文搜索
7.1 让关系型数据库也能“非结构化”
JSONB把JSON数据解析成二进制结构存储,支持索引,查询性能远超MySQL的JSON类型。
JSONB的核心操作符:
-- 创建表CREATETABLE user_profiles (idSERIAL PRIMARY KEY, profile JSONB);INSERTINTO user_profiles (profile) VALUES('{"name": "张三", "age": 30, "address": {"city": "北京", "zip": "100000"}, "skills": ["Java", "Python"]}'),('{"name": "李四", "age": 25, "address": {"city": "上海", "zip": "200000"}, "skills": ["Go", "Rust"]}');-- 查询:-> 返回JSON对象,->> 返回文本SELECT profile -> 'name'AS name_json, profile ->> 'name'AS name_text, profile -> 'address' ->> 'city'AS cityFROM user_profiles;-- 条件查询:包含操作符 @>SELECT * FROM user_profiles WHERE profile @> '{"skills": ["Java"]}';-- JSON路径查询:用 #>> 直接定位SELECT profile #>> '{address,city}' FROM user_profiles;7.2 全文搜索:让数据库变成搜索引擎
PostgreSQL内置了全文搜索引擎,使用tsvector(词位向量)和tsquery(查询表达式)两个核心类型:
-- 创建测试表CREATETABLE articles (idSERIAL PRIMARY KEY, title TEXT,contentTEXT);INSERTINTO articles (title, content) VALUES('PostgreSQL 全文搜索入门', '全文搜索让PostgreSQL能像搜索引擎一样检索文本'),('JSONB 实战指南', 'JSONB类型支持高效的半结构化数据存储和查询');-- 基础全文搜索SELECT title FROM articlesWHERE to_tsvector('english', title || ' ' || content) @@ to_tsquery('english', 'search');-- 最佳实践:创建GIN索引加速全文搜索ALTERTABLE articles ADDCOLUMN search_vector tsvectorGENERATEDALWAYSAS (to_tsvector('english', title || ' ' || content)) STORED;CREATEINDEX idx_articles_search ON articles USING GIN(search_vector);-- 按相关度排序SELECT title, ts_rank(search_vector, query) ASrankFROM articles, to_tsquery('english', 'search') queryWHERE search_vector @@ queryORDERBYrankDESC;GENERATED ALWAYS AS ... STORED是PostgreSQL的一个巧妙设计——生成列自动维护,查询时直接用,不用每次都临时计算,性能和便捷性都兼顾了。
八、Java集成实战
作为Java后端,我们需要把数据库操作融入实际项目中。
这里以Spring Boot + MyBatis Plus为例。
8.1 添加依赖
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- PostgreSQL 驱动 --><dependency><groupId>org.postgresql</groupId><artifactId>postgresql</artifactId><version>42.7.0</version></dependency><!-- MyBatis Plus --><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.7</version></dependency>8.2 配置数据源
spring:datasource:url:jdbc:postgresql://localhost:5432/mydbusername:postgrespassword:your_passworddriver-class-name:org.postgresql.Driver# 连接池配置(推荐HikariCP)datasource:hikari:maximum-pool-size:20minimum-idle:5connection-timeout:30000mybatis-plus:configuration:log-impl:org.apache.ibatis.logging.stdout.StdOutImplglobal-config:db-config:id-type:auto8.3 实体类和Mapper
@Data@TableName("products")publicclassProduct{@TableId(type = IdType.AUTO)private Long id;private String name;private BigDecimal price;private Integer stock;private String category;private List<String> tags; // PostgreSQL原生支持数组}@MapperpublicinterfaceProductMapperextendsBaseMapper<Product> {// 自定义查询:价格范围内的产品@Select("SELECT * FROM products WHERE price BETWEEN #{min} AND #{max}")List<Product> selectByPriceRange(@Param("min") BigDecimal min, @Param("max") BigDecimal max);}8.4 Service层使用
@ServicepublicclassProductService{@Autowiredprivate ProductMapper productMapper;// 分页查询public IPage<Product> pageList(int pageNum, int pageSize){ Page<Product> page = new Page<>(pageNum, pageSize);return productMapper.selectPage(page, null); }// Lambda条件查询public List<Product> getInStockProducts(){ LambdaQueryWrapper<Product> wrapper = new LambdaQueryWrapper<>(); wrapper.gt(Product::getStock, 0) .orderByDesc(Product::getPrice);return productMapper.selectList(wrapper); }// JSONB字段查询(使用原生SQL)@Select("SELECT * FROM products WHERE details @> #{jsonCondition}::jsonb")List<Product> selectByJsonCondition(@Param("jsonCondition") String jsonCondition);}九、PostgreSQL vs MySQL对比
9.1 核心差异一览表
| 核心定位 | ||
| SQL标准兼容 | ||
| 架构模型 | ||
| MVCC实现 | ||
| 可序列化隔离 | ||
| 扩展能力 | ||
| JSON支持 | ||
| 高级SQL | ||
| 开源协议 | ||
| 适用场景 |
PostgreSQL最大的优势在于功能完整性和标准合规性。
PostgreSQL 对 SQL 标准的支持最为完整,这对复杂应用和数据分析至关重要。
国内越来越多的大厂开始从MySQL向PostgreSQL迁移,看中的正是它的SQL标准兼容性和插件扩展能力。
十、优缺点与适用场景
10.1 优点
功能丰富,一库通吃:支持JSON、数组、地理空间、时序数据等多种数据类型 SQL标准兼容度高:迁移成本低,生态工具丰富 数据完整性保障强:原生支持完整外键约束、CHECK约束、排除约束 强大的并发性能:MVCC机制让读写互不阻塞,高并发写入领先于MySQL 扩展性极强:通过插件扩展可实现几乎所有企业级需求 插件生态成熟:PostGIS(地理信息)、pgvector(向量检索)、TimescaleDB(时序数据)等
10.2 缺点
学习曲线陡峭:功能多,每个特性的学习成本也相应增加 默认配置保守:通常需要调优才能发挥最佳性能 社区热点分散:插件多,“最佳实践”不集中 简单查询吞吐量:比MySQL略低(MySQL约20,000 tpmC,PostgreSQL约18,000 tpmC) VACUUM维护成本:MVCC产生的死元组需要定期清理
10.3 适用场景
强烈推荐PostgreSQL的场景:
金融交易、订单系统(需要完整ACID和严格约束) 复杂报表、数据分析系统(需要高级SQL和窗口函数) JSON/半结构化数据存储(利用JSONB+GIN索引) 地理信息系统(PostGIS是行业标准) 全文搜索引擎(内置全文检索,无须Elasticsearch) AI+向量检索应用(借助pgvector扩展) 时序数据监控(借助TimescaleDB)
MySQL更适合的场景:
高并发纯OLTP、简单CRUD的应用 前期快速原型开发(配置简单、生态成熟) 已有成熟的MySQL运维体系和工具链 团队成员对PostgreSQL不熟悉的学习成本问题
总结
MySQL是“菜刀”式的数据库,锋利简单,一招吃遍天。
PostgreSQL是“瑞士军刀”式的数据库。它功能全面但学习门槛高。
没有哪个一定更好,但你需要了解这两把利器的各自神威。
我建议每个Java后端工程师,花两个月时间:
读一遍PostgreSQL官方文档的“SQL Language”和“Server Administration”部分 练一遍CRUD、索引、事务、JSONB、全文搜索所有本章例子的实际操作 想一遍如果在你的业务里用PostgreSQL,架构哪里可以做得更好
当你熟悉了PostgreSQL的这些高级特性,你会发现——原来复杂需求真的可以用数据库一行SQL解决,而不是在业务代码里凑一千行的Java if-else。
这是数据库思维上的根本改变。
我希望这篇文章不仅帮你入了PostgreSQL的门,更帮你打开了多模态数据管理和复杂业务建模的一扇窗。

往 期 推 荐
1、十万个Why:两个字段都建了单列索引,为什么加了 OR,执行计划还是全表扫描?
2、面试官问我:“为什么要用 Spring AI,而不是直接调用大模型?”,我笑了说:因为 Spring AI 解决的不是大模型能不能调用的问题。。
3、忘掉Win 12吧,曝微软要把Win 11打造成本地“龙虾”
4、摊牌了!20年老程序员自曝不再写代码:“如果明天AI编程没了,我就彻底转行”
5、JDK 27 又把 API 砍了俩方法,JEP 531 和 Set.ofLazy() 来了
6、面试官皱眉:“公司项目几百万行代码,Claude Code 怎么扛得住?”我:“换 Opus 4.7”,他叹气:模型是地板,harness 才是天花板
点分享
点收藏
点点赞
点在看
夜雨聆风



