1. MongoDB索引策略和索引类型–简介
MongoDB是一个开放源代码,面向文档的跨平台数据库,它使用C ++开发,并且是最流行和使用最广泛的NoSQL类型数据库之一。 它可在具有键-值对的类JSON文档的顶部运行,其键值对在每个文档中都无法定义。 同样,它是免费使用的,因为它是在GNU Affero通用公共许可证和Apache许可证的组合下发布的。
在本课程中,我们将讨论MongoDB中索引的类型以及可用于最大化数据库性能以及对数据库执行的操作的不同策略。 首先,我们还将研究数据库中索引的重要性以及索引的存在如何对在我们的数据上运行的查询有利有弊。 我们还将研究一些属性,这些属性可用于更改我们在数据库中定义的MongoDB索引的行为,从而使其具有比简单索引所指的扩展方式更广泛的行为。 这种变化的行为不仅可以提高查询级别的性能,还可以帮助我们从索引中实现更多功能。 让我们开始吧。
2.什么是指数?
数据库中的索引使查询能够比没有索引的情况下执行查询更有效,更快速地查找和过滤数据。 索引的最简单示例是我们所有人都已经在书中使用的东西。 每本书的开头都有一个“目录”,可帮助读者找到该书中出现的主题的页码。 要阅读主题,我们只需要在目录中找到它即可,主题目录是主题的有序列表,我们可以从中获取页码。 索引以相同的方式工作。 由于一个表(如果是MongoDB,则为一个集合)中可以有多个列,因此可以在集合中存在的任何列上形成索引。
当需要对多个参数执行搜索和过滤数据时,需要在集合中使用多个索引。 例如,对于包含有关书籍数据的表,我们可以根据作者姓名或价格或书籍名称或表中存在的任何其他字段来过滤书籍数据。
我们还提到索引的存在会降低数据库的性能 。 当集合中的索引过多时,这是可能的。 发生这种情况的原因是,无论何时在构建了太多索引的集合中有一个插入,都必须重新计算所有这些索引以调整新数据,这不是异步任务。 仅当所有索引都已更新时,才可以将写入称为成功。 这意味着,如果数据库中任何集合上的索引过多,则当相应集合中发生插入时,MongoDB将必须重新访问所有这些索引并重新计算。
3. MongoDB中的索引类型
MongoDB提供了许多不同的方式来形成索引并将其存储在内存(和磁盘)中。 这些索引中的每一个都有不同的用途,并且可能仅适用于某些数据类型。 让我们在这里看看这些索引类型。
3.1单字段索引
MongoDB支持所有数据类型的单个字段索引,并且可以在文档的任何用户定义字段上定义。
注意,对于单个字段索引,索引键的排序顺序无关紧要,因为MongoDB可以从任一方向读取索引。 如果要在字段book_name
上创建单个字段索引,则可以使用以下查询:
单场索引
db.books.createIndex( { book_name: 1 } )
在上面的查询中,数字1指定了索引的顺序(实际上并不重要,因为MongoDB可以从任一方向读取索引)。
3.2复合指数
通常,我们需要在多个字段的基础上搜索表/集合,这非常常见。 如果是这种情况,我们可以考虑在MongoDB中创建复合索引。 复合索引支持基于多个字段的索引,这些字段扩展了索引的概念并将它们扩展到索引中的较大域。
制作复合索引时要注意的重要事项是字段顺序很重要 。 因此,如果我们运行以下查询:
复合指数
db.books.createIndex( { price: 1, book_name: 1 } )
在此复合索引中,值首先按price
字段排序,然后在每个价格值内,按book_name
字段排序。 这也意味着字段的顺序决定了此索引的键是否可以支持排序操作。 这也意味着我们运行以下查询:
复合指数
db.books.createIndex( { book_name: 1, price: 1 } )
在这种情况下, 即使字段相同 , 这也将创建另一个索引,并且不会重复使用上次查询创建的索引。 这也意味着,如果在此集合中插入了一条新记录,则将重新计算这两个索引,这会使写操作更重,因此也更慢。
3.3多键索引
我们研究的两种类型的索引很简单,并且为每个创建的索引使用不同的键。 这些索引也适用于所有数据类型。 多键索引是在数组字段上创建的索引,用于索引存储在数组中的内容。
对数组的内容建立索引后,MongoDB会爆炸该数组,创建具有相同名称的多个字段,每个字段在该数组中包含不同的值:
这允许非常高效的查询,这些查询尝试将查询中传递的值匹配到单个数组字段或数组字段的集合。 好消息是,如果指定的字段为数组,则MongoDB可以自行决定何时创建Multikey Index。
尝试微调数据库时可能遇到的限制之一是,多键索引可能无法完全覆盖查询中指定的过滤器。 用索引覆盖查询意味着我们可以完全从索引获取结果数据,而根本不访问数据库中的数据。 由于索引最有可能存储在RAM中,因此可以显着提高性能。
3.4地理空间指数
MongoDB通过使我们能够在文档中存储Geo-JSON集合,使我们能够在数据库中保存地理空间形状。 为了有效查询地理空间数据,MongoDB在内部提供了两种类型的索引:
- 返回结果时使用平面几何的 2d索引
- 使用球形几何图形返回结果的2d球形索引
在此处阅读有关这些索引如何工作的更多信息。 利用我们数据库中的地理空间形状,我们可以轻松地运行查询以查找您当前位置附近的汉堡店,而地理空间索引有助于更快地执行此搜索。
3.5文字索引
MongoDB还提供了在文本字段上建立索引的功能,还支持在集合中搜索某些字符串内容。 要注意的是,这些索引不存储诸如“ the”,“ a”,“ or”之类的停用词。 在文本索引中,词干仅存储根词。 我们可以使用以下查询在字段上创建文本索引:
文字索引
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还支持变音符号不敏感。
凭借高性能的text-index度量,MongoDB给Elasticsearch带来了严峻的挑战, Elasticsearch是一个主要用于Text-search查询的数据库。
3.5哈希指数
我们将研究的最后一种指数是哈希指数 。 这种索引类型使我们可以对内容执行基于哈希的分片 。 在这种类型的索引中,键的值是散列的。 由于这个原因, 这些索引只能支持相等匹配过滤器查询,而不能用于基于范围的查询 。
如果要对索引运行范围查询,则可能必须在同一字段上创建多个索引,其中一个可以是常规索引,另一个可以是哈希索引。 最后, 哈希索引将浮点字段截断为整数。 应尽可能避免对散列字段使用浮点数。
4. MongoDB中索引的属性
可以在MongoDB中通过为索引指定特定的属性来更改索引的行为。 其中一些属性是:
4.1唯一索引
这些是可以通过规范使其唯一的索引。 这样,当要求单个字段索引保持唯一时,它将拒绝该键的集合中已存在的值。 任何索引都可以在MongoDB中设为唯一。
在复合索引中,索引值的唯一性是通过与构成复合索引的键对应的值的组合来保持的。
4.2部分索引
如果您知道只需要为指定键或一组键建立索引的文档,则可以通过指定过滤器查询将索引转换为部分索引。 仅通过此过滤器的文档将在指定字段上建立索引。 这样,部分索引的存储需求要低得多,并且由于数据量较少,因此比普通索引要快得多。
要注意的是,仅当部分查询可以满足完整查询时,查询才会针对部分索引运行。
4.3稀疏指数
索引的稀疏属性可确保索引仅包含实际包含已索引字段的文档的条目。 稀疏索引将完全跳过没有索引字段的文档。
要注意的是,部分索引比稀疏索引更可取,因为稀疏索引的所有功能都可以通过添加更多索引的部分索引来实现。
4.4 TTL索引
如果要在指定时间段后从集合中删除文档,我们可以在字段上创建TTL索引。 这是索引的重要属性,可用于定期更新的数据,从而使较旧的数据过时并且对于将来的目的(如日志数据)无用。
每隔60秒(或在指定的时间)运行一次后台作业,将删除MongoDB中的数据。 因此,不能明确保证文档将在其过期日期后保留多长时间。
5.索引的局限性
尽管到目前为止,我们已经研究了索引的许多优点,但是索引也有一些缺点或限制。 让我们在这里阅读它们:
- MongoDB中的单个集合最多只能有64个索引。 当文档很大时,这将成为一个问题,我们可能不得不破坏文档才能覆盖多个馆藏。
- 文档中的标准索引名称不能超过128个字符。 索引的FQN由
<db_name>.<collection-name>.$<index_name>
。 - 在复合索引中,字段不能超过31个。
- MongoDB查询不能同时使用文本索引和地理空间索引。 我们不能将
$text
运算符与与特殊索引关联的任何其他运算符组合。 例如,$text
运算符和$near
运算符不能一起使用。 - 具有2d球面索引的字段只能包含几何数据。 因此,平面坐标系上的点[x,y]是允许的。 对于非几何图形,如果在此索引中保存任何其他类型的数据,则数据查询操作将失败。
- 当MongoDB实例运行时,由于索引中的数据主要存在于RAM中,因此它们会消耗计算机上的大量内存。 不过,这也使MongoDB索引非常快。
- MongoDB索引默认情况下位于前台。 这意味着在完全建立索引之前,将阻止对集合的所有操作。 但是,可以通过在查询中指定后台创建属性来覆盖此行为。
六,结论
在本课程中,我们研究了MongoDB中存在的各种类型的索引,以及如何通过可施加于它们的许多属性和约束来改变和扩展它们的行为。 我们还描述了在使用索引时遇到的一些限制,在为集合创建索引以及将数据插入包含许多索引的MongoDB集合中时应注意这些限制,以确保我们不会使数据库成为写繁重的数据库,导致整体性能下降。
如果在创建索引之前已经特别注意,并且为应用程序的MongoDB实例正确管理了内存,则索引的主要目的是通过一个主要因素来提高数据库的性能。
阅读关于如何通过一个Java应用程序,它集成了MongoDB的和执行各种查询它与上手这个职位。 如果您更喜欢Javascript,请阅读这篇文章。
翻译自: https://www.javacodegeeks.com/2018/08/mongodb-index-strategies-and-types-of-indexes.html