阿里、蚂蚁、晟腾、中科加禾精彩分享 AI 基础设施洞见,现购票可享受 9 折优惠 |AICon 了解详情
写点什么

MongoDB 最常见的 10 个错误说法

  • 2021-01-21
  • 本文字数:4607 字

    阅读完需:约 15 分钟

MongoDB最常见的10个错误说法

我加入 MongoDB 还不到一年,但学到了很多东西。在面试这家公司前,我从未真正使用过 MongoDB,尽管我听过一些有关它的演讲,并且它的简单易用给我留下深刻印象。


但和大多数人一样,我也听说过这些可怕的说法:“它不支持关系模型。如果你想存储文档,那没问题,但如果以后想要进行聚合该怎么办?你将被困在这个错误的数据库里!而且不管怎样,它不支持事务!”


当我开始查找这些信息的来源,才意识到两个问题:首先,这些帖子大多是十年前的,所以他们所说的是一个刚刚推出三年的产品,而不是今天这个成熟、经过实战考验的数据库。其次,他们说的几乎都不再是对的,而且在某些情况下从来都没有对过。


所以我决定做一个演讲(并写了这篇文章)来逐一澄清这些错误的说法。

迷思 0:MongoDB 是 Web 可伸缩的


YouTube 上有个视频,视频里有几只狗(看起来应该是狗吧?)。你可能已经看到了——其中一只是盲目的新技术追随者,它盲目相信 MongoDB,没有真正加以了解。另一只狗比较理性,第一只狗的盲从让它感到沮丧。



在加入 MongoDB 第一天,我的一个朋友给我发了这个视频链接,但此前,我已经看过了。看看日期,这段视频已经流传十多年了。当时真的很有趣,但现在呢?里面几乎所有的东西都过时了。


事实上,MongoDB 公司很多人的 T 恤或笔记本电脑贴纸上都有这个角色,它是 MongoDB 的非官方吉祥物。

MongoDB 到底是什么?


在开始讲“MongoDB 不是什么”之前,我们来总结一下 MongoDB 到底是什么。


MongoDB 是一个分布式文档数据库。集群(我们称之为复本集)大多是自我管理的——当集群中的每台机器都知道了其他服务器的所在,如果其中一个节点宕机或网络出现问题,它们会自动加以处理。如果其中一台机器被关闭或发生崩溃,其他机器会接管。要实现仲裁,群集中至少需要有 3 个节点。集群中的每台服务器都有数据库所有数据的完整副本。



集群是为了冗余,而不是为了可伸缩性。所有的客户端通常只连接到一台服务器——被选举出来的主服务器,它负责执行查询和更新,并将数据变更传输到备用机器。


你可以直接连接到备用服务器做一些有趣的事情,比如运行分析查询。但一般来说,直接连接到备用节点意味着你可能会遇到一些旧数据,所以不应该连接到备用节点,除非你可以接受旧数据。


讲完“分布式”,接下来讲讲“文档数据库”。


MongoDB 与传统关系型数据库的不同之处在于,它不是将数据保存成扁平的行,然后存储在数据库的表中,而是在文档中存储分层结构的数据——基本上与 JSON 对象类似。文档存储在集合中,集合实际上就是一堆文档。每个文档可以具有与集合中其他文档不同的结构或模式。你还可以(而且应该)根据将要运行的查询类型和存储数据对集合中的文档进行索引。如果你想要确保集合中的所有文档都遵循一种结构,可以将 JSON 模式应用于集合,作为验证器。


{   '_id': ObjectId('573a1390f29313caabcd4135'),   'title': 'Blacksmith Scene',   'fullplot': 'A stationary camera looks at a large anvil with a   blacksmith behind it and one on either side.',   'cast': ['Charles Kayser', 'John Ott'],   'countries': ['USA'],   'directors': ['William K.L. Dickson'],   'genres': ['Short'],   'imdb': {'id': 5, 'rating': 6.2, 'votes': 1189},   'released': datetime.datetime(1893, 5, 9, 0, 0),   'runtime': 1,   'year': 1893}
复制代码


上面的文档是一个例子,显示了 1893 年的一部电影的信息!文档是用PyMongo驱动程序获取的。


注意,这里有些值是数组,比如“countries”和“cast”,而有些值是对象(我们称它们为子文档)。这就是 MongoDB 文档的层次结构——它们不像关系数据库中的表行那样扁平。


