在开始使用 MongoDB 之前我希望知道的 14 件事

文章的翻译是在课程开始前夕准备的 “非关系型数据库”.

在开始使用 MongoDB 之前我希望知道的 14 件事

亮点:

  • 开发模式极其重要,尽管它在 MongoDB 中是可选的。
  • 同样,索引必须与您的架构和访问模式相匹配。
  • 避免使用大对象和大数组。
  • 请小心 MongoDB 设置,尤其是在安全性和可靠性方面。
  • MongoDB没有查询优化器,因此在执行查询操作时必须小心。

我已经使用数据库很长时间了,但直到最近才发现 MongoDB。 在我开始使用它之前,我希望我知道一些事情。 当一个人已经在某个领域有了经验时,他们就会对数据库是什么以及数据库做什么有先入为主的观念。 为了让其他人更容易理解,我列出了常见错误的列表。

创建无需身份验证的 MongoDB 服务器

不幸的是,MongoDB 默认安装时没有进行身份验证。 对于本地访问的工作站来说,这种做法很正常。 但由于 MongoDB 是一个多用户系统,喜欢使用大量内存,因此最好将其放在具有尽可能多 RAM 的服务器上,即使您只是将其用于开发。 通过默认端口在服务器上安装可能会出现问题,特别是如果可以在请求中执行任何 javascript 代码(例如, $where 作为一个想法 注射).

有多种身份验证方法,但最简单的方法是设置用户 ID/密码。 当您考虑基于以下内容的花哨身份验证时,请使用这个想法 LDAP的。 在安全性方面,MongoDB 应不断更新,并且应始终检查日志是否存在未经授权的访问。 例如,我喜欢选择不同的端口作为默认端口。

不要忘记将攻击面绑定到 MongoDB

MongoDB 安全检查表 包含降低网络入侵和数据泄露风险的好技巧。 人们很容易忽视这一点并说开发服务器不需要高级别的安全性。 然而,事情并没有那么简单,这适用于所有 MongoDB 服务器。 特别是,如果没有令人信服的理由使用 mapReduce, group или $哪里,您需要通过在配置文件中写入来禁用JavaScript中任意代码的使用 javascriptEnabled:false。 由于标准 MongoDB 中的数据文件未加密,因此使用以下命令运行 MongoDB 是有意义的 专用用户,它具有对文件的完全访问权限,仅对文件具有有限访问权限,并且能够使用操作系统自己的文件访问控制。

开发电路时出错

MongoDB 不使用模式。 但这并不意味着不需要该方案。 如果您只想存储没有任何一致模式的文档,那么存储它们可以快速且轻松,但以后检索它们可能会很困难。 该死的很难.

经典文章》MongoDB 架构设计的 6 条经验法则” 值得一读,其功能如下 架构浏览器 在第三方工具Studio 3T中,值得使用它来定期检查电路。

不要忘记排序顺序

与任何其他不正确的配置相比,忘记排序顺序可能会导致更多的挫败感并浪费更多的时间。 默认情况下 MongoBD 使用 二进制排序。 但它不太可能对任何人都有用。 早在上世纪 80 年代,区分大小写、区分重音、二元排序与珠子、长袍和卷曲小胡子一样,都被认为是奇怪的不合时宜的东西。 现在它们的使用是不可原谅的。 在现实生活中,“摩托车”与“摩托车”是一样的。 “英国”和“不列颠”是同一个地方。 小写字母只是大写字母的等效形式。 别让我开始对变音符号进行排序。 在 MongoDB 中创建数据库时,使用不区分重音的排序规则 登记,对应于语言和 系统用户文化。 这将使搜索字符串数据变得更加容易。

创建包含大型文档的集合

MongoDB 很乐意在集合中托管高达 16MB 的大型文档,并且 网格FS 专为大于 16 MB 的大型文档而设计。 但仅仅因为可以放置大型文档,就将它们存储在那里并不是一个好主意。 如果您存储大小为几千字节的单个文档,并将它们更像是宽 SQL 表中的行,那么 MongoDB 将发挥最佳作用。 大型文档将成为问题的根源 表现.

使用大型数组创建文档

文档可以包含数组。 数组中元素的数量最好远离四位数。 如果频繁地将元素添加到数组中,它将超出包含它的文档,并且需要 移动,这意味着有必要 也更新索引。 当使用大数组重新索引文档时,索引通常会被覆盖,因为存在 记录,它存储其索引。 当插入或删除文档时也会发生这种重新索引。

MongoDB 有一个叫做 “填充因子”,这为文档增长提供了空间,以最大限度地减少此问题。
您可能认为无需数组索引即可完成。 不幸的是,缺少索引可能会导致您遇到其他问题。 由于文档是从头到尾扫描的,因此搜索数组末尾的元素将花费更长的时间,并且与此类文档相关的大多数操作将是 慢的.

不要忘记聚合中阶段的顺序很重要

在具有查询优化器的数据库系统中,您编写的查询是对您想要获取什么的解释,而不是如何获取它。 这种机制的运作方式与在餐厅点餐类似:通常你只是简单点菜,而不向厨师给出详细的指示。

