mongo 唯一約束索引_快速掌握mongoDB(三)——mongoDB的索引詳解

1 mongoDB索引的管理

本節介紹mongoDB中的索引,熟悉mysql/sqlserver等關系型數據庫的小伙伴應該都知道索引對優化數據查詢的重要性。我們先簡單了解一下索引:索引的本質就是一個排序的列表,在這個列表中存儲著索引的值和包含這個值的數據(數據row或者document)的物理地址,索引可以大大加快查詢的速度,這是因為使用索引后可以不再掃描全表來定位某行的數據,而是先通過索引表找到該行數據對應的物理地址(多數為B-tree查找),然后通過地址來訪問相應的數據。

索引可以加快數據檢索、排序、分組的速度,減少磁盤I/O,但是索引也不是越多越好,因為索引本身也是數據表,需要占用存儲空間,同時索引需要數據庫進行維護,當我們對索引列的值進行增改刪操作時,數據庫需要更新索引表,這會增加數據庫的壓力。

我們要根據實際情況來判斷哪些列適合添加索引,哪些列不適合添加索引,一般遵循的規律如下:

主/外鍵列,主鍵用于強制該列的唯一性和組織表中數據的排列結構;外鍵可以加快連接的速度;

經常用于比較的類(大于小于等于等),因為索引已經排序,值就是大于/小于的分界點;

經常進行范圍搜索,因為索引已經排序,其指定的范圍是連續的;

經常進行排序的列,因為索引已經排序,這樣查詢可以利用索引的排序,加快排序查詢時間;

經常進行分組的列,因為索引已經排序,同一個值的所有數據地址會聚集在一塊,很方便分組。

我們看一下mongoDB的索引使用,首先準備數據:

db.userinfos.insertMany([

{_id:1, name: "張三", age: 23,level:10, ename: { firstname: "san", lastname: "zhang"}, roles: ["vip","gen"]},

{_id:2, name: "李四", age: 24,level:20, ename: { firstname: "si", lastname: "li"}, roles:[ "vip"]},

{_id:3, name: "王五", age: 25,level:30, ename: { firstname: "wu", lastname: "wang"}, roles: ["gen","vip"]},

{_id:4, name: "趙六", age: 26,level:40, ename: { firstname: "liu", lastname: "zhao"}, roles: ["gen"] },

{_id:5, name: "田七", age: 27, ename: { firstname: "qi", lastname: "tian"}, address:'北京'},

{_id:6, name: "周八", age: 28,roles:["gen"], address:'上海'}

]);

索引的增刪改查還是十分簡單的,我們看一下索引管理的幾個方法:

//創建索引,值1表示正序排序,-1表示倒序排序db.userinfos.createIndex({age:-1})//查看userinfos中的所有索引

db.userinfos.getIndexes()//刪除特定一個索引

db.userinfos.dropIndex({name:1,age:-1})//刪除所有的索引(主鍵索引_id不會被刪除)

db.userinfos.dropIndexes()//如果我們要修改一個索引的話,可以先刪除索引然后在重新添加。

2 mongoDB中常用的索引類型

1 單鍵索引

單鍵索引(Single Field Indexes)顧名思義就是單個字段作為索引列,mongoDB的所有collection默認都有一個單鍵索引_id,我們也可以對一些經常作為過濾條件的字段設置索引,如給age字段添加一個索引,語法十分簡單:

//給age字段添加升序索引

db.userinfos.createIndex({age:1})

其中{age:1}中的1表示升序,如果想設置倒序索引的話使用?db.userinfos.createIndex({age:-1})?即可。我們通過explain()方法查看查詢計劃,如下圖,看到查詢age=23的document時使用了索引,如果沒有使用索引的話stage=COLLSCAN。

因為document的存儲是bson格式的,我們也可以給內置對象的字段添加索引,或者將整個內置對象作為一個索引,語法如下:

//1.內嵌對象的某一字段作為索引//在ename.firstname字段上添加索引

db.userinfos.createIndex({"ename.firstname":1})//使用ename.firstname字段的索引查詢

db.userinfos.find({"ename.firstname":"san"})//2.整個內嵌對象作為索引//給整個ename字段添加索引

db.userinfos.dropIndexes()//使用ename字段的索引查詢

db.userinfos.createIndex({"ename":1})

2 復合索引

復合索引(Compound Indexes)指一個索引包含多個字段,用法和單鍵索引基本一致。使用復合索引時要注意字段的順序,如下添加一個name和age的復合索引,name正序,age倒序,document首先按照name正序排序,然后name相同的document按age進行倒序排序。mongoDB中一個復合索引最多可以包含32個字段。