还需要注意的是,它还包含一个原生 Python datetime 类型的“released”字段,以及一个特殊的 ObjectId 类型的值。或许这个不是真正意义上的 JSON 文档?我们待会再来说这个……


上面的文档是一个例子,显示了 1893 年的一部电影的信息!文档是用PyMongo驱动程序获取的。


注意,这里有些值是数组,比如“countries”和“cast”,而有些值是对象(我们称它们为子文档)。这就是 MongoDB 文档的层次结构——它们不像关系数据库中的表行那样扁平。


还需要注意的是,它还包含一个原生 Python datetime 类型的“released”字段,以及一个特殊的 ObjectId 类型的值。或许这个不是真正意义上的 JSON 文档?我们待会再来说这个……

迷思 1:MongoDB 的版本是 3.2


如果你在 Debian Stretch 上使用apt get mongodb安装 MongoDB,它会安装 3.2 版本。不幸的是,这个版本已经是 5 年前的了!从那时起,已经发布了 5 个主要版本,它们包含大量的新特性,以及安全性、性能和可伸缩性方面的改进。


MongoDB 的当前版本是 4.4(截至 2020 年末)。如果你要安装,应该安装MongoDB社区服务器版,但最好请先了解一下MongoDB Atlas,也就是我们的托管数据库即服务(DBaaS)产品!

迷思 2:MongoDB 是一个 JSON 数据库


你肯定听说过 MongoDB 是一个 JSON 数据库的说法,特别是如果你最近访问过 MongoDB 的主页。



不过,正如前面提到的,MongoDB 不是一个 JSON 数据库。它支持额外的数据类型,比如对象、原生日期对象、更多的数字类型、地理原语和高效的二进制类型等等。


MongoDB 实际上是一个 BSON 数据库。


这似乎是一个微不足道的区别,但却很重要。与基于文本的格式相比,它在存储、传输和遍历方面更高效,而且比 JSON 支持更多的数据类型。


  • MongoDB 存储的是 BSON 文档

  • 用于查找的实际上也是 BSON 文档

  • 结果以 BSON 文档的形式输出

  • BSON 甚至是 MongoDB 的有线协议


如果你习惯了使用 JSON,可以将 MongoDB 看成是 JSON 数据库,这就是为什么我们有时会这样描述它!等你使用 MongoDB 一段时间,就会开始对 BSON 的优势大加赞许。

迷思 3:MongoDB 不支持事务


一些第三方文章将 MongoDB 描述成 BASE 数据库。BASE 是指“基本可用、软状态、最终一致”。


但这不是真的,从来都不是!MongoDB 从来都不是“最终一致”的。对主文档的读写是强一致性的,对单个文档的更新始终是原子的。软状态是指需要持续不断的更新数据,否则数据就会过期,但 MongoDB 并非如此。


最后,如果太多的节点不可用,无法达成仲裁,MongoDB 将进入只读状态(降低可用性)。这是有意这么设计的,因为这样可以确保在出现问题时保持一致性。


MongoDB 是一个 ACID 数据库。它支持原子性、一致性、隔离性和持久性。


对单个文档的更新始终是原子的,从 4.0 版本开始,MongoDB 也支持跨多个文档和集合的事务。从 4.2 开始,甚至支持分片集群的跨分片事务。


虽然 MongoDB 支持事务,但在使用它时仍然要谨慎。事务是以性能为代价的,而且由于 MongoDB 支持丰富的分层文档,如果你的模式设计正确,就没有必要经常跨多个文档更新数据。

迷思 4:MongoDB 不支持关系


关于 MongoDB 另一个过时的说法是,你不能在集合或文档之间建立关系。你可以使用聚合管道来连接文档,它们非常强大,你可以使用直观的查询模型来查询和转换来自多个集合的数据。


MongoDB 从 2.2 开始就支持查找(连接)。


下面的示例文档演示了将订单集合和库存集合连接之后,在返回的订单文档中包含了嵌入到数组的库存文档。



我认为,能够在返回的主文档中嵌入相关文档比在关系连接中为每个关系复制行更直观。

迷思 5:MongoDB 完全是关于分片


你可能听人说过分片是 MongoDB 的一个很酷的特性。这绝对是 MongoDB 的一个很酷的核心特性。


分片是指将数据分成片段,并将每个片段放到不同的复制集或集群中。这是一种处理庞大数据集的技术。MongoDB 可以自动将数据和请求发送到正确的副本集,并将来自多个分片的结果合并起来。


但分片存在一个很根本的问题。


我在前面提到过,副本集的最小节点数是 3,这样才能实现仲裁。在进行分片时,至少需要两个副本集,因此至少需要 6 台服务器。除此之外,你还需要运行多个 mongos 实例。mongos 是分片集群的代理,负责路由请求和响应。要实现高可用性,至少需要两个 mongos 实例。



因此,这意味着一个分片集群最少需要 8 台服务器,每增加一个分片,就会增加至少 3 台服务器。


分片集群还会使数据变得难以管理,并且会限制可执行的查询类型。如果你确实需要进行分片,那么分片对你来说确实是有用的,但更简单的办法是直接升级硬件,通常这样更便宜、更容易。


数据的伸缩主要与 RAM 有关,所以如果可以的话,请购买更多的 RAM。如果 CPU 是瓶颈,那就升级 CPU。如果磁盘容量是个问题,那就买一个更大的磁盘。


MongoDB 的分片功能一直都在,如果对内存的需求超过了一台计算机的容量,可以使用分片。你还可以使用分片功能做一些有趣的事情,比如地理位置固定,可以将用户数据存储在离用户位置更近的地方,从而减少延迟。


在决定使用分片进行数据伸缩时,应该先考虑一下硬件升级是否是一个更有效的选择。


你可以看看 MongoDB Atlas,MongoDB 的托管数据库即服务(DBaaS)产品。MongoDB Atlas 不仅可以在你选择的云平台上托管数据库,还可以根据需要伸缩数据库,保持可用性,同时保持较低的成本。它将负责处理备份和冗余,还提供了额外的功能,如图表、文本搜索、无服务器功能等等。

迷思 6:MongoDB 不安全


关于 MongoDB 的另一个误解,是说它不安全。我个人认为,这对 MongoDB 来说是一种不公平的评判,但不可否认的是,在互联网上有很多不安全的 MongoDB 实例,而且发生了几起涉及数据泄露的事故。


从历史上看,这是由于 MongoDB 的发行方式导致的。一些 Linux 发行版曾经在发行 MongoDB 时启用网络并禁用身份验证。


因此,如果你没有防火墙,或者打开了防火墙上的 MongoDB 端口,那么你的数据就有可能被窃取。现如今,机器人很可能会找到你的数据,把你的数据加密,然后再加上一个文档向你勒索比特币。


我想说的是,如果你将一个不受保护的数据库服务器放到互联网上,那就是你的错——这种情况肯定已经发生过很多次了,而且肯定有办法不让事态变得如此糟糕。


我们对 MongoDB 3.6 的一些默认设置进行了修复。MongoDB 不会连接到网络,除非启用身份验证,或者你给服务器设置了一个特定标志来覆盖这个行为。所以,如果使用不当,仍然可能不安全。不管怎样,你至少要先阅读一下手册。


除此之外,在安全方面,MongoDB 还使用了行业标准,例如使用 TLS 对传输中的数据进行加密,使用 SCRAM-SHA-256 对用户进行安全认证。


MongoDB 还提供了客户端字段级加密(FLE)功能,数据在客户端和传输过程中都是经过加密的。也就是说,如果第三方拿到数据库服务器的访问权限,但没有客户端访问权限,也无法读取加密的数据。

迷思 7:MongoDB 会丢失数据


这在 Hacker News 上是一个很经典的问题。有人发帖子分享他们如何成功地用 MongoDB 开发了一些东西,然后立刻有人评论说:“我知道这个人曾经把 MongoDB 里所有的数据都弄丢了,所以请避免同样的事情发生。”


如果你继续联系这些用户,并让他们提交问题,他们就消失了。


MongoDB 被广泛应用于那些非常关心数据保存问题的行业,从摩根士丹利、巴克莱和汇丰等大型银行,到福布斯等大型出版品牌。我们从未收到过有关大规模数据丢失的报告。如果你确实有关于数据丢失的第一手故事要讲,请向我们反馈,无论你是付费企业用户还是开源用户,我们都会认真对待。

迷思 8:MongoDB 只是一个玩具


