为什么我从 MongoDB 迁移到 PostgreSQL
我的第一个以 MongoDB 作为主数据库开发的网站是 codecampo.com(2011 年),第二个是 writings.io(2013 年)。Campo 在第 3 版的时候重写(2014 年)迁移到 PostgreSQL,而 writings.io 已经关闭了,现在正在做的创业项目 selfstore.io 也是使用 PostgreSQ
我的第一个以 MongoDB 作为主数据库开发的网站是 codecampo.com(2011 年),第二个是 writings.io(2013 年)。Campo 在第 3 版的时候重写(2014 年)迁移到 PostgreSQL,而 writings.io 已经关闭了,现在正在做的创业项目 selfstore.io 也是使用 PostgreSQL。PostgreSQL 已经成为我的默认数据库,鉴于我曾经做过一段时间 MongoDB 布道者,所以我想有必要总结一下。
我开发维护的都是流量很小的网站,所以不用期待我分享千万级数据管理的经验(我以前正式工作中倒是接触一个千万级使用 MySQL 的网站,但优化工作不是我做的)。我也不会犯一些低级错误,例如项目开发到一半才困惑“MongoDB 没有 JOIN 查询怎么办?”,选型时已经知道将要面临怎样思维转换。
我不希望这篇文章被当作是“XX 已死,YY 永生”一类的噱头文章,这类文章大多带有偏见,并且对评论对象浅尝辄止。不同的工具有不同的应用场合,不能一概而论。
我从 MySQL 转向 MongoDB,以及从 MongoDB 转向 PostgreSQL 的最大原因都是:有趣。Web 开发一个优点就是你不用限定在某个平台某类技术上,最终用户看到的都是 HTML 页面。
下面是一些我选择数据库的经验。
MongoDB 优点
无模式
无模式是个双面刃。好的方面,它可以减少表的空余字段,减少拆表的必要,例如用户集合可以一条记录带有 admin: true
属性,其他不带有这个属性,而在关系数据库中这类带来大量空余字段的属性最好拆表。PostgreSQL 打开 HStore 扩展后也可以实现这样的结构。如果觉得 admin: true
的例子太简单,可以考虑下怎么储存 gemspec 的内容并让它可索引。
无模式另一个好处是让代码逻辑管理起来更清晰,可以把属性定义和模型逻辑放在一起:
class Artist include Mongoid::Document field :name, type: String end
类似 DataMapper 的库虽然也能实现这样的语法,但始终需要维护一个迁移脚本,需要重复自己。用 Mongoid 的时候我一直觉得打开 Model 文件先看到属性定义很舒服。
无模式的最大坏处就是无法真正掌握数据库中有什么内容,实际上并不是经常需要储存无模式数据,多数是模式化数据。所以即使不需要管理模式迁移,还是要管理数据迁移,每次更改属性相关逻辑时要写数据迁移脚本。这里无模式是好是坏取决于应用场景。
数据类型
MongoDB 支持的数据类型多于 MySQL,其中最主要是 Array,Hash 类型。PostgreSQL 原生或通过扩展可以支持 Array 和 Hash,但是配套的操作不够 MongoDB 简便。
例如 MongoDB 对 Array 有一个 $addToSet
方法,只有数组不存在某元素时进行插入:
update( $addToSet: { upvotes_ids: 1 } )
而 PostgreSQL 要进行同样操作需要组合一些语句:
SET upvotes_ids = array_append(upvotes_ids ,1) WHERE NOT (upvotes_ids @>array[1])
MongoDB 的语句更简洁,也不排除 PostgreSQL 以后也会添加同样的方法。
MongoDB 缺点
不支持事务
也许需不需要数据库事务成了是否选择 MongoDB 的决定性因素,MongoDB 不支持数据库事务。
有很多应用对数据一致性其实要求不高,例如很多社交应用,大多数应用逻辑只是简单存取(发一段文字,上传一张照片),极少的不一致是不影响应用的。而一些严肃应用,例如交易系统,就很需要数据库事务的支持了,否则就需要在应用层自己实现一个粗糙的、充满 Bug 的事务支持。如果有兴趣自己实现事务操作,可以看 MongoDB 的文章 Perform Two Phase Commits。
如果有跨系统的事务操作,就不能完全依赖数据库事务,还要有应用层的重试或回滚操作(例如远程调用支付接口)。数据库层面支持事务的话,起码让维护系统内部数据一致性更轻松。
查询语法
MongoDB 的原生查询语法是 JavaScript,JavaScript 程序员可能对此欣喜若狂。我最初感觉也是很新鲜,但久了就觉得很烦躁。JavaScript 太多的括号和花括号,在组合多个查询条件的时候作括号匹配很费神。SQL 是一个查询 DSL,虽然看起来有点古老,但是在查询这个特定领域上做得很好。
如果应用使用 ORM,可能很多时候不需要写原生查询语句。除了 PHP 社区外,其他社区也不推荐写原生查询。不过少数情况下,复杂查询还是原生语句更高效,而且数据库终端也是调试查询错误的最终手段,所以查询语法至少不能让人难受。
默认不安全
MongoDB 的开发者假设你是一个资深系统管理员,并且把 MongoDB 部署在安全的内部网络当中,所以他们官方安装包内含的配置没有设置任何安全验证,接收任何来源的访问,结果就是一些初级系统管理员(例如我)把 MongoDB 直接暴露到了公网,造成数据泄漏。
这不仅是 MongoDB 的问题,Redis、Elasticsearch 也是这样,姑且把这认为是一种设计“哲学”。Ubuntu 的软件源管理者不认同这个“哲学”,从软件源安装的 MongoDB 的默认只接受本地连接,这保护了一些初级系统管理员,但如果追新使用数据库开发方的安装包就会中招。顺便一提,PostgreSQL 默认配置只接受本地连接。
无论用什么数据库都好,使用前一定要完整读一遍文档,特别是设置和安全相关的章节,同时设置系统防火墙。
库
MongoDB 的官方驱动更新没有问题,不过一般不会直接使用驱动写程序(写过,很繁琐),而是使用 ODM(对象-文档映射)工具,在 Ruby 中就是 Mongoid。
Mongoid 已经做得很好,提供了类似 ActiveRecord 的 API,并且很好的利用了 MongoDB 的特性,但在关注度和社区规模上还不及 ActiveRecord。ActiveRecord 作为 Rails 的默认组件,每次都是跟随 Rails 的更新同时更新的,Mongoid 则要滞后一段时间。所以如果你希望紧跟 Rails 的更新,那么最好使用 ActiveRecord 和关系数据库。
为什么是 PostgreSQL 而不是 MySQL/MariaDB
今年开始,我的精力投入到一个交易网站的开发,所以一开始就打算迁移到关系数据库。至于为什么用 PostgreSQL 而不是 MySQL/MariaDB,有几个理由:
- 有趣,我还没用过 PostgreSQL。
- PostgreSQL 的数据类型更多,我主要需要 Array 和 HStore。这些数据类型可以减少开发量,在 MySQL 实现 Tag 属性需要多两张表。
- 过去的工作中让我接触到 MySQL 不好的一面,例如因为 JOIN 性能不好(我没验证过),不允许用
includes
方法,基本上只做主键查询,所以我之前那么容易接受 MongoDB。 - MySQL 被 Oracle 收购后社区出现分裂(MariaDB),我对 Oracle 印象也不好,前公司旗下一个网站因为域名带有 Java 而收到律师函,所以我尽可能避开 Oracle 的产品。
- PostgreSQL 的社区热度在增加,ActiveRecord 对其特性的支持也在完善。
基于以上理由,我选择了 PostgreSQL,目前为止工作得很好。
总结
这几年间我接触了 3 个数据库(不包括 Redis 的话),SQL-NoSQL-SQL 的切换让我对数据库有了更深刻的理解,也认识到还有很多类型数据库我没试过,关系数据库不是唯一选择。我的几个项目都是只是玩具规模,没什么说服力,但以免被误解,还是提几条建议:
- 如果当前数据库用得很好,就没必要更换。
- 如果没有明确的数据库需求,那么用关系数据库。
- 如果要开发新的项目,推荐 PostgreSQL。
最终,选择要取决于你的应用场景。
原文地址:为什么我从 MongoDB 迁移到 PostgreSQL, 感谢原作者分享。

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