在 MongoDB 中,您指导厨师。 例如,您需要确保数据通过 reduce 尽早在管道中使用 $match и $project,并且排序仅发生在 reduce,并且搜索完全按照您想要的顺序进行。 拥有一个可以消除不必要的工作、以最佳方式排列步骤并选择连接类型的查询优化器可能会让您感到厌烦。 使用 MongoDB,您可以以牺牲便利为代价获得更多控制权。

类似的工具 工作室3T 将简化聚合查询的构造 MongoDB的。 聚合编辑器功能允许您一次应用一个阶段的管道语句,并检查每个阶段的输入和输出数据,以便于调试。

使用快速录音

切勿将 MongoDB 写入选项设置为具有高速度但低可靠性。 这种模式 “一劳永逸” 看起来很快,因为命令在写入发生之前返回。 如果系统在数据写入磁盘之前崩溃,数据将会丢失并最终处于不一致的状态。 幸运的是,64 位 MongoDB 启用了日志记录。

MMAPv1 和 WiredTiger 存储引擎使用日志记录来防止这种情况,尽管 WiredTiger 可以恢复到最后一致的状态 控制点,如果禁用日志记录。

日记可确保数据库在恢复后处于一致状态,并保留所有数据直到将其写入日记。 记录的频率使用参数配置 commitIntervalMs.

为了确保条目的正确性,请确保在配置文件中启用了日志记录 (storage.journal.enabled),记录的频率对应于您可以承受丢失的信息量。

无索引排序

在搜索和聚合时,经常需要对数据进行排序。 我们希望这是在过滤结果之后的最后阶段之一完成的,以减少排序的数据量。 即使在这种情况下,为了排序你也需要 指数。 您可以使用单一索引或复合索引。

如果没有合适的索引,MongoDB 就不用它了。 所有文档的总大小的内存限制为 32 MB 排序操作,如果 MongoDB 达到这个限制,那么它要么抛出错误,要么返回 空记录集.

不支持索引的搜索

搜索查询执行的功能类似于 SQL 中的 JOIN 操作。 为了最好地工作,他们需要用作外键的键值的索引。 这并不明显,因为使用没有体现在 explain()。 这些索引是除了写入的索引之外的 explain(),依次由管道操作员使用 $match и $sort,当它们在管道的开头相遇时。 索引现在可以覆盖任何阶段 聚合管道.

选择不使用多重更新

方法 db.collection.update() 用于更改现有文档的一部分或整个文档,直至完全替换,具体取决于您指定的参数 update。 不太明显的是,除非您设置选项,否则它不会处理集合中的所有文档 multi 更新所有符合请求标准的文档。

不要忘记哈希表中键的顺序的重要性

在 JSON 中,对象由大小为零或多个名称/值对的无序集合组成,其中名称是字符串,值是字符串、数字、布尔值、null、对象或数组。

不幸的是,BSON 在搜索时非常强调顺序。 在 MongoDB 中,内置对象中键的顺序 事项{ firstname: "Phil", surname: "factor" } - 不一样 { { surname: "factor", firstname: "Phil" }。 也就是说,如果您想确保找到名称/值对,则必须在文档中存储它们的顺序。

不要混淆 “空值” и “不明确的”

“不明确的” 根据,在 JSON 中从来都不是有效的 官方标准 JSON(ECMA-404 第 5 节),即使它在 JavaScript 中使用。 此外,对于 BSON 来说它已经过时并被转换为 $null,这并不总是一个好的解决方案。 避免使用 “不明确的” 在 MongoDB 中.

使用 $limit()$sort()

通常,当您在 MongoDB 中进行开发时,仅查看查询或聚合返回的结果示例非常有用。 对于此任务,您将需要 $limit(),但它永远不应该出现在最终代码中,除非您之前使用过它 $sort。 这种机制是必要的,因为否则您将无法保证结果的顺序,并且您将无法可靠地查看数据。 在结果的顶部,根据排序,您将获得不同的条目。 为了可靠地工作,查询和聚合必须是确定性的,即每次执行时都产生相同的结果。 代码包含 $limit(), 但不是 $sort,不会是确定性的,并且可能随后导致难以追踪的错误。

结论

对 MongoDB 感到失望的唯一方法是将其直接与另一种类型的数据库(例如 DBMS)进行比较,或者基于某些期望来使用它。 这就像将橙子与叉子进行比较一样。 数据库系统服务于特定目的。 最好自己简单地理解和欣赏这些差异。 如果向 MongoDB 开发人员施加压力,迫使他们走上 DBMS 的道路,那将是一种耻辱。 我希望看到新的、有趣的方法来解决老问题,例如确保数据完整性和创建能够抵御故障和恶意攻击的数据系统。

MongoDB 在 4.0 版本中引入 ACID 事务性是以创新方式引入重要改进的一个很好的例子。 多文档和多语句事务现在是原子的。 还可以调整获取锁和终止卡住事务所需的时间,以及更改隔离级别。

在开始使用 MongoDB 之前我希望知道的 14 件事

阅读更多:

来源: habr.com

添加评论