看到这里,你就已经知道这是一个迷思了。


MongoDB 是一个用于存储文档的通用数据库,它可以安全、原子地更新数据,可以与其他文档连接,提供了丰富、强大和直观的查询语言。当你的数据规模大到一台机器装不下,可以进行分片,它还支持高级功能,例如用于保护敏感数据的客户端字段级别加密、可以让应用程序立即响应变更数据的变更流


原文链接:


https://developer.mongodb.com/article/everything-you-know-is-wrong

2021-01-21 12:264660
用户头像

发布了 114 篇内容, 共 43.4 次阅读, 收获喜欢 311 次。

关注

评论

发布
暂无评论
发现更多内容

ARTS 打卡第 2 周: 对比法在编程上的具体应用

前行

AI+SaaS,会是微盟们的新法器吗?

自象限

安卓设备文件传输 MacDroid pro for mac激活中文

胖墩儿不胖y

文件传输 Mac 软件 传输文件

超越边界:FaaS 的应用实践和未来展望

SOFAStack

Serverless 架构 开发 Faas 函数

蚂蚁 SOFAServerless 微服务新架构的探索与实践

SOFAStack

Serverless 微服务 开发 应用架构

HarmonyOS元服务开发实践:桌面卡片字典

HarmonyOS开发者

HarmonyOS

如何给application.yml文件的敏感信息加密?

java易二三

Java 编程 程序员 计算机 科技

R语言之数据导出

timerring

R 语言

代码随想录Day50 - 动态规划(十一)

jjn0703

电商秒杀系统架构设计

艾瑾行

架构训练营

我是如何使用Spring Retry减少1000 行代码

小小怪下士

Java spring 程序员

生成式AI技术的应用与发展

百度开发者中心

自然语言处理 #人工智能 ChatGPT 文心一言

Java函数式编程 :为什么要关心Java8

java易二三

Java 编程 程序员 计算机 科技

直播app源码,会话描述协议SDP:高质量平台服务

山东布谷科技

软件开发 数据传输 直播APP源码 sdp 会话描述协议

极狐GitLab 价值流管理之「总时间图」使用指南

极狐GitLab

DevOps gitlab 软件研发 价值流 时间图表

生成式AI将重塑中国云产业

百度开发者中心

智能云 ChatGPT 生成式AI 文心一言

生成式AI:引领未来文案创作新潮流

百度开发者中心

#人工智能 生成式AI 文心一言

生成式AI革新传媒互联网行业

百度开发者中心

媒体 传媒 #人工智能 ChatGPT 文心一言

采购云服务器安全与成本不可兼得?云耀云服务器L或许可以了解一下

轶天下事

快速构建商业模式,企业在云服务器选购上有什么需要注意的?

轶天下事

Java仿抽奖系统

java易二三

Java 编程 程序员 计算机

DaVinci Resolve Studio 18 for Mac 18.5.1中文激活版

mac大玩家j

达芬奇18破解版 达芬奇18 视频调色软件

龙蜥社区标准化SIG举行线下社区标准研讨会,助力开源社区规范发展

OpenAnolis小助手

操作系统 龙蜥社区 硬件兼容性 质量测试 标准化 SIG

流程图&时序图绘制小tips

得物技术

流程图 UML 画图 企业号 8 月 PK 榜

生成式AI:改变未来的创新力量

百度开发者中心

#人工智能 ChatGPT 生成式AI 文心一言

月活近千万,连续365天无故障:货拉拉怎么做稳定性指标度量?

TakinTalks稳定性社区

创建web应用程序,React和Vue怎么选?

没有用户名丶

鹏云网络入选中国信通院《高质量数字化转型产品及服务全景图(2023)》

鹏云网络

数字化转型 云服务 分布式存储 信通院 分布式块存储

适用于各阶段Java程序员的面试备战/避坑指南

程序员小毕

Java 程序员 架构师 java面试 八股文

写得了代码,焊得了板!嵌入式开发工程师必修之代码管理方案(中)

极狐GitLab

git gitlab conan Git-Repo 多仓管理

K8S集群中使用JDOS KMS服务对敏感数据安全加密 | 京东云技术团队

京东科技开发者

数据安全 数据加密 k8s集群 企业号 8 月 PK 榜 KMS

MongoDB最常见的10个错误说法_大数据_Mark Smith_InfoQ精选文章