PostgreSQL 可以替代 MongoDB 吗?

最近,一篇《从 MongoDB 到 PostgreSQL 的大迁移》引发了 MongoDB 用户的关注,在我们的用户群组里有朋友 @flyingcrp 问了这样一个问题 —— 为什么PG上的一个插件或者功能点就能顶的上别人一个完整的产品?当然也有持相反观点的朋友 —— PG的 JSON 性能肯定比不过细分领域的专业产品,这个讨论引起了我的兴趣,这些命题成立吗?

通常来说,讨论性能问题离不开具体的场景。我上一次和 MongoDB 打交道是在 2016 年 —— 我使用 Multicorn FDW 迁移了一套服务于生产在线业务的 MongoDB 到 PostgreSQL。把1TB出头规模的数据,搬到使用同样硬件的 PostgreSQL 上。在迁移的过程中,我对 MongoDB 留下了极差的印象 —— 我花费了很多时间清洗模式错乱的垃圾数据;在性能方面我已经忘掉了具体的数字,但还记得迁移至 PostgreSQL 后,性能有了突飞猛进的改善。之后的这么多年里,我没有再和 MongoDB 打过交道,确实也不知道 MongoDB 后面有没有什么长进。

于是,我做了一些简单的检索与研究,结果发现了一些非常有趣且震惊的结论:

  • 在关于 JSON 存储检索性能上,PG 吊打 MongoDB!
  • MongoDB 在正确性上比 MySQL 还要垃圾得多!
  • MongoDB 已经开始过气,流行度趋势下跌

我在 Reddit 上看到一个帖子,怒斥 MongoDB 的问题,最令我震惊的莫过于 MongoDB 还有这么一段轶事 —— 在 3.2 的时候,拿着嵌入的 PostgreSQL 作为其“分析引擎”。而且做法和我 2016 年搞数据迁移的方式如出一辙 —— 都是用 Multicorn 编写的 FDW。

关于性能

Performance Benchmark: PostgreSQL vs. MongoDB @ 2020

Can PostgreSQL with its JSONB column type replace MongoDB? @ 2023-08

关于正确性

MongoDB and Jepsen

JEPSEN MongoDB 4.2.6

关于流行度

StackOverflow Developer Survey 2017 - 2023

DB-Engine Ranking - Trend Popularity

关于社区

JSON/JSONB, FerretDB, mongo_fdw

The Great Migration from MongoDB to PostgreSQL

关于黑历史

Doubt regarding PostgreSQL vs Mongodb

MongoDB 3.2: Now Powered by PostgreSQL

小结

Why You Should Never Use MongoDB

群友讨论的时候抛出了一个有趣的问题,研究了一下发现 MongoDB 实在是太垃圾了,无论是性能还是正确性都被PG吊打。正好最近喷云厂商太多了,应该回归一下数据库主业,清明节准备写一篇批判 MongoDB 的文章。

看看能不能吸引些 MongoDB 的用户迁移到 PostgreSQL 上来。

迁移完成后测试了一下

我已经忘记具体的性能数字了,只是记得迁移万

性能这种要看具体场景的场景。作为一个特定经验:我在 2016 年的时候用 MongoDB FDW 迁移了一套 MongoDB 到同硬件上的 PG,性能反正好了很多。但这么多年过去了,我也不知道现在 MongoDB 怎么样了。

首先,MongoDB 公司被发现在性能方面大量撒谎。

然后人们发现该产品的数据质量也很差。

然后人们发现“无模式”实际上意味着你拥有数百万个模式。

然后人们发现MongoDB的报告子系统实际上是一个嵌入式的Postgres数据库。

然后人们发现缺乏连接实际上是一个巨大的问题。而且在繁忙的 MongoDB 集群上回填旧数据可能需要数周时间。

最后人们发现,在存储 json 的一系列基准测试中,Postgres 比 MongoDB 更快。

因此,从这一点来看,MongoDB 就像 NoSQL 世界中的 MySQL:有太多谎言、太多夸张、太多坏建议。我们中的许多人都希望永远不再看到 mongodb。

学习如何有效使用文档数据库并不需要成为营销部门的鹦鹉。这意味着了解优势、劣势和设计模式:

数据质量:当 mongodb 复制不是原子的并且您可以覆盖部分记录时 - 您会怎么做?

无模式:实际上意味着“数百万个模式”——每行可能包含不同类型的不同字段。或者您很严格,坚持使用单一模式,并频繁进行模式迁移。这违背了公司的建议,违背了他们的“无模式”公关,并且在大型数据库上可能需要很长时间。

连接:是一种非常强大的适应性功能。最终,大多数人发现他们需要 mongodb 返回包含或被其他数据过滤的文档。例如,不仅要返回交易时的 customer_id,还要返回截至今天的customer_name ?很简单,只需连接到您的客户表即可。当连接速度非常慢时,您将失去大量的灵活性。

在某些时候和某些地方,mongodb 可能有意义。但就像 mysql 的领导层 20 年前告诉大家,90% 的开发人员不需要事务、视图、子选择、联合等一样,MongoDB 给人们带来了很多糟糕的建议。

Last modified 2024-04-15: routine update (612f8ce)