数据库选型:MySQL、PostgreSQL、MongoDB
能够支撑实时业务的数据库,常见的数据库有:
关系型数据库:MySQL、PostgreSQL,以及Oracle、DB2、Microsoft SQL Server等
非关系型数据库:MongoDB
下面针对MySQL、PostgreSQL、MongoDB做对比分析。
关于最受欢迎排行榜,该三类数据库处于前五位置,也是霸榜颇久。另外补充数据库市场份额如下:
概要分析如下:
基本特点 | 优势 | 发展趋势 | |
---|---|---|---|
MySQL | 常用关系型数据库,速度快、易于使用,出道早 | 适用于大量事务处理 | |
PostgreSQL | 功能更强大,支持更多的数据类型和约束 | 适用于复杂查询 | 不断改进其 JSON 能力,如索引、查询优化和更多操作符 |
MongoDB | 非关系型数据库 | 适用于海量非结构化数据 | 增加了多文档 ACID 事务、二级索引和高级查询功能,变得更像传统关系型数据库 |
接下来做多维度交叉对比,包括:
-
许可证、社区生态
MySQL、Postgres、MongoDB 都允许商业应用。 -
数据模型支持 Data Model Support
MySQL、Postgres 是关系型数据库。关系数据库存储数据很规则,必须是表格的形式,且表格的结构需要事先定义好,每个字段的数据类型、长度需要明确,因此需要按照业务数据提前规划schema、table、column(遵循数据设计范式去做表设计),这样做的好处是表内的一切都井井有条、很清晰,坏处就是很繁琐。
Postgres额外支持复杂数据类型如:数组、JSON、XML、GIS等,能满足半结构化数据。
mongodb是面向文档的数据库,是一种非关系数据库,最常见的作用是在某些领域作为关系数据库的替代品,相较于关系数据库它在性能上更有优势,因为不对事务以及数据完整性有硬性要求,所以在写入数据时效率更高。同时,mongdb的数据存储结构也比较灵活,只要是一个json结构就可以存储,相较于关系数据库的表结构定义,更加快捷方便,一切约束全靠程序员自身。mongodb的这种随意性也是把双刃剑,尤其当项目涉及的开发人员越多,需求变化越频繁,mongodb存储的数据就越容易变成一个屎坑,你无法完全知道某一个集合中的文档哪些字段是有用的,哪些字段是没用的,你的程序不得不去配合这些未知的数据,从而造成不必要的繁琐,以及带来更多的BUG。因此,mongodb不建议像关系数据库那样独立使用,必须在代码层做好数据模型定义,才能发挥作用同时避免副作用。 -
性能 Performance
性能主要由访问模式决定。如果一个操作涉及不同的实体,MongoDB 通常更快,因为数据是 denormalized 的,并且不需要在表之间进行复杂的连接操作。另一方面,Postgres 能处理复杂查询,这得益于 SQL 和其先进的查询优化器。 -
可靠性 Reliability
MySQL、Postgres有成熟可靠的主从方案、集群方案。MongoDB 在早期因为不支持 ACID 事务而被认为是不太靠谱的。不过自从他们收购了 WiredTiger 并使用其 WiredTiger 存储引擎后,从事务角度来看,如今的 MongoDB也是稳定可靠的(因为还存在着MongoDB不稳定会丢数据的说法) -
拓展性 Extensibility
MongoDB 是一个支持自动分片的分布式数据库。MySQL、Postgres本身不支持水平拓展,需要依赖分库分表工具,而按照微服务最佳实践,应该先做垂直拆分,再考虑水平拓展。分库分表工具常见:sharding-sphere(前身是sharding-jdbc)、TDDL(Taobao Distribute Data Layer)、Mycat;PostgreSQL也有轻量级的分库分表解决方案citus插件。
当然也有成熟的分布式数据库方案,把分库操作对业务系统透明化、下沉到运维,如TDSQL、Greenplum、PolarDB等等 -
易用性 Usability
MySQL作为传统的关系型数据库,其基本功能完善,能满足极大部分微服务场景,且很容易上手。
PostgreSQL作为可替代MySQL的产品,其功能要比MySQL强大不少,查询能力也更强悍,且组件工具生态活跃,上手门槛比MySQL稍高些。
MongoDB而在处理复杂查询方面,MQL (MongoDB Query Language) 不如 SQL 强大,多表连接查询时速度慢因此不适用于关系多的数据。
综上,三者比较如下:
MySQL | PostgreSQL | MongoDB | |
---|---|---|---|
许可证 | GPL | Postgres协议(类似MIT) | Server Side Public License (SSPL) |
社区生态 | 有多个开源分支 | 由社区维护,近年来,生态系统蓬勃发展,拥有众多插件 | 由商业开源企业牵头,收购过多个生态系统解决方案,包括WiredTiger存储引擎、mLab托管服务、Realm移动端数据同步方案、Compass MongoDB GUI 客户端 |
数据模型规范 | 表格模型 | 表格模型 | 文档对象模型 |
下面在适用性方面,列举了几个常见的业务场景:
场景 | MySQL | PostgreSQL | MongoDB | 备注 |
---|---|---|---|---|
微服务系统 | 非常适用 | 非常适用 | 不建议 | 微服务的数据往往是垂直拆分出来的,具有业务聚合特点,数据之间也会有较高的关联性,且对数据库操作耗时敏感 |
爬虫 | 一般 | 非常适用 | 适用 | 爬虫数据较复杂,可能是能结构化的数据,也可能是灵活的键值对(一般序列化为json),也可能是复杂格式(如GIS信息),且数据间往往有关联,另外需要考虑数据量预留水平拓展能力 |
单体系统 | 非常适用 | 非常适用 | 适用 | 单体系统趋势是垂直拆分,将不可避免地向关系型数据库发展 |
某垂直领域的大批数据 | 一般 | 适合 | 适用 | 这类数据是粒度较精细、关联较小的数据集,例如订单信息、用户的特征数据等,需要综合考虑数据量、业务时效性、查询复杂性。可能会更考虑redis、ES |
数据分析(数据集市) | 一般 | 适用 | 适用 | 三者之间PostgreSQL可能是最适合的,因为其查询功能强、支持的数据类型更多。但是这属于大数据领域,适用Hadoop、Hbase等方案会更主流些 |
最后简单地做一下交叉对比:
MySQL vs PostgreSQL : 都是关系型数据库,都能满足线上业务需求;MySQL较早落地推广(赶了个早市),PostgreSQL功能稍强大(对数据分析场景会更友好些)。
MySQL vs MongoDB :可以看做是传统的关系型数据库与NoSQL的对比,具体场景具体分析
MongoDB vs PostgreSQL : 有说法是可以互相替换,因为PostgreSQL也能支持非结构化的json数据,该说法算是给PostgreSQL加分了。这里建议重点考量数据关联性
备注1、MongoDB可能会有些负面的说法:
- 模式自由,自由灵活的文件存储格式带来的数据错误
- 不支持事务操作 (实际上,大概2018年MongoDB 4.0开始支持ACID事务了)
- 占用空间过大
- MongoDB没有如MySQL那样成熟的维护工具 (实际上,MongoDB也有不少GUI可视化客户端管理工具)
- 无法进行关联表查询,不适用于关系多的数据;复杂聚合操作通过mapreduce创建,速度慢