
做后端开发这些年,被问到最多的问题之一就是:数据库该怎么选?PostgreSQL、MySQL、NoSQL,这三个词天天挂在嘴边,但真正能说清楚它们区别和适用场景的人其实不多。
最近正好在给团队做技术分享,顺手把相关内容整理成这篇东西,把这些年踩过的坑、总结的经验一次性说清楚。
先说个常见误区:很多人觉得PostgreSQL和MySQL是一类,NoSQL是另一类,它们之间是非此即彼的竞争关系。实际上没这么简单——PostgreSQL和MySQL都是SQL数据库,核心都是关系型那一套;NoSQL则是一个更大的范畴,底下细分了好几种子类型。搞清楚这些,对你做架构决策很重要。
数据库说白了就是存取数据的地方。拿做个电商系统举例:
这些东西你当然可以存txt文件里,但数据库能给你:
现代数据库基本分两大类:
SQL数据库(关系型数据库)
典型代表:
特点:表结构固定、SQL查询、强一致性、表与表之间可以建立关系。
NoSQL数据库
典型代表:
特点:schema灵活、数据模型多样、擅长水平扩展、专为分布式系统设计。
SQL全称是Structured Query Language,翻译过来叫结构化查询语言。SQL数据库把数据组织成表的形式,表和表之间通过外键建立关联。
拿用户表和订单表举例:
用户表
id 姓名 手机号
1 张伟 13800138001
2 王芳 13900139002
订单表
id user_id 金额
101 1 599
102 2 1280
Orders表里的user_id就是外键,指向Users表的id。这种表与表之间的关联关系,就是"关系型数据库"名字的由来。
PostgreSQL(圈子里常叫PG)是个开源的关系型数据库,功能非常全面,被业界称为"最强大的开源数据库"。
它的强项:
很多大厂的核心业务系统都跑在PostgreSQL上,就是因为它既稳定又灵活。
PostgreSQL使用示例:
CREATE TABLE users ( id SERIAL PRIMARY KEY, name VARCHAR(100), email VARCHAR(255) UNIQUE
); INSERT INTO users (name, email)
VALUES ('张伟', 'zhangwei@email.com'); SELECT * FROM users; MySQL是世界上使用最广泛的数据库之一,无数网站和应用靠它撑着。
它能火起来主要因为:
早年PHP、WordPress、Laravel这些技术栈在国内刚兴起的时候,基本都是搭配MySQL用的。
MySQL使用示例:
CREATE TABLE users ( id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(100), email VARCHAR(255) UNIQUE
); INSERT INTO users (name, email)
VALUES ('张伟', 'zhangwei@email.com'); SELECT * FROM users; 看这几段代码,PostgreSQL和MySQL的写法几乎一模一样。没错,因为它们都是SQL数据库,用的是同一套查询语言。
NoSQL的全称是"Not Only SQL",意思是"不仅仅是SQL"。
NoSQL数据库不依赖传统的表结构,可能用文档、键值对、图、宽列等方式存储数据,追求的是灵活性和横向扩展能力。
文档数据库
代表:MongoDB
数据以类JSON的文档形式存储:
{ "id": 1, "name": "张伟", "email": "zhangwei@email.com"
} 键值数据库
代表:Redis
user:1 -> 张伟
user:2 -> 王芳 性能极高,常用于缓存、会话存储、实时排行榜这类场景。
宽列数据库
代表:Cassandra
专为超大规模、高可用、分布式场景设计,比如微博热搜这种瞬时流量。
图数据库
代表:Neo4j
直接存储实体之间的关系,适合做社交网络、推荐系统、风控这些需要深度关联分析的场景。
这两个数据库的共同点很多:
同样的查询,两边都能跑:
SELECT users.name, orders.amount
FROM users
JOIN orders
ON users.id = orders.user_id; 标准兼容性
PostgreSQL严格遵循SQL标准,MySQL早年更注重速度和简单,标准兼容这块没那么讲究。
胜出:PostgreSQL
高级特性
PostgreSQL支持的功能更丰富:窗口函数、物化视图、原生JSON支持、高级索引、自定义数据类型等。
SELECT name, salary, RANK() OVER ( ORDER BY salary DESC ) AS ranking
FROM employees; 这种窗口函数查询,在MySQL里要到8.0才支持,而且语法和PG不太一样。
胜出:PostgreSQL
上手难度
MySQL对新手更友好,基本配置好就能跑起来。
胜出:MySQL
复杂查询
数据分析、报表、数据仓库这类场景,PostgreSQL明显更强。
胜出:PostgreSQL
Web应用
传统Web托管环境里,MySQL的生态积累更深。
胜出:MySQL
性能表现
这个真要看具体场景:
结论:视情况而定
这才是真正两个世界的碰撞。
数据结构
PostgreSQL:固定schema,每一行必须符合表定义
CREATE TABLE users ( id INT, name VARCHAR(100)
); NoSQL:灵活schema,同一个集合里可以有不同的结构
文档1:
{ "name": "张伟"
} 文档2:
{ "name": "王芳", "phone": "13800138000"
} 关联关系
PostgreSQL:表与表通过外键连接,关联查询能力强
NoSQL:通常把关联数据嵌入到一个文档里,比如:
{ "user": "张伟", "orders": [ { "id": 1, "amount": 599 } ]
} 一致性
PostgreSQL:强一致性,每次事务都能保证数据准确。
NoSQL:很多NoSQL数据库为了可用性和扩展性,会牺牲一部分一致性,这是CAP定理的权衡。
扩展方式
PostgreSQL:传统上靠纵向扩展——加CPU、加内存、换更好的服务器。近几年也开始支持一些横向扩展能力。
NoSQL:从娘胎里就是为横向扩展设计的,数据自动分散到多台机器上。
场景一:银行核心系统
需求:精确的账户余额、事务原子性、完整的审计日志、不能丢一分钱。
选型:PostgreSQL
原因:金融系统对数据完整性要求极高,强一致性是刚需。
场景二:短视频平台
需求:海量用户生成内容、海量点赞评论、用户资料字段随时可能增加(比如加个"兴趣标签"字段)。
选型:MongoDB或DynamoDB
原因:横向扩展能力强,schema灵活,不用因为产品经理加个字段就改表结构。
PostgreSQL这几年越来越火,有个重要原因:它不是非此即彼。
它既能做传统关系型的事,也能存文档:
CREATE TABLE products ( id SERIAL PRIMARY KEY, details JSONB
); INSERT INTO products(details)
VALUES (
'{ "name": "小米15", "brand": "小米", "ram": "16GB"
}'
); SELECT details->>'brand'
FROM products; 这种JSONB类型的字段,让PostgreSQL既有SQL的严谨,又有了文档数据库的灵活性。很多场景下,你不需要引入额外的MongoDB。
特性 PostgreSQL MySQL NoSQL
SQL支持 是 是 通常否
固定Schema 是 是 可选
ACID事务 优秀 优秀 因库而异
复杂查询 优秀 良好 有限
JOIN支持 优秀 优秀 通常有限
横向扩展 良好 良好 优秀
灵活数据 良好(JSONB) 有限 优秀
数据分析 优秀 良好 因库而异
学习曲线 中等 简单 中等
数据完整性 优秀 优秀 因库而异
选PG的场景:
选MySQL的场景:
选NoSQL的场景:
其实现在纠结"SQL还是NoSQL"意义不大了。成熟的技术团队,往往是组合拳:
PostgreSQL:存用户、订单、支付这些核心业务数据
Redis:做缓存、存session、秒杀计数器
MongoDB:存用户的动态feed、非结构化的内容数据
这种用不同数据库处理不同需求的策略,有个专门的名字叫Polyglot Persistence(多语言持久化)。没有银弹,扬长避短才是正道。
如果你现在要起一个新项目,不知道该选哪个数据库,我建议把PostgreSQL作为默认选项。
重视数据正确性、灵活性、想要一套方案解决大部分问题——PostgreSQL。
团队传统Web背景深、WordPress/Laravel老项目维护——MySQL。
业务量级大到单库扛不住、字段天天加——NoSQL(或者PG+JSONB先试试)。
记住这句话:最好的数据库不是功能最多的那个,而是最匹配你业务需求的那个。搞懂PostgreSQL、MySQL、NoSQL各自的长处和取舍,你做技术决策的时候才能心里有底。