Coinbase安全登录指南:如何避免钓鱼网站和诈骗? 网络钓鱼和诈骗日益猖獗,安全访问Coinbase官方登录入口至关重要。本文提供实用指南,帮助用户安全地找到并使用Coinbase最新官方登录入口,保护数字资产安全。我们将介绍如何识别钓鱼网站,以及如何通过官方网站、移动应用或可信第三方平台安全登录,并提供加强账户安全的建议,例如使用强密码和启用双重验证。 避免因错误登录导致资产损失,请务必仔细阅读本文!

本文详细介绍了如何在欧易OKX交易所官网注册账户,并开始加密货币交易。欧易作为全球领先的加密货币交易所,提供丰富的交易品种、多种交易方式和强大的安全保障,并支持多种法币和加密货币的便捷出金。文章涵盖了欧易官网注册入口查找方法、详细注册步骤(包括邮箱/手机注册、信息填写、验证码验证等),以及注册后的注意事项(KYC认证、安全设置等),并解答了常见问题,帮助新手用户快速安全地完成欧易账户注册,开启加密货币投资之旅。

在数字货币交易中,安全至关重要。 由于网络钓鱼盛行,找到欧易OKX官方入口地址和官方链接至关重要,错误链接可能导致账户被盗、资产损失和身份盗用。本文将提供安全访问欧易OKX官方平台的全面指南,帮助用户识别并避免钓鱼网站,保护数字资产安全。 我们将介绍如何通过官方网站、官方应用、官方社交媒体账号以及其他可信渠道确认欧易OKX官方入口,并提供重要的安全提示,例如避免不明链接、使用强密码和启用双重验证等,确保您的交易安全可靠。

