`
eksliang
  • 浏览: 599650 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

MongoDB索引管理(1)——[九]

阅读更多

转载请出自出处:http://eksliang.iteye.com/blog/2178427

一、概述

      数据库的索引与书籍的索引类似,有了索引就不需要翻转整本书。数据库的索引跟这个原理一样,首先在索引中找,在索引中找到条目以后,就可以直接跳转到目标文档的位置,从而使查询速度提高几个数据量级。

      不使用索引的查询称为全表扫描(这个术语来源于关系型数据库),也就是说,服务器必须查找完一整本书才能找到查询结果。这个过程跟我们在一本没有索引(目录)的书中查找信息很像:从第一页开始一直读完整本书。通常来说,应该尽量避免使用全表扫描,因为对于大集合来说,全表扫描的效率非常低。

      Mongodb的索引几乎与关系型数据库的索引一模一样,所以适用于关系型数据库索引优化技巧,在这里就不多说了。

 

二、创建索引

创建索引使用db.collectionName.ensureIndex(...)方法进行创建;

参考实例一:创建普通索引

 

> db.users.ensureIndex({"name":1})

      这样就在users这个集合上面的name字段上面创建了一个name_1的索引,{"name":1}说明建立的索引是升序的,如果{"name":-1}说明创建的索引是降序的。

 

参考实例二:创建普通复合索引

 

db.users.ensureIndex({"name":1,"age":1})

      这样就在users这个集合上面的name和age字段上面创建了一个name_1_age_1的索引.

 

参考实例三:创建唯一索引

       唯一索引可以确保集合里面的每一个文档指定的键都有唯一值。例如,如果想保证不同文档的name键拥有不同的值,创建一个唯一索引就可以了:

 

> db.dept.ensureIndex({"name":1},{"unique":true})

      创建完唯一索引以后,如果想向dept集合中添加如下文档:

 

 

> db.dept.insert({ "_id" : 1, "name" : "ickes" })
> db.dept.insert({ "_id" : 2, "name" : "ickes" })

      会发现只有第一个文档添加进去了,添加第二个时就会抛出异常,所以使用唯一索引来应对偶尔可能出现键重复的问题,而不是在运行时对重复键进行过滤。"_id"就是这中类型的索引,这个索引会在创建集合时自动创建。

 

参考实例三:创建复合唯一索引

    创建复合唯一索引时,单个键的值可以相同,但是所有键的组合的值必须是唯一的。

 

> db.users.ensureIndex({"name":1,"age":1},{"unique":true})

 

参考实例四:创建唯一索引时去除重复  

      在已有的集合上面创建唯一索引时,可能失败,因为集合中可能已经存在重复值了,如下所示:

 

> db.dept.find() 
{ "_id" : 1, "name" : "ickes" }
{ "_id" : 2, "name" : "ickes" }
{ "_id" : 3, "name" : "ickes1" }
{ "_id" : 4, "name" : "eks" }
{ "_id" : 5, "name" : "eks" }
--从上面的集合中看出name已经有大量重复值,创建唯一索引时抛出异常
> db.dept.ensureIndex({"name":1},{"unique":true})
{
        "createdCollectionAutomatically" : false,
        "numIndexesBefore" : 1,
        "ok" : 0,
        "errmsg" : "E11000 duplicate key error index: test.dept.$name_1  dup key
: { : \"eks\" }",
        "code" : 11000
}

     通常需要对已有的数据进行处理(可以使用聚合框架,后面会说),找出重复的数据,想办法处理。

     在极少数情况下,可能希望直接删除重复的值。创建索引时使用"dropDups"选项,如果遇到重复的值,第一个会被保留,之后的重复文档都会被删除。

 >  db.dept.ensureIndex({"name":1},{"unique":true,"dropDups":true})
{
        "createdCollectionAutomatically" : false,
        "numIndexesBefore" : 1,
        "numIndexesAfter" : 2,
        "ok" : 1
}

      "dropDups"会强制性的建立唯一索引,但是这个方式太粗暴了:你无法控制那些文档需要被保留,那些文档需要被删除(从上面打印的信息可以看出,如果文档被删除了,MongoDB也不会给出提示信息)。对于比较重要的数据,千万不要使用"dropDups".

参考实例四:创建稀疏索引

      唯一索引会把null值看做值,所以无法将缺少键的多个文档插入到建立的唯一索引的集合中。然而,在某些情况下,你可能希望唯一索引只针对包含相应键的文档生效。如果有一个可能存在也有可能不存在的字段,当字段存在时是唯一索引,不存时不做处理,这时就可以将unique和sparse选项组合在一起使用。

    使用sparse选项就可以创建稀疏索引。例如集合的结构如下:

> db.sparse.find()
{ "_id" : 1, "x" : 1 }
{ "_id" : 2, "x" : 2 }
{ "_id" : 3, "x" : null }
{ "_id" : 4 }

   创建稀疏索引

> db.sparse.ensureIndex({"x":1},{"unique":true,"sparse":true})

    稀疏索引不必是唯一的。只要去掉unique选项,就可以创建一个非唯一的稀疏索引

    MongoDB的稀疏索引与关系型数据库中的稀疏索引是完全不同的概念。基本上来说,MongoDB中的稀疏索引只是不需要将每个文档都作为索引条目。那么问题来了,根据是否使用稀疏索引,同一个查询的返回结果可能不同。

    例如上面文档,当在x上面执行查询时,他会返回相应匹配的文档:

> db.sparse.find({"x":{"$ne":1}}).hint({}) --hint({})强制不使用索引
{ "_id" : 2, "x" : 2 }
{ "_id" : 3, "x" : null }
{ "_id" : 4 }

    如果在x字段上面使用索引,那么{ "_id" : 4 }的文档将不会返回,因为他不在索引中,例如:

> db.sparse.find({"x":{"$ne":1}}).hint({"x":1})
{ "_id" : 3, "x" : null }
{ "_id" : 2, "x" : 2 }

 

 二、查看索引

 所有数据库索引信息都存储在system.indexes集合中。这是一个保留集合,不能在其中插入或者删除文档。只能通过ensureIndex({...})或者dropIndexes对他进行操作:

参考实例一:查看所有数据库建立的索引详情

> db.system.indexes.find()
{ "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "test.users" }
{ "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "test.dept" }
{ "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "test.food" }
{ "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "test.test" }
{ "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "test.emp" }
{ "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "test.blog" }
 ................省略!

 参考实例二:查看特定集合的索引信息

> db.users.getIndexes()
[
        {
                "v" : 1,
                "key" : {
                        "_id" : 1
                },
                "name" : "_id_",
                "ns" : "test.users"
        },
        {
                "v" : 1,
                "key" : {
                        "name" : 1,
                        "age" : 1
                },
                "name" : "name_1_age_1",
                "ns" : "test.users"
        }
]
>

       这里最重要的字段是key和name,key说明了你创建索引时字段跟排序,name就是索引的名称,默认为key_dir_key_dir....的格式,"v"字段只在内部使用,用于标识索引的版本。如果你的索引不包含“v”:1这样的字段,说明你的索引是一种效率比较低的旧方式存储的。将MongoDB升级到至少2.0的版本,删除并重建这些索引,就可以把所有的存储方式升级到新的格式了。

 

三、标识索引

       集合中的每一个索引都有一个名称,用于唯一标识索引,也可以用于服务器端来删除索引。索引默认的命名方式是key1_dir1_key2_dir2....keyn_dirn,其中key就是索引的键,dir是索引的排序方向(1或者-1),如果索引中包含的键比较多,这种默认的命名方式就显得比较笨重,可以再创建索引时指定索引的名称。

参考实例:

> db.users.ensureIndex({"name":1,"age":1},{"name":"name_age1"})

 温馨提示:MongoDB索引名称的长度有限,所以新建复杂索引时可能需要自定义索引名称.

 

四、删除索引

参考实例一:删除集合里面的所有索引

 > db.users.dropIndexes()

 参考实例二:根据索引的key或者name删除集合里面的指定索引

> db.users.dropIndex("name_1_age_1")--根据索引的name删除
> db.users.dropIndex({"name":1,"age":1})--根据索引的key删除

 

     

       

 

 

 

    

 

 

 

分享到:
评论

相关推荐

    Spring Boot 2.x基础教程:使用MongoDB(csdn)————程序.pdf

    MongoDB支持强大的查询语言,类似于面向对象的语法,能实现类似关系数据库的查询功能,并支持索引。 在Spring Boot 2.x中集成MongoDB,首先需要在`pom.xml`文件中添加`spring-boot-starter-data-mongodb`依赖,该...

    mongodb 数据库基本操作.doc

    MongoDB提供了许多高级功能和选项,如索引、分片、复制集、事务等,以满足更复杂的数据管理和处理需求。 - **索引**:通过创建索引来加速查询速度。 - **分片**:将大数据集分布在多个服务器上,提高可伸缩性和性能...

    30分钟学MongoDB系列 ——MongoDB的安全机制和高级管理篇

    在处理海量数据时,MongoDB提供了很多高级管理功能来确保数据的安全性和一致性。本篇将重点介绍MongoDB的安全机制和高级管理功能,包括数据复制、异常处理、进程控制等。 数据复制是分布式数据库系统的基础特性之一...

    NoSQL Manager for MongoDB(5.8.3)

    《NoSQL Manager for MongoDB(5.8.3)——高效管理MongoDB数据库的利器》 在如今的大数据时代,MongoDB作为一款流行的NoSQL数据库,因其灵活的数据模型、高性能和可扩展性,被广泛应用于各种业务场景。而针对MongoDB...

    java面试——MongoDB面试专题.zip

    - 创建和管理索引,理解单字段、复合索引、文本索引、地理空间索引的作用。 - 索引优化:了解如何根据查询模式选择合适的索引类型,以及使用`explain()`方法分析查询性能。 5. **复制集**: - 复制集提供高可用...

    Zabbix MongoDB监控模板.xml

    本文将详细探讨Zabbix针对MongoDB的监控模板——"Zabbix MongoDB监控模板.xml",以及如何使用和配置这个模板来确保MongoDB的稳定运行。 一、Zabbix与MongoDB监控模板简介 Zabbix是一款企业级的分布式监控解决方案...

    2021Java字节跳动面试题——面向字节_MongoDB.pdf

    #### 知识点九:MongoDB的数据文件管理 - MongoDB会积极预分配存储空间,以减少文件系统碎片并提高性能。 - 这种预分配策略可能导致数据文件显得较大。 以上内容涵盖了NoSQL数据库的基本概念、类型以及MongoDB的...

    studio 3T MongoDB图形化管理工具

    **MongoDB图形化管理工具——Studio 3T详解** MongoDB作为一款强大的非关系型数据库系统,因其灵活性、可扩展性和高性能,在众多领域得到了广泛应用。然而,对于如此复杂的数据库管理系统,仅靠命令行操作往往效率...

    玩转MongoDB4.0从入门到实践、MongoDB基本操作之CRUD、进阶之聚合、中索引的重要性、数据分片

    这一章节将详细介绍MongoDB中的基本操作——创建(Create)、读取(Retrieve)、更新(Update)和删除(Delete),即CRUD操作: 1. **插入文档**:利用`insert`或`insertOne`命令插入单个文档;使用`insertMany`批量插入多...

    《Node应用程序构建:使用MongoDB和Backbone》 源码

    4. **Node.js与MongoDB的集成**:本书会讲解如何使用Node.js的MongoDB驱动程序(如`mongodb`或`mongoose`)来连接和操作数据库,包括数据的增删查改、集合管理、索引创建等。 5. **Express框架**:在Node.js中,...

    深入剖析 MongoDB 架构

    MongoDB 是一款流行的开源、分布式文档数据库系统,以其高性能、高可用性和...通过深入理解其主从复制、分片、GridFS、BSON、索引和管理工具等核心概念,你可以更好地利用 MongoDB 来构建和维护大规模的数据存储系统。

    MongoDB_two_MongoDB_

    6. 键与索引:讨论唯一性键、复合键和多键索引,以及如何创建和管理索引以优化查询性能。 7.聚合框架:MongoDB的聚合框架允许对数据进行处理和分析,包括分组、过滤、计算统计值等操作,类似于SQL的聚合函数。 8. ...

    Mongodb使用手册

    1. **MongoDB基础**:介绍MongoDB的基本概念,包括数据模型(如文档、集合、数据库)、安装步骤、启动和停止服务,以及如何通过命令行进行基本操作。 2. **数据存储**:详细解释MongoDB的数据存储机制,包括BSON...

    PHP实例开发源码—RockMongo php MongoDB管理工具.zip

    【标题】"PHP实例开发源码—RockMongo php MongoDB管理工具.zip" 提供的是一个基于PHP编写的MongoDB管理工具——RockMongo的源代码。RockMongo是一个轻量级且易于使用的Web界面,允许用户通过浏览器对MongoDB数据库...

    MongoDB基础教程

    MongoDB提供了强大的查询语言——MQL(MongoDB Query Language),支持丰富的查询表达式和聚合框架。你可以根据字段、条件进行查询,并使用正则表达式、数组过滤等高级特性。 在性能方面,MongoDB支持索引,可以...

    MongoDB.in.Action.2nd.Edition.2016.3.pdf

    - **分片**:讲解MongoDB的水平扩展技术——分片集群的工作原理及配置步骤。 - **复制集**:探讨复制集在实现高可用性方面的作用,以及如何配置复制集。 - **性能优化** - **索引管理**:如何合理创建和维护索引...

    mongodb-linux-x86_64-rhel62-4.4.1.tgz

    在本案例中,我们关注的是针对Linux 64位系统的MongoDB版本——"mongodb-linux-x86_64-rhel62-4.4.1.tgz",这是一个tarball格式的压缩包,用于在RHEL 6.2或兼容系统上安装和运行MongoDB 4.4.1版本。 MongoDB 4.4.1...

Global site tag (gtag.js) - Google Analytics