---
title: 3.0、索引
date: 2017-12-16 18:45:33
tags: 
  - 数据库
  - MongoDB
categories: 
  - MongoDB
---

索引是对数据库表中一列或多列的值进行排序的一种结构，进行排序以后 , 数据的检索效率就会极大提高 , 因为不需要遍历所有的数据 , 所以使用索引可快速访问数据库表中的特定信息。
<!-- more -->

#### 查看集合当中的索引
```
db.集合名称.getIndexes()
```
每个集合当中都包含一个默认创建的索引 , 就是主键id的索引 , 名称是 \_id\_
![getIndexes](/images/MongoDB/getIndexes.png)

#### mongoDB当中的索引类型
+ `_id索引` : 在集合被创建的时候自动添加的索引 , 不能删除 ( 也是一种单键索引 )
+ `单键索引` : 针对单个字段创建的索引
+ `多键索引` : 在数组元素上建立的索引 , 会对数组的每个元素添加索引
+ `复合索引` : 针对多个字段创建的索引
+ `过期索引` : 在一定时间后会过期的索引 , 索引过期后 , 相应的数据会被删除
适合存储一些登陆信息 日志等数据
+ `全文索引`
+ `地理位置索引`


#### 创建索引
```
db.集合名称.ensureIndex( {索引字段名1: 1 , 索引字段名2 : 1 ...} , [索引属性] )
```
索引类型1表示按照升序方式存储索引 , -1表示降序
有多个索引字段时 , 该索引就是一个复合索引
索引属性的可选参数 , 后面有具体的介绍
##### 创建过期索引
```
db.集合名称.ensureIndex( {索引字段名 :1 ...} , {expireAfterSeconds : 过期的秒数} )
```
注意 : 
1. 过期索引对应的字段必须是Date类型 或者 Date的数组 , 否则不会被自动删除
-> 可以使用 .insert( {time : new Date()} ) 来获取当前的日期时间
2. 如果是Date的数组 , 只要有其中任意一个到了过期时间 , 该数据就会被删除
3. 过期索引不可以是复合索引
4. 删除的执行是由后台的一个60s执行一次的定时任务完成 , 所以删除的时间是不精确的

#### 删除索引
```
db.集合名称.dropIndex("索引名称")
```
注意是索引名称 , 而不是索引所对应的字段

---
#### 补充
**在执行查询时强制使用索引**
```
db.集合名称.find( 查询条件 ).hint( 索引名称 )
```

**索引当中的其他几个重要的属性**
+ `name` - 索引的名称 , 不指定的话可以由系统自动生成
+ `unique` - (true/false) 索引的唯一性 , 相当于为添加该索引的某个或多个字段添加了唯一约束 , 不能插入重复的两条数据 (默认false)
+ `sparse` - (true/false) 稀疏性 默认false , 为某个字段添加索引之后 , 由于非关系型数据库的特点 , 某条数据可能并不包含该字段的键值对数据 , 如果在非稀疏的模式下 , 也会为该数据创建索引 , 如果不希望如此 , 可以把sparse置为true . 有助于减少磁盘占用 , 提高写入性能

注意 : 鉴于稀疏索引本身的这种特性 , 如果我们强制使用稀疏索引去查找不存在某个字段的数据 , 就会出现问题 , 因为这些数据不存在于稀疏索引当中
例如 "m_1"是一个针对m字段的稀疏索引
执行 db.test.find({m : {$exists:false }}).hint("m_1")
即使有符合条件的数据 , 也不可能返回任何结果