在数字货币交易日益火热的今天,选择安全可靠的交易平台至关重要。OKX作为全球领先的数字资产交易所,其安全性备受关注。然而,众多钓鱼网站冒充OKX官方,导致用户面临账户安全和资产损失的风险。本文将为您详细讲解如何识别并访问真正的欧易OKX官方网站及APP入口,避免钓鱼网站陷阱,保障您的数字资产安全。 通过官方网站验证、官方App下载、官方社交媒体渠道以及官方客服咨询等多种途径,您可以有效识别并访问OKX官方平台,确保您的交易安全。 请务必仔细核对域名、检查HTTPS协议,并提高网络安全意识,保

BitMEX作为老牌加密货币衍生品交易平台,其官方网站入口的准确性至关重要。由于钓鱼网站猖獗,误入假冒网站可能导致账户被盗和资金损失。本文旨在指导用户安全访问BitMEX官方网站,提供通过可信加密货币信息平台(如CoinMarketCap、CoinGecko)、官方社交媒体、验证现有地址及官方支持渠道等多种方法,并强调启用双重验证、定期更改密码及使用安全软件等安全措施,帮助用户有效规避风险,保障账户安全。

Gate.io芝麻开门交易所App下载指南:本文详解Gate.io交易所官方App下载方法,助您随时随地进行加密货币交易。Gate.io App拥有便捷性、良好用户体验、全面功能(现货、合约、杠杆、理财等)和强大的安全性等优势,并提供实时行情信息。 为保障安全,请务必从Gate.io官网下载App,避免下载恶意软件。文章详细介绍了官网下载步骤及iOS、Android安装流程,并提供常见问题解答及安全建议,帮助您快速上手Gate.io App,开启安全便捷的加密货币交易之旅。

本文旨在指导用户安全注册币安交易所网页版,开启数字资产之旅。币安作为全球领先的加密货币交易所,拥有庞大的用户群体和丰富的交易品种,其优势包括:全球领先的交易量、丰富的币种选择、多元化的交易产品、强大的安全保障、便捷的出金体验以及活跃的社区和完善的生态系统。文章将详细介绍通过官方渠道注册币安的步骤,并强调注册后完成身份认证(KYC)、开启双重验证(2FA)以及设置资金密码等安全措施的重要性,提醒用户警惕钓鱼网站和诈骗信息,理性投资。

本文介绍如何下载Gate.io(芝麻开门)交易所官方App,助您随时随地进行加密货币交易。Gate.io App优势在于便捷性、流畅的用户体验、全面的交易功能(现货、合约、杠杆、理财等)以及强大的安全性,并提供实时行情信息。文章详细讲解了通过官网下载App的步骤,包括Android和iOS系统的安装方法,并特别强调了从官方渠道下载的重要性,以避免恶意软件。此外,文章还提供了常见问题解答及安全建议,帮助用户顺利完成下载和安装,保障账户安全。 选择Gate.io,开启您的加密货币投资之旅!
