三年,三次迁移,300万行数据

2023年,我们用MongoDB启动了一个社交电商项目。文档模型灵活,开发速度快,第一个月就上线了MVP。

2024年,我们把数据从MongoDB迁移到了PostgreSQL。因为"关系型数据用文档数据库是一个错误"。

2025年底,我们又从PostgreSQL迁移到了SurrealDB。因为"我们需要实时协作功能,而PostgreSQL的JSONB查询太慢了"。

2026年Q2,我们正在考虑回到PostgreSQL。

三次迁移,累计停产时间超过72小时,工程师投入超过600人时,间接损失保守估计超过50万。这些教训,我希望你不用再经历一遍。

第一次翻车:MongoDB的"灵活"是一个陷阱

2023年选择MongoDB的理由非常典型:需求还不明确,Schema频繁变化,文档模型不需要Migration。前三个月,一切都很美好。

第4个月开始出问题。“用户关注”、“订单关联商品”、“评论回复评论” —— 这些关系型数据在MongoDB里实现起来极其痛苦。我们开始用嵌套文档和引用混用的方式"凑合",结果就是:

  • 一个用户文档嵌套了他的前100条评论,但评论表需要支持分页和排序,嵌套文档做不到
  • 订单和商品的关联用引用,但查询"买了商品A的用户还买了什么"需要两次查询,N+1问题严重
  • 聚合管道(Aggregation Pipeline)写起来像在写外星代码,团队里只有一个人能维护

更致命的是:MongoDB的事务支持在2023年已经成熟,但性能糟糕。一个跨3个collection的事务,吞吐量比PostgreSQL低40%。

教训:如果你的数据有任何关系(而99%的商业数据都有关系),不要用MongoDB。 文档数据库适合非结构化数据(日志、IoT数据、爬虫结果),而不是用户-订单-商品这种典型的关系模型。

第二次翻车:PostgreSQL很强,但"银弹"幻觉让我付出了代价

迁移到PostgreSQL之后,前6个月风平浪静。JSONB支持让我们保留了一些灵活的数据结构,关系模型让复杂的JOIN查询变得优雅。

但我们的产品在2025年加入了两个核心功能:实时协作文档编辑(类似Notion)和实时数据看板。PostgreSQL在这里遇到了瓶颈:

  • 实时协作需要频繁的文档更新和冲突解决,PostgreSQL的行锁在高并发写入下成为瓶颈
  • 实时看板需要复杂的聚合查询,虽然PostgreSQL 16的并行查询很强大,但500ms的查询延迟对于实时看板来说太慢了
  • 我们需要WebSocket + 数据库变更推送(CDC),PostgreSQL的LISTEN/NOTIFY在大量订阅者场景下不够稳定

我们开始在外面加Redis做缓存、加Elasticsearch做搜索、加ClickHouse做分析。数据架构从"一个PostgreSQL"变成了"PostgreSQL + Redis + Elasticsearch + ClickHouse + Kafka"。数据同步成了最大的噩梦。

教训:PostgreSQL是一个优秀的OLTP数据库,但它不是OLAP数据库,不是搜索引擎,不是缓存,不是消息队列。 当你发现自己在PostgreSQL上叠了4个外部存储时,你的架构已经失控了。

第三次翻车:SurrealDB的"all-in-one"承诺太美好

2025年底,发现了SurrealDB。它的宣传语击中了我:“一个数据库,替代PostgreSQL + Redis + Elasticsearch + 实时推送。”

SurrealDB支持:SQL-like查询、图查询、实时订阅、全文搜索、内嵌分析。而且它原生支持多租户、权限控制、实时数据推送。这就是我们需要的"银弹"。

迁移花了3个月。上线第一周,一切正常。第二周开始崩了。

  • SurrealDB 2.0的全文搜索在大数据量下性能急剧下降,超过10万条记录的搜索,延迟从50ms飙升到2秒
  • 实时订阅功能在高并发下出现消息丢失,官方文档承认"还在优化中"
  • 图查询的语法极其反直觉,团队学习成本远超预期
  • 社区生态薄弱,遇到问题GitHub Issue的回复周期是1-2周

最致命的是:SurrealDB的查询优化器在复杂查询下表现很差。一个在PostgreSQL上跑200ms的报表查询,在SurrealDB上跑了4秒。我们不得不把分析查询又搬回了PostgreSQL,结果就是两个数据库并行运行,数据同步又是一场噩梦。

教训:数据库的"all-in-one"承诺是一个危险信号。 一个数据库能把一件事做好已经很不容易了,同时做好OLTP、OLAP、搜索、实时推送、图计算——这需要10年以上的工程积累,不是一个新数据库能做到的。

2026年,我总结的数据库选型铁律

铁律一:先搞清楚你的查询模式,再选数据库。 你的核心查询是单条记录读写(OLTP)?还是复杂聚合分析(OLAP)?还是全文搜索?还是图遍历?不同场景对应不同类型的数据库。

铁律二:首选PostgreSQL,除非你有明确的理由不用它。 PostgreSQL在2026年已经是一个"瑞士军刀"级别的数据库:JSONB、全文搜索(pg_trgm)、时序数据(TimescaleDB)、向量搜索(pgvector)、图查询(AGE)、列存储(Hydra)。它可能不是每个场景的最佳选择,但它是"最少犯错"的选择。

铁律三:少于100万用户,不要做多数据库架构。 一个PostgreSQL + 一个Redis能解决99%的问题。那些"大数据架构"的需求,很可能直到你的项目关停都不会到来。

铁律四:新数据库等三年再用。 数据库是基础设施中最不应该追新的部分。SurrealDB在2028年可能非常成熟,但2026年,它不是生产环境的选择。

结尾

三次翻车让我明白了一个道理:数据库选型的失败,从来不是因为数据库本身不行,而是因为你不了解自己的业务。 你不知道你的查询模式是什么,你不知道你的数据模型会长成什么样,你不知道你的规模会到多少。

所以最快的解决方案是:先用PostgreSQL,跑起来,看清楚你的业务真正需要什么,然后再做决策。至少你不会像我一样,三年迁移三次。