一、說明
1、該系列MongoDB學習筆記的學習環境採用的MongoDB版本為mongodb-win32-i386-2.4.6,作業系統為win7。
二、安裝
1、建立兩個目錄,分別是D:\Installations\MongoDB-2.4.6\MongoDB和D:\Installations\MongoDB-2.4.6\MongoDBDATA(利用mongod啟動服務,需要指定一個資料目錄用於存放資料庫資料檔案,Windows下預設是C:\data\db)。
2、將下載的MongoDB壓縮包解壓,並拷貝裡面的檔案至D:\Installations\MongoDB-2.4.6\MongoDB目錄下,目錄結構如下:
3、將bin目錄配置到系統內容變數。
4、安裝MongoDB資料庫並啟動資料庫服務:如下圖這樣就安裝了MongoDB資料庫並啟動服務了(通過--dbpath顯示指定了資料目錄),以後要啟動該資料庫,使用同樣的命令即可。可以發現啟動資料庫服務後,預設情況下MongoDB監聽了27017連接埠,且會自動啟動一個http服務,監聽連接埠為28017,在瀏覽器中輸入http://localhost:28017就能登入web介面。
5、MongoDB還提供了以服務的形式進行資料庫啟動,如下:需要通過--logpath指定一個記錄檔的路徑
三、MongoDB與傳統的關係型資料庫
1、文檔
它是MongoDB中資料的基本單元,類似於關係型資料庫的行,多個索引值對有序地放置在一起便是文檔。MongoDB中對文檔的區分包括:索引值對的順序,鍵和值的類型,鍵和值的大小寫。在兩個文檔中如果這三者有任何一個不一致,這兩個文檔就不相同。文檔中索引值對的“值”的資料類型甚至還可以是整個嵌入的文檔。“鍵”則只能是字串,命名規則為:
鍵不能包含“\0”(Null 字元),這個用於表示鍵的結束
字元“$” 有特殊含義,在一般情況下避免使用
以“_” 底線開頭的名稱是為系統預留的,避免使用 另外,用“鍵(key)”表示表示傳統關係型資料庫中表的欄位。 2、集合 集合在MongoDB中代表一組文檔,類似於關係型資料庫中的表。但在MongoDB中的表(集合)是沒有模式的,可以將完全不同的文檔放入同一個集合中,但從資料庫管理、操作效率、構建索引等方面看,不支援這麼做,最佳實務是:為特定集合隱性規定一種模式。集合的命名規範為:
不可為空串""
不能包含“\0”(Null 字元),這是集合名稱結束的標誌
不能以“system.”開頭,這個是系統保留首碼
名稱中不能包含"$",這個字元為系統集合使用
組織集合的一個慣例是通過“.”字元分開的按命名空間劃分的子集合,比如user.class,集合user(可能並不存在)和這個子集合沒有任何關係
3、資料庫 一組集合就可以組成一個資料庫。一個MongoDB執行個體可以承載多個資料庫。每個資料庫都有獨立的許可權控制。其命名規範為:
不可為空串""
不能含有' '(空格)、.、$、\、/ 和\0(Null 字元)
應該全部小寫且最多64位元組
資料庫名最終會變成檔案系統的檔案名稱。MongoDB系統中有一些預置的特殊資料庫,這些名稱不可使用:
admin:從許可權的角度看,這是“root”資料庫,這個資料庫中的使用者,會繼承所有資料庫的許可權,一些特定的伺服器命令,如列出所有資料庫,關閉伺服器等也只能從這個資料庫執行。 local:這個資料庫中的資料不會被複製,可以用來儲存本地單台伺服器的任意集合
config:當Mongo用於分區設定時,該資料庫在內部被使用,用來儲存分區的相關資訊。
把資料庫名稱放置在集合名稱前面,就是集合的完全限定名,稱為命名空間。完全限定名長度不得超過121個位元組。
4、MongoDB中一個集合的每一個文檔中的key的個數、名稱以及類型可以是不一樣的。
四、MongoDB資料類型
JSON在資料類型方面,只支援:null,布爾,數字,字串,數組和對象。且JSON本身不直接支援日期類型,對於數字,也沒法區分整數和浮點數,更不能區分32位元字和64位元字。MongoDB採用BSON資料格式進行資料的傳輸與儲存,它是JSON的擴充,新增了諸如日期、浮點數等JSON不支援的資料類型。如下:
null:用於表示空值或不存在的欄位
布爾
數字:Shell中數字均為64位浮點數,所以通過Shell往集合中插入的文檔包含的數字均為64位浮點數。如果通過其他方式向集合中插入一個文檔包含32位整數,通過Shell將這個文檔進行更新,即使沒有更新這個32位整數對應的索引值對,這個數字也會被更新為64位浮點數。因為64位浮點數可以精確表示32位整數,顯示上也沒有問題。但64位浮點數表示64位整數有時就會出現問題,在Shell中查看64位整數時,會以一個內建文檔的形式呈現,如下圖: 內建文檔如果只有“floatApprox”這樣一個鍵,說明這個64位整數可以通過64位浮點數進行精確表示,如果這個數字不能被精確表示,則Shell顯示的內建文檔會在內建文檔中額外添加兩個鍵 “top” 和 “bottom”,分別表示高32位和低32 位 字串
日期:在資料存放區時,儲存的是從標準紀元開始的毫秒數,沒有儲存時區資訊
未定義:undefined
數組:數組是一組值,既可以表示為有序對象(列表,棧,隊列等)也可以表示無序對象(集合)。數組可以包含不同資料類型的元素,常規索引值對支援的所有實值型別都可以放到數組中。數組中也可以嵌套數組。文檔中的數組有個特性:MongoDB可以深入到數組內部進行搜尋。
內嵌文檔:把一個文檔整個作為另一個文檔某一個鍵對應的值。這樣來組織資料使得不用非得存為扁平結構。與數組一樣,MongoDB能夠理解內建文檔的結構,並深入到其中來構建索引,執行查詢等。
Regex:文檔中可以包含Regex,採用JavaScript的Regex文法即可。
對象ID:MongoDB中儲存的文檔必須有一個“_id”的鍵,其值可以為任意類型,但必須保證其值在一個集合中是唯一的,多個集合中可以存在“_id”相同的文檔。如果向集合中插入文檔時沒有指明“_id”,則系統會自動向文檔中加上這個鍵,其值預設為ObjectId對象。ObjectId是“_id”的預設值類型,不同機器可以採用同樣的機制去產生不同的主鍵。MongoDB沒有採用自增長這種最常用的主鍵策略,是因為其天生面向分散式資料庫,在大量主機間同步自增長的主索引值費時,費力還容易出錯。ObjectId採用12個位元組的儲存空間,分為四組,按照此方式產生:{0,1,2,3}|{4,5,6}|{7,8}|{9,10,11},分別是時間戳記、機器、PID和計數器。這樣就足可以保證這個值的唯一性。最佳實務是:在插入文檔時加上這個鍵,並且保證其值是集合中唯一的。這樣能減少資料庫端的開銷,並且也體現了一種設計理念:能從資料庫層轉移到應用程式層的操作就轉移出去,畢竟擴充應用程式層比擴充資料庫層容易。如果是這樣做的,在插入文檔後還可以將文檔的“_id”直接返回給用戶端,如果通過MongoDB去產生這個值,插入文檔後還需find一遍,才可以得到這個值。
五、MongoDB Shell命令列與基本使用
1、MongoDB內建一個JavaScript Shell,它是一個JavaScript解譯器,還是一個MongoDB的用戶端,可以通過JavaScript與啟動的資料庫執行個體進行互動(Shell中命令區分大小寫)。在Shell中,每當寫完一句完整的JS代碼,Shell就會將其結果返回。
2、啟動資料庫服務後就可以登入shell命令列:如下圖,預設是登入test資料庫的,如果要登入admin資料庫,可以使用該命令:mongo 127.0.0.1:27017/admin。也可以只使用命令mongo,則串連的是本機資料庫伺服器的test資料庫。串連後,會將這個資料庫連接賦值給全域變數db。
3、查看所有的資料庫:show dbs。
4、建立一個資料庫與資料庫之間的切換:use 資料庫名,使用該命令可以在不同的資料庫之間進行切換(切換全域變數db當前指向的資料庫);當要切換的資料庫不存在時,會建立該名稱的資料庫,但是這個資料庫並沒有真正的被建立,它只是在MongoDB緩衝中,也就是在預先處理緩衝池中有該資料庫,如果什麼也不幹就離開的話,該資料庫會被MongoDB自動刪除;當為該資料庫加入集合後才會真正地被建立。
5、查看某個資料庫中所有的集合:show collections。如果該資料庫中有已經存在的集合,並該集合中插入了文檔,那麼使用該命令查看集合時會發現多了一個system.indexes的集合,它負責儲存索引,這是因為在插入一個文檔時,如果沒有一個叫做“_id”的key,那麼會自動加入一個“_id”的key,系統預設會為該key建立唯一索引,所以在增加一個system.indexes的集合。
6、刪除資料庫中指定的集合:db.集合名.drop()。這裡的db就是表示當前進入到的資料庫,使用.集合名的方式就能夠獲得資料庫中的某個集合,還可以使用db["集合名"]的方式來擷取某個集合,特別是集合名含有某些特殊字元時,使用"."的方式很可能擷取不到,此時使用[]的方式就特別有效;除了這兩種方式擷取一個集合外,還可以使用函數getCollection,如db.getCollection("集合名").drop()。且集合在第一次使用時會被建立。
7、刪除當前資料庫:db.dropDatabase()。
8、shell中的help函數:當進入到某個資料庫中,要如何知道可以使用哪些操作呢。此時就可以使用help函數,如下圖,就能夠列出資料庫層級有哪些用法了,當然除了資料庫層級的help,還有集合層級的help,使用方法為:db.集合名.help()。在函數名稱後面不添加“()”還可以查看函數的源碼。
8、Shell內建的JS引擎可以直接執行執行JS代碼,如下
如果啟動Shell僅是想實驗一下JavaScript,則運行mongo --nodb得到的Shell沒有串連任何資料庫。
9、雖然Shell中提供的全域變數db指向當前串連的資料庫,但還可以用其它的變數來儲存其它串連的資料庫,利用Shell中提供的connect()命令即可,如下圖: