索引类型

mongoDB 的索引在存储结构都是一样的,但是根据不同的应用需求,还是分成了:唯一索引,稀疏索引,复合索引

1.唯一索引

MONGODB 在默认建立文档时,都会自动添加一个:“_id” 字段,而此字段默认建立唯一索引;

如果我们要使一个键值在文档中唯一,我们就要在此字段建立一个唯一索引,语法如下:

db.users.ensureIndex({account:1},{unique:true})

和其它数据库一样,唯一索引,此字段是允许值为NULL 的,但只允许有一条。

当然,我们也可以在多个字段中建立一个唯一索引:

db.users.ensureIndex({mobile:1,email:1},{unique:true})

2.稀疏索引

有这样一个问题:

如果某个字段,如果它存在,那么必须是唯一,因为 会把null当做值,如果定义了唯一索引,那么此字段只能存在一个null值的记录。

这时我们可以使用以下方法定义这个索引:

db.user.ensureIndex({email:1},{“unique”:true,”sparese”:true})

当然,上面是为了方便理解而举的一个例子。其实 【稀疏索引】并不是必须是唯一索引。

db.user.ensureIndex({email:1},{”sparese”:true})

我们也看一个 稀疏索引查询

> db.foo.find()
{ "_id" : 0 }
{ "_id" : 1, "x" : 1 }
{ "_id" : 2, "x" : 2 }
{ "_id" : 3, "x" : 3 }
> db.foo.find({x:{$ne:2}})
{ "_id" : 0 }
{ "_id" : 1, "x" : 1 }
{ "_id" : 3, "x" : 3 }

在文档的x 键建立一个 [稀疏索引]

> db.foo.ensureIndex({x:1},{sparse:true})
> db.foo.getIndexes()
[{"v" : 1,
"key" : {"_id" : 1},"ns" : "test.foo","name" : "_id_"},
{"v" : 1,"key" : {"x" : 1},"ns" : "test.foo","name" : "x_1","sparse" : true
}
]

完成后,我们再来查询看看:

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

看到,这时查询结果,已排除了 没有键 X 的文档 _id:0 了。

就是因为在建立索引时,“_id”=0 的文档,不会包含在索引中。

当然,如果你需要查询到 那些不包含 “x” 的 文档。你可以使用  hint() 来强制全表或其它索引搜索。

比如我下面的代码:

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

全表索引:

> db.foo.find({x:{$ne:2}}).hint({$natural:1})
{ "_id" : 0 }
{ "_id" : 1, "x" : 1 }
{ "_id" : 3, "x" : 3 }
> 

3.复合索引

 复合索引同样可用于局部属性的搜索,但必须依照索引字段顺序。比如创建索引字段顺序"a,b,c",那么仅对"a,b,c"、"a,b"、"a"查询有效,而对"b,c"之类的组合无效。

上面这段话,在mongodb 也有效。

> db.order_detail.find()
{ "_id" : 1, "cust_id" : 1, "order_id" : 1, "prod_id" : 1 }
{ "_id" : 2, "cust_id" : 1, "order_id" : 1, "prod_id" : 2 }
{ "_id" : 3, "cust_id" : 2, "order_id" : 2, "prod_id" : 2 }
{ "_id" : 4, "cust_id" : 3, "order_id" : 2, "prod_id" : 1 }
{ "_id" : 5, "cust_id" : 3, "order_id" : 3, "prod_id" : 3 }
> db.order_detail.ensureIndex({cust_id:1,order_id:1})
> db.order_detail.getIndexes()
[{"v" : 1,
"key" : {"_id" : 1},
"ns" : "test.order_detail","name" : "_id_"},
{"v" : 1,
"key" : {"cust_id" : 1,"order_id" : 1},
"ns" : "test.order_detail",
"name" : "cust_id_1_order_id_1"}]

上面文档在建立完成复合索引后,我们来查询一下数据,并看看执行计划:

> db.order_detail.find({order_id:1}).explain()
{"cursor" : "BasicCursor","isMultiKey" : false,"n" : 2,"nscannedObjects" : 5,"nscanned" : 5,"nscannedObjectsAllPlans" : 5,"nscannedAllPlans" : 5,"scanAndOrder" : false,"indexOnly" : false,"nYields" : 0,"nChunkSkips" : 0,"millis" : 0,"indexBounds" : {},"server" : "localhost.localdomain:27017"
}

我指定了一个组合索引中后面一个字段进行查询可以看到,确实没用到索引

再来看看下面代码:

> db.order_detail.find({order_id:1}).sort({cust_id:1}).explain()
{"cursor" : "BtreeCursor cust_id_1_order_id_1","isMultiKey" : false,"n" : 2,"nscannedObjects" : 2,"nscanned" : 4,   "nscannedObjectsAllPlans" : 4,"nscannedAllPlans" : 6,   "scanAndOrder" : false,"indexOnly" : false, "nYields" : 0,"nChunkSkips" : 0,    "millis" : 0,"indexBounds" : {"cust_id" : [[{"$minElement" : 1},{"$maxElement" : 1}   ]],"order_id" : [[1,1]    ]},"server" : "localhost.localdomain:27017"
}
> 

我指定了一个组合索引中 后面一个字段进行查询,但我增加了一个第一个字段的排序。这时可以看到,它用到索引了。

看来还是有办法解决复合索引的缺陷的。

还有办法:

