leftso 2470 0 2018-08-29 07:46:18

1. MongoDB索引策略和索引类型 - 简介

MongoDB是一个开源的,面向文档的,跨平台的数据库,它是用C ++开发的,是最流行和使用的NoSQL类型数据库之一。它在具有键值对的JSON类文档之上工作,其架构可以在每个文档中保持未定义。此外,它可以免费使用,因为它是在GNU Affero通用公共许可证和Apache许可证的组合下发布的。

在本课中,我们将讨论MongoDB中的索引类型以及我们可以用来最大化数据库性能和在其上执行的操作的不同策略。首先,我们还将了解数据库中索引的重要性以及索引的存在对于运行在我们数据上的查询的优缺点。我们还将研究一些属性,这些属性可用于改变我们在数据库中定义的MongoDB索引的行为,使它们以比简单索引更为简单的方式运行。这种改变的行为有助于我们从索引中获得更多的东西,而不仅仅是在查询级别上提高性能。让我们开始吧。


2.什么是MongoDB索引?

数据库中的索引允许查询比在没有索引的情况下执行的查询更有效和更快地查找和过滤数据。索引的最简单的例子是我们在书中已经使用过的东西。在每本书的开头,都有一个“目录”,帮助读者找到该书中出现的主题的页码。要阅读主题,我们只需要在TOC中找到它,这是一个有序的主题列表,我们可以从中获取页码。索引以相同的方式工作。由于表中可以有多个列(或者MongoDB中的集合),因此可以在集合中存在的任何列上形成索引。

当需要对多个参数执行搜索和过滤数据时,需要集合中的多个索引。例如,对于包含有关Books的数据的表,我们可以根据作者姓名或价格或书名或表中的任何其他字段过滤Book数据。

我们还提到索引的存在会降低数据库的性能。当集合中的索引太多时,这是可能的。发生这种情况是因为每当在集合中插入太多索引时,必须重新计算所有这些索引以调整不是异步任务的新数据。只有在更新了所有索引之后,才能将写入称为成功。这意味着如果数据库中的任何集合上有太多索引,则当相应集合中发生插入时,所有这些都必须由MongoDB重新访问并重新计算。

3. MongoDB中的索引类型

MongoDB提供了许多不同的方法,可以在其中形成索引并将其存储在内存(和磁盘)中。 这些索引中的每一个都有不同的用途,可能仅适用于某些数据类型。 我们来看看这些索引类型。

3.1单字段索引

MongoDB支持所有数据类型中的单个字段索引,并且可以在文档的任何用户定义字段上定义。

需要注意的是,对于单个字段索引,索引键的排序顺序无关紧要,因为MongoDB可以在任一方向读取索引。 如果我们想在字段book_name上创建单个字段索引,我们可以使用以下查询:
db.books.createIndex( { book_name: 1 } )

3.2复合索引

通常我们需要在多个字段的基础上搜索表/集合,这是非常频繁的。 如果是这种情况,我们可能会考虑在MongoDB中制作复合索引。 复合索引支持基于多个字段的索引,这扩展了索引的概念并将它们扩展到索引中的更大域。

制作复合索引时要注意的一个重要事项是字段顺序很重要。 因此,如果我们运行以下查询:
db.books.createIndex( { price: 1, book_name: 1 } )
在此复合索引中,值首先按价格字段排序,然后在每个价格值内按照book_name字段排序。 这也意味着字段的顺序决定了该索引的键是否可以支持排序操作。 这也意味着我们运行以下查询:
db.books.createIndex( { book_name: 1, price: 1 } )
在这种情况下,即使字段相同也不会重用我们使用上一个查询创建的索引,这将创建另一个索引。 这也意味着如果在此集合中插入了新记录,则将重新计算这两个索引,这使得写入操作更重,因此更慢。

3.3多键索引

我们研究的两种类型的索引很简单,并且为每个创建的索引使用不同的键。 这些索引也适用于所有数据类型。 Multikey Index是一个在数组字段上生成的索引,用于索引存储在数组中的内容。

当索引数组的内容时,MongoDB会激增数组,创建多个具有相同名称的字段,每个字段在该数组中包含不同的值:
在MongoDB索引中爆炸数组
在MongoDB索引中激增数组


这允许非常有效的查询,这些查询尝试将查询中传递的值与单个数组字段或数组字段集合进行匹配。 好处是,如果指定字段是数组,MongoDB可以决定何时创建多键索引。

在尝试微调数据库时,我们可能遇到的一个限制是多键索引可能无法完全覆盖查询中指定的过滤器。 使用索引覆盖查询意味着我们可以完全从索引获取结果数据,而无需访问数据库中的数据。 由于索引最有可能存储在RAM中,因此可以显着提高性能。

3.4地理空间索引

MongoDB允许我们通过使我们能够在文档中存储Geo-JSON集合来在我们的数据库中保存地理空间形状。 为了有效查询地理空间数据,MongoDB在内部提供了两种类型的索引:

返回结果时使用平面几何的2d索引
使用球面几何体返回结果的2d球体索引
详细了解这些索引如何在这里工作。 通过我们数据库中的地理空间形状,我们可以轻松运行查询以查找当前位置附近的汉堡联合,而地理空间索引有助于更快地执行此搜索。

3.5文本索引

MongoDB还提供了在文本字段上创建索引的功能,该索引还支持在集合中搜索某些字符串内容。 应注意,这些索引不存储诸如“该”,“一个”,“或”之类的停用词。 在文本索引中,单词仅用于存储根词。 我们可以使用以下查询在字段上创建文本索引:
db.books.createIndex( { book_name: "text" } )
如果您使用英语以外的语言索引文本字段,我们可以使用以下查询:
db.books.createIndex( { book_name: "text" }, { default_language: "french" } )
文本索引是不区分大小写和不区分大小写的。 文本索引的第3版(版本3.4附带的版本)支持常见的C,简单S和特殊的T案例折叠,如Unicode字符数据库8.0案例折叠中所述。 除了不区分大小写,文本索引的第3版支持变音符号不敏感。

通过文本索引的高性能测量,MongoDB对Elasticsearch提出了严峻的挑战,Elasticsearch是一个主要用于文本搜索查询的数据库。

3.6哈希索引

我们将研究的最后一种索引是哈希索引。 这种类型的索引允许我们对内容执行基于哈希的分片。 在这种类型的索引中,键的值被散列。 由于这个原因,这些索引只能支持相等匹配过滤器查询,并且不能在基于范围的查询上工作。

如果我们想在索引上运行范围查询,我们可能必须在同一个字段上创建多个索引,其中一个可以是常规索引,另一个可以是散列索引。 最后,Hashed索引将浮点字段截断为整数。 应尽可能避免对散列字段使用浮点。

4. MongoDB中索引的属性

通过为该索引指定特定属性,可以在MongoDB中更改索引的行为。其中一些属性是:

4.1独特的索引

这些索引可以通过规范使其成为唯一的。这样,当要求单个字段索引保持唯一时,它将拒绝该密钥的集合中已存在的值。 MongoDB中的任何索引都可以是唯一的。

在复合索引中,索引值的唯一性通过与组成复合索引的键对应的值的组合来维持。

4.2部分索引

如果您知道只需要为指定的键或一组键索引某些文档,我们可以通过指定过滤器查询将索引转换为部分索引。只有通过此过滤器的文档才会在指定字段上编制索引。这样,部分索引具有更低的存储要求,并且比正常索引快得多,因为数据量较少。

需要注意的是,只有在部分索引可以满足完整查询的情况下,查询才会针对部分索引运行。

4.3稀疏索引

索引的稀疏属性确保索引仅包含实际包含索引字段的文档的条目。稀疏索引完全跳过没有索引字段的文档。

应注意,部分索引优于稀疏索引,因为稀疏索引的所有功能都可以通过具有更多添加的部分索引来实现。

4.4 TTL索引

如果要在指定的时间段后从集合中删除文档,我们可以在字段上创建TTL索引。这是索引的一个重要属性,可以应用于定期更新的数据,使旧数据过时,对日后数据(如日志数据)无用。

MongoDB中的数据由每60秒(或在指定时间)运行的后台作业删除。因此,没有明确保证文件将在有效期过后持续多长时间。

5.MongoDB索引的局限性

尽管到目前为止我们已经在课程中研究了索引的许多优点,但索引也存在一些与之相关的缺点或限制。我们在这里阅读:
  • MongoDB中的单个集合最多只能有64个索引。当文档大小很大时,这就成了一个问题,我们可能不得不打破我们的文档,以涵盖多个集合。
  • 文档中的完全限定索引名称不能超过128个字符。索引的FQN由<db_name>。<collection-name>。$ <index_name>组成。
  • 在复合索引中,不能超过31个字段。
  • MongoDB查询不能同时使用文本和地理空间索引。我们不能将$ text运算符与任何与特殊索引关联的其他运算符组合在一起。例如,$ text运算符和$ near运算符不能一起使用。
  • 具有2d球体索引的字段只能包含几何数据。因此,允许在平面坐标系上使用[x,y]点。对于非几何,如果在此索引中保存任何其他类型的数据,则数据查询操作将失败。
  • 由于当MongoDB实例运行时,索引中的数据主要存在于RAM中,因此它们会消耗机器上的大量内存。这也使得MongoDB索引非常快。
  • 默认情况下,MongoDB索引在前台进行。这意味着集合上的所有操作都将被阻止,直到完全构建索引。但是,可以通过在查询中指定后台创建属性来覆盖此行为。

6总结

在本课程中,我们研究了MongoDB中存在的各种类型的索引,以及如何通过我们可以强加给它们的许多属性和约束来改变和扩展它们的行为。 我们还描述了在使用Indexes时我们应该注意的一些限制,我们应该在对集合进行索引时注意,同时将数据插入到包含许多索引的MongoDB集合中,以确保我们不会使数据库成为写入数据库 ,导致整体性能下降。

如果在创建索引之前特别小心并且为应用程序的MongoDB实例正确管理内存,则索引的主要目标是通过一个主要因素来提高数据库的性能。

 
编程技术 MongoDB 索引