//添加復合索引,name正序,age倒序

db.userinfos.createIndex({"name":1,"age":-1})//過濾條件為name,或包含name的查詢會使用索引(索引的第一個字段)

db.userinfos.find({name:'張三'}).explain()

db.userinfos.find({name:"張三",level:10}).explain()

db.userinfos.find({name:"張三",age:23}).explain()//查詢條件為age時,不會使用上邊創建的索引,而是使用的全表掃描

db.userinfos.find({age:23}).explain()

執行查詢時查詢計劃如下:

3 多鍵索引

多鍵索引(mutiKey Indexes)是建在數組上的索引,在mongoDB的document中,有些字段的值為數組,多鍵索引就是為了提高查詢這些數組的效率。看一個栗子:準備測試數據,classes集合中添加兩個班級,每個班級都有一個students數組,如下:

db.classes.insertMany([

{"classname":"class1","students":[{name:'jack',age:20},

{name:'tom',age:22},

{name:'lilei',age:25}]

},

{"classname":"class2","students":[{name:'lucy',age:20},

{name:'jim',age:23},

{name:'jarry',age:26}]

}]

)

為了提高查詢students的效率,我們使用?db.classes.createIndex({'students.age':1})?給students的age字段添加索引,然后使用索引,如下圖:

4 哈希索引

哈希索引(hashed Indexes)就是將field的值進行hash計算后作為索引,其強大之處在于實現O(1)查找,當然用哈希索引最主要的功能也就是實現定值查找,對于經常需要排序或查詢范圍查詢的集合不要使用哈希索引。

3 mongoDB中常用的索引屬性

1? 唯一索引

唯一索引(unique indexes)用于為collection添加唯一約束,即強制要求collection中的索引字段沒有重復值。添加唯一索引的語法:

//在userinfos的name字段添加唯一索引

db.userinfos.createIndex({name:1},{unique:true})

看一個使用唯一索引的栗子:

2? 局部索引

局部索引(Partial Indexes)顧名思義,只對collection的一部分添加索引。創建索引的時候,根據過濾條件判斷是否對document添加索引,對于沒有添加索引的文檔查找時采用的全表掃描,對添加了索引的文檔查找時使用索引。使用方法也比較簡單:

//userinfos集合中age>25的部分添加age字段索引

db.userinfos.createIndex(

{age:1},

{ partialFilterExpression: {age:{$gt:25}}}

)//查詢age<25的document時,因為age<25的部分沒有索引,會全表掃描查找(stage:COLLSCAN)

db.userinfos.find({age:23})//查詢age>25的document時,因為age>25的部分創建了索引,會使用索引進行查找(stage:IXSCAN)

db.userinfos.find({age:26})

當查詢age=23的記錄時,stage=COLLSCAN,當查詢age=26的記錄時,使用了索引,如下:

2 稀疏索引

稀疏索引(sparse indexes)在有索引字段的document上添加索引,如在address字段上添加稀疏索引時,只有document有address字段時才會添加索引。而普通索引則是為所有的document添加索引,使用普通索引時如果document沒有索引字段的話,設置索引字段的值為null。

稀疏索引的創建方式如下,當document包含address字段時才會創建索引:

//創建在address上創建稀疏索引

db.userinfos.createIndex({address:1},{sparse:true})

看一個使用稀疏索引的栗子:

4 TTL索引

TTL索引(TTL indexes)是一種特殊的單鍵索引,用于設置document的過期時間,mongoDB會在document過期后將其刪除,TTL非常容易實現類似緩存過期策略的功能。我們看一個使用TTL索引的栗子:

//添加測試數據

db.logs.insertMany([

{_id:1,createtime:new Date(),msg:"log1"},

{_id:2,createtime:new Date(),msg:"log2"},

{_id:3,createtime:new Date(),msg:"log3"},

{_id:4,createtime:new Date(),msg:"log4"}

])//在createtime字段添加TTL索引,過期時間是120s

db.logs.createIndex({createtime:1}, { expireAfterSeconds: 120})//logs中的document在創建后的120s后過期,會被mongoDB自動刪除

注意:TTL索引只能設置在date類型字段(或者包含date類型的數組)上,過期時間為字段值+exprireAfterSeconds;document過期時不一定就會被立即刪除,因為mongoDB執行刪除任務的時間間隔是60s;capped Collection不能設置TTL索引,因為mongoDB不能主動刪除capped Collection中的document。