>db.order_detail.find({order_id:1}).hint({cust_id:1,order_id:1}).explain()
{"cursor" : "BtreeCursor cust_id_1_order_id_1","isMultiKey" : false,"n" : 2,"nscannedObjects" : 2,"nscanned" : 4,"nscannedObjectsAllPlans" : 2,"nscannedAllPlans" : 4,"scanAndOrder" : false,"indexOnly" : false,"nYields" : 0,"nChunkSkips" : 0,"millis" : 0,"indexBounds" : {"cust_id" : [[{"$minElement" : 1},{"$maxElement" : 1}]],"order_id" : [[1,1]]},"server" : "localhost.localdomain:27017"
}
>

我指定了一个组合索引中后面一个字段进行查询,但我使用了指定索引进行查询。

这时看到,查询也用到索引了。

但这时因为第一个字段为空值,在进行索引检索时,肯定会搜索更多的数据。

有可能是 fullindexsearch.

但总比全表索搜好吧。

【知识小课堂】4 之 索引相关推荐

  1. 【知识小课堂】 mongodb 之 objectId

    一.OBJECTID 因公司开发人员在使用MONGODB时,总遇到一些小问题.为了增加大家的mongodb 数据库知识. 决定每周进行一.两次的知识小课堂.这里把内容整理出来,上传到博客中.也算是自己 ...

  2. 宝付国际跨境知识小课堂 | 人民币外汇市场是个啥?

    全球化浪潮下,因为各个经济体的比较利益差异,产生了货物.服务.人员或资本之间的流动.各个经济体使用的当地货币不同,为了贸易或资本流动及其价值定价,本国的货币需要兑换成另一国的货币来结算,这个货币兑换的 ...

  3. 【知识小课堂】mongodb 之 特殊集合及索引

    1.固定集合 一般的集合都是动态的,可以自动增长以容纳越来越多的数据. 但MONGODB 还有另外一种集合:固定集合.集合大小创建时指定.如果没有空间了,就会自动删除最老的文档,以释放空间.(类似以一 ...

  4. 计算机知识小课堂宣传标语,创建高效课堂宣传标语50条

    创建高效课堂宣传标语50条 在日常学习.工作或生活中,大家都接触过很多优秀的标语吧,标语是指文字简练.意义鲜明的宣传.鼓动口号.那什么样的标语才算得上是经典呢?以下是小编精心整理的创建高效课堂宣传标语 ...

  5. 家电知识小课堂 帮您避过选购的那些坑

    本文来自IT168 大家在选购家电时,是否会或多或少拥有一些困惑呢?面对琳琅满目的众多产品,不知道该如何选择,甚至一不小心就可能陷入某些选购陷阱之中,多花了冤枉钱.下面我们就来为大家普及一些家电选购的 ...

  6. 模具制造设计知识小课堂

    "潇洒模具"--模具制造设计培训讲堂: 一,选择模具钢时什么是最重要的和最具有决定性意义的因素? 成形方法:可从两种基本材料类型中选择. A) 热加工工具钢,它能承受模铸.锻造和挤 ...

  7. 【知识小课堂】 之 聚合函数

    我们先来看几个简单的聚合命令: 1.count > db.foo.count() 4 > db.foo.find({_id:{$gte:2}}) { "_id" : 2 ...

  8. 【知识小课堂】mongodb 之 查询关键词使用

    查询关键词: $or 多个条件 满足其中一个 即可: Syntax:{ $or: [ { <expression1> }, { <expression2> }, ... , { ...

  9. 【知识小课堂】 mongodb 之字段中的【 数组】、【内嵌文档】

    一.介绍 MONGODB 的表结构 很灵活 .主要还是因为 字段中可以包含 [ 数组].[内嵌文档]. 现在简单介绍一下 字段中的[ 数组].[内嵌文档]相关的一些操作 (为了方便理解,还是以表来理解 ...

最新文章

  1. 理想ONE“偷袭”豪华品牌 李想强调不会收取金融服务费 | 2019上海车展
  2. 使用HTML5的classList属性操作CSS类
  3. Microsoft Visual Studio International Pack 1.0
  4. 《shop》 --- 商品图片上传功能
  5. Python 应用领域
  6. 智能自动PPR更改事件策略
  7. python管理系统web版_【程序源代码】python web 管理系统开发框架
  8. 全球品牌百强榜单出炉:中国品牌仅有华为上榜
  9. java static 对象加锁_java安全编码指南之:lock和同步的正确使用
  10. oracle 自动执行存储过程,oracle 自动执行存储过程
  11. javaweb框架和其他知识点总结
  12. 如何把网易云音乐ncm格式转换成mp3格式---记一下
  13. java ResourceBundle类
  14. 阿里架构师墙裂推荐Java岗实战文档:Spring全家桶+Docker+Redis
  15. 单片机电子密码锁C语言程序,以STC89C52单片机为核心的电子密码锁设计
  16. 理解计算-从根号 2 到 AlphaGo
  17. 奔腾服务器处理器性能,英特尔服务器出奇招 用奔腾M代替至强处理器
  18. [TMI2019-06]3D Auto-Context-Based Locality Adaptive Multi-Modality GANs for PET Synthesis
  19. Unity 灯光系统详解
  20. java rmi 推送_java 企业微信推送消息 示例源码

热门文章

  1. Oracle中类似于isql或osql的命令行工具
  2. 单表数据量过大处理策略
  3. uniGUI试用笔记(一)
  4. 21-matlab 迷宫题
  5. 软件工程--第六周学习进度
  6. C语言拼接字符串 -- 使用strcat()函数
  7. Delphi2009下编译提示“无法找到“Excel_TLB”
  8. 换Ubuntu邮件客户端Evolution为Thunderbird
  9. 关于linux中的 秘钥认证 ,最清晰解读
  10. 关于解决DevExpress用DevExpress patch工具破解后经常弹出试用框的问题