索引是一种用来方便查询数据的 数据结构
B Tree就是一种常用的数据库索引数据结构,MongoDB采用 B 树做索引,索引创建在colletions 上。
我们可以在这个网站上直观的看到索引的效果
https://www.cs.usfca.edu/~galles/visualization/Algorithms.html
除了 B 树,平衡二叉树、红黑树、B + 树都可以用来做索引
mongodb 中的索引与多种索引类型,梳理一下看看效果
索引类型 | 描述 | demo |
---|---|---|
单字段索引 | 在某一个特定的字段上建立索引mongoDB 在 ID 上建立了唯一的单键索引,所以经常会使用 id 来进行查询;在索引字段上进行精确匹配、排序以及范围查找都会使用此索引; | 创建一个倒序的索引db.users. createIndex({age:-1}); |
复合索引 | 在多个特定的属性上建立索引复合索引键的排序顺序,可以确定该索引是否可以支持排序操作;在索引字段上进行精确匹配、排序以及范围查找都会使用此索引,但与索引的顺序有关;为了性能考虑,应删除存在与第一个键相同的单键索引 | db.users. createIndex({username:1,age:-1,country:1}) |
多键索引 | 在数组的属性上建立索引针对这个数组的任意值的查询都会定位到这个文档,既多个索引入口或者键值引用同一个文档 | db.users.createIndex({favorites.city:1}) |
空间索引 | 2 种平面几何的 2d 索引,球面几何的2dsphere索引 见后文详解文本索引 支持在集合中搜索字符串内容 | db.reviews.createIndex( { comments: "text" } ) |
Hash索引 | 不同于传统的B-树索引,哈希索引使用hash函数来创建索引在索引字段上进行精确匹配,但不支持范围查询,不支持多键hash;Hash索引上的入口是均匀分布的,在分片集合中非常有用 | db.users.createIndex({username : 'hashed'}) |
MongoDB 使用 createIndex()
方法来创建索引,createIndex()
方法基本语法格式是这样的
db.集合名.createIndex(keys, options)
文档类型值为要创建的索引字段,1为指定按升序创建索引,-按降序来创建索引指定为-1。
文档类型值 MongoDB 中提供了丰富的属性,比如 background
,是否后台构建索引,
数据量太大时构建索引消耗时间长,为了不影响业务,可以加上此参数
后台运行同时还会为其他读写操作让路
自定义索引名字
唯一索引
可确保索引字段不会存储重复值
MongoDB默认在创建集合时会在_id字段上创建唯一索引,例如
db.collection.createIndex(
{id:1},
{unique:true}
)
部分索引
仅索引集合中符合指定过滤器表达式的文档
较低的存储需求,索引创建和维护的成本变小,例如
db.restaurants.createIndex(
{ cuisine: 1, name: 1 },
{
partialFilterExpression:{
rating:{
$gt: 5
}
}
}
)
稀疏索引
仅索引包含具有索引字段的文档,哪怕索引字段包含空值,例如
db.addresses.createIndex(
{ "xmpp_id": 1 },
{ sparse: true }
)
TLL索引
特殊的单字段索引,在一定时间后或在特定时间自动从集合中删除文档
这对于日志和会话类的信息很有用。
db.eventlog.createIndex(
{"lastModifiedDate":1},
{expireAfterSeconds:3600 }
)
不区分大小写
例如
db.fruit.createIndex(
{ type: 1},
{
collation:{
locale:'en',
strength:2
}
}
)
创建索引
db.集合名.createIndex()
查看索引
db.集合名.getIndexes()
db.集合名.totalIndexSize()
更新索引
db.集合名.reIndex()
删除索引
db.集合名.dropIndex()
db.集合名.dropIndexes()
图片来源于 mongodb 官网
MongoDB 为文档集合中的任何字段上的索引提供了完整的支持
默认情况下,所有集合在_id字段上都有一个索引,应用程序和用户可以添加额外的索引来支持重要的查询和操作
MongoDB 支持复合索引,其中单个索引结构保存对集合文档中多个字段的引用。
图中可以看到使用了 userid 和 score 的引用, userid 是升序,score 是倒序
在官网上我们可以看到 mongodb 的每一种索引类型的图解
https://docs.mongodb.com/manual/indexes/
多键索引,或可以称为数组索引
文档的多个待索引字段是数组,不能创建两个多键值字段的复合索引,复合索引只能包含一个字段是多键索引。
MongoDB是文档型数据库,两个字段为数组,这个情况是可以发生改变的,比如其中一个为数组,另一个不是数组。
MongoDB 支持动态的文档结构,通过通配符索引应用程序可以查询事先未知字段
例如可以这样创建索引
{ "userMetadata" : { "likes" : [ "pigs", "cats" ] } }
{ "userMetadata" : { "dislikes" : "pickles" } }
{ "userMetadata" : { "age" : 100 } }
可以 通过$**
来匹配某个字段后面未知的字段
db.userData.createIndex( { "xxx.$**" : 1 } )
MongoDB中有两种二维平面索引:2d、geoHaystack。
1、2d,对在二维平面上坐标点为存储的数据使用索引,是2.2版本中的坐标对。
2、GeyHaystack索引是一个特殊的索引,该索引被优化以在较小的区域上返回结
3、GeHaystack索引提高了使用平面几何图形的查询的性能
例如
平面的坐标我们可以这样来表示
// 数组形式
location: [-43.856077, 21.848447]
// 内嵌文档形式,第一个为经度,第二个为纬度,忽略字段名
location: { field1: -63, field2: 31,6 }
空间索引总是稀疏的,并且忽略稀疏选项,仅支持简单的二进制比较
Hash索引通过索引字段值的散列来维护索引数据,使用哈希函数来计算索引字段值的哈希,
主要使用在分片键上。需要注意的点:
1、支持任意单字段的Hash索引,不能创建多键的Hash索引
2、Hash值会发生碰撞,Hash索引不能设定为唯一约束
3、支持相等查询,不支持范围查询
4、创建hash索引的字段也可以创建其他索引
5、hashed索引不支持不能转换为64位整数的浮点值,大于2的53次方的浮点值
// 创建一个hash索引
db.集合名.createIndex( { field: "hashed" } )
最后梳理一下 使用 mongodb 的注意事项:
确定将要运行的查询的类型,以便可以构建引用这些字段的索引
当索引包含该查询扫描的所有字段时,该索引就支持该查询
为了支持有效的查询,在指定索引字段的顺序和排序顺序时间
内存有限的情况下,MongoDB 通过保存最近的值来淘汰老值,mongodb 的索引还是很消耗内存的
查询使用索引缩小结果范围,可以限制可能检索的文档数量
总的来说,咱们学习还是从官网入手
朋友们,你的支持和鼓励,是我坚持分享,提高质量的动力
好了,本次就到这里
技术是开放的,我们的心态,更应是开放的。拥抱变化,向阳而生,努力向前行。
我是阿兵云原生,欢迎点赞关注收藏,下次见~