小結

本節介紹了mongoDB中常用的索引和索引屬性,索引對提升數據檢索的速度十分重要,在數據量比較大的時候一般都要在collection上建立索引。mongoDB提供的索引種類很豐富,總會有幾種適用于我們的業務,除了上邊介紹的索引外,mongoDB還支持text index和一些地理位置相關的索引,這里不再介紹,有興趣的小伙伴可以到官網?研究下。如果文中有錯誤的話,希望大家可以指出,我會及時修改,謝謝。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/371396.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/371396.shtml
英文地址,請注明出處:http://en.pswp.cn/news/371396.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

HBase MapReduce

1. HBase to HBase Mapper 繼承 TableMapper&#xff0c;輸入為Rowkey和Result. public abstract class TableMapper<KEYOUT, VALUEOUT> extends Mapper<ImmutableBytesWritable, Result, KEYOUT, VALUEOUT> { public TableMapper() { }} package com.scb.ja…

第六期的知識點

1.volatile詳解 在應用程序中&#xff0c;volatile主要是被設計用來修飾被不同線程訪問和修改的變量 .volatile的本意是“易變的” 因為訪問寄存器要比訪問內存單元快的多,所以編譯器一般都會作減少存取內存的優化&#xff0c;但有可能會讀臟數據。當要求使用volatile聲明變量值…

在DelayQueue中更改延遲,從而更改順序

因此&#xff0c;我正在研究構建一個簡單的對象緩存&#xff0c;該緩存在給定時間后會使對象過期。 顯而易見的機制是使用Java并發包中的DelayedQueue類。 但我想知道是否有可能在將對象添加到隊列后更新延遲。 看一下Delayed接口&#xff0c;似乎沒有充分的理由不在文檔中&…

vi編輯器服務器維護,vi編輯器有哪幾種工作模式及如何轉換_網站服務器運行維護,vi編輯器,工作模式...

整理分享一些 Linux思維導圖(值得收藏)_網站服務器運行維護本篇文章整理分享了一些 Linux思維導圖(值得收藏)。有一定的參考價值&#xff0c;有需要的朋友可以參考一下&#xff0c;希望對大家有所幫助。vi編輯器有三種基本的工作模式&#xff0c;分別是&#xff1a;指令行模式、…

(八)cmockery中的calculator和run_tests函數的注釋代碼

所分析的calculator.c和calculator_test.c文件位于 工程中的 cmockery/src/example/ 目錄下&#xff0c;是一個相對而言比較全面的樣例程序&#xff0c;用到了cmockery項目中的大多數單元測試方法。基本上涵蓋了之前所有的樣例程序中的用法&#xff0c;還有兩組測試是database操…

家用雙wan口路由器推薦_請推薦雙WAN口的有線千兆硬路由器?

利益相關&#xff1a;TP-LINK一線銷售人員(來看看會不會有推薦我司產品的2333 )路由器&#xff1a;TL-ER3220G&#xff0c;帶機量300終端&#xff0c;可管理50個AP&#xff0c;最大支持四條寬帶接入POE交換機&#xff1a;TL-SF1005P(5口百兆) TL-SG1005P(5口千兆) TL-SF1009PH(…

第一章魔獸窗口

開始顯示第一個窗體 用戶直接點登陸的話就會提示用戶名不能為空密碼不能為空 沒有賬號的話只能先注冊&#xff0c;點擊藍色摁鈕進入下一個窗體 這里有判斷是否為空&#xff0c;注冊成功后利用窗體傳值&#xff0c;并且打開第一個窗口 把注冊的用戶名和密碼寫上去就可以的登陸到…

Apache Digester示例–輕松配置

解決問題–硬編碼&#xff0c;需要為您的應用程序創建自定義配置&#xff0c;例如struts配置文件&#xff0c;以僅通過更改文件來改變應用程序行為。 Apache Digester可以輕松為您完成此任務。 使用Apache Digester相當容易將XML文檔轉換為相應的Java bean對象層次結構。 請參閱…

騰訊云搭svn服務器,騰訊云使用筆記二: 安裝svn服務器及web同步

A01&#xff1a;安裝subversionsudo apt-get install subversionA02:創建倉庫很多目錄可以放subversion文件倉庫&#xff0c;最常見的是/usr/local/svn和/home/svnsudo mkdir -p /home/svn/youshengyousesudo svnadmin create /home/svn/youshengyouse//說明&#xff1a;先創建…

python將圖像轉換為8位單通道_使用Python將圖片轉換為單通道黑白圖片

本文介紹如何使用python將圖片轉換為純黑白的單通道圖片。文中用到的腳本支持彩色、灰度、帶alpha通道的輸入圖片以及SVG矢量圖&#xff0c;支持調整輸出圖片大小以及設置灰度閾值。最后介紹如何輸出SSD1306 OLED顯示屏可用的XBM文件&#xff0c;并利用輸出的XBM數據在0.96寸的…

Java FlameGraph 火焰圖

上周一個偶然的機會聽同事提到了Java FlameGraph&#xff0c;剛實驗了一下&#xff0c;效果非常好。 一、什么是FlameGraph 直接看圖說話。FlameGraph 是 SVG格式&#xff0c;矢量圖&#xff0c;可以隨意擴大縮小&#xff0c;看不清的信息可以放大看。圖中&#xff0c;各種紅橙…

ADB 常用命令

獲取Android設備號 adb shell getprop ro.serialno 獲取系統版本 adb shell getprop ro.build.version.release>4.2.2 獲取系統api版本 adb shell getprop ro.build.version.sdk>17 獲取設備分辨率&#xff08;SDK4.3&#xff09; adb shell wm size獲取設備屏幕密度&am…

哪個Java線程消耗了我的CPU?

當您的Java應用程序占用100&#xff05;的CPU時&#xff0c;您該怎么辦&#xff1f; 事實證明&#xff0c;您可以使用內置的UNIX和JDK工具輕松找到有問題的線程。 不需要探查器或代理。 為了進行測試&#xff0c;我們將使用以下簡單程序&#xff1a; public class Main {publi…

煙草局計算機筆試,2020年廣西南寧煙草局什么時候筆試?

最近廣西煙草局各地市社招通知頻發&#xff0c;南寧煙草局報名截止至今都無任何消息&#xff0c;根據往年的考情&#xff0c;通知近期很大可能會發布&#xff0c;將于6月底完成筆面!你備考好了嗎&#xff1f;今天廣西中公國企小編來給大家說一下南寧煙草局社招的筆試內容及備考…

JAVA Swing 組件演示***

下面是Swing組件的演示&#xff1a; package a_swing;import java.awt.BorderLayout; import java.awt.Color; import java.awt.Container; import java.awt.Cursor; import java.awt.Dimension; import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.…

Spring 3.1緩存和@CacheEvict

我的上一個博客演示了Spring 3.1的Cacheable批注的應用&#xff0c; Cacheable批注用于標記返回值將存儲在緩存中的方法。 但是&#xff0c; Cacheable只是Spring的Guy為緩存而設計的一對注釋??中的一個&#xff0c;另一個是CacheEvict 。 像Cacheable一樣&#xff0c; Cache…

centos 獲取硬件序列號_如何在 Linux 上查找硬件規格

在 Linux 系統上有許多工具可用于查找硬件規格。-- Sk&#xff08;作者&#xff09;在 Linux 系統上有許多工具可用于查找硬件規格。在這里&#xff0c;我列出了四種最常用的工具&#xff0c;可以獲取 Linux 系統的幾乎所有硬件&#xff08;和軟件&#xff09;細節。好在是這些…

位置服務器管理器,查看 DIMM 位置

鍵入&#xff1a;-> show /System/Memory/DIMMs -t locationTarget | Property | Value-----------------------------------------------------------------------/System/Memory/DIMMs/ | location | CMIOU0/CM/CMP/BOB00/CH0/DIMM (CPU MemoryDIMM_0 | | IO Unit 0 Memor…

Spring –持久層–編寫實體并配置Hibernate

歡迎來到本教程的第二部分。 當您看到本文有多長時間時&#xff0c;請不要驚慌–我向您保證&#xff0c;這主要是簡單的POJO和一些生成的代碼。 在開始之前&#xff0c;我們需要更新我們的Maven依賴項&#xff0c;因為我們現在將使用Hibernate和Spring。 將以下依賴項添加到pom…

無線服務器主機名是,wifi默認服務器主機名

wifi默認服務器主機名 內容精選換一換以CentOS 7操作系統的彈性云服務器為例&#xff1a;登錄Linux彈性云服務器&#xff0c;查看“cloud-init”的配置文件。檢查“/etc/cloud/cloud.cfg”文件中“update_hostname”是否被注釋或者刪除。如果沒有被注釋或者刪除&#xff0c;則需…