摘要:上一篇文章指南簡介下一篇文章指南基礎知識數據類型非常強大但很容易上手。把同種類型的文檔放在一個集合里,數據會更加集中。命名集合使用名稱進行標識。集合名不能是空字符串。簡單起見,數據庫名應全部小寫。
上一篇文章:MongoDB指南---1、MongoDB簡介
下一篇文章:MongoDB指南---3、MongoDB基礎知識-數據類型
MongoDB非常強大但很容易上手。本章會介紹一些MongoDB的基本概念。
文檔是MongoDB中數據的基本單元,非常類似于關系型數據庫管理系統中的行,但更具表現力。
類似地,集合(collection)可以看作是一個擁有動態模式(dynamic schema)的表。
MongoDB的一個實例可以擁有多個相互獨立的數據庫(database),每一個數據庫都擁有自己的集合。
每一個文檔都有一個特殊的鍵"_id", 這個鍵在文檔所屬的集合中是唯一的。
MongoDB自帶了一個簡單但功能強大的JavaScript shell,可用于管理MongoDB的實例或數據操作。
文檔是MongoDB的核心概念。文檔就是鍵值對的一個有序集。每種編程語言表示文檔的方法不太一樣,但大多數編程語言都有一些相通的數據結構,比如映射(map)、散列(hash)或字典(dictionary)。例如,在JavaScript 里面,文檔被表示為對象:
{"greeting" : "Hello, world!"}
這個文檔只有一個鍵"greeting",其對應的值為"Hello,world!"。大多數文檔會比這個簡單的例子復雜得多,通常會包含多個鍵/值對:
{"greeting" : "Hello, world!", "foo" : 3}
從上面的例子可以看出,文檔中的值可以是多種不同的數據類型(甚至可以是一個完整的內嵌文檔,詳見2.6.4節)。在這個例子中,"greeting"的值是一個字符串,而"foo"的值是一個整數。
文檔的鍵是字符串。除了少數例外情況,鍵可以使用任意UTF-8字符。
鍵不能含有0(空字符)。這個字符用于表示鍵的結尾。
.和$具有特殊意義,只能在特定環境下使用(后面的章節會詳細說明)。通常,這兩個字符是被保留的;如果使用不當的話,驅動程序會有提示。
MongoDB不但區分類型,而且區分大小寫。例如,下面的兩個文檔是不同的:
{"foo" : 3} {"foo" : "3"}
下面兩個文檔也是不同的:
{"foo" : 3} {"Foo" : 3}
還有一個非常重要的事項需要注意,MongoDB的文檔不能有重復的鍵。例如,下面的文檔是非法的:
{"greeting" : "Hello, world!", "greeting" : "Hello, MongoDB!"}
文檔中的鍵/值對是有序的:{"x" : 1, "y":2}與{"y": 2, "x": 1}是不同的。通常,字段順序并不重要,無須讓數據庫模式依賴特定的字段順序(MongoDB會對字段重新排序)。在某些特殊情況下,字段順序變得非常重要,本書將就此給出提示。
一些編程語言對文檔的默認表示根本就不包含順序問題(如:Python中的字典、Perl和Ruby 1.8中的散列)。通常,這些語言的驅動具有某些特殊的機制,可以在必要時指定文檔的順序。
集合就是一組文檔。如果將MongoDB中的一個文檔比喻為關系型數據庫中的一行,那么一個集合就相當于一張表。
2.2.1 動態模式集合是動態模式的。這意味著一個集合里面的文檔可以是各式各樣的。例如,下面兩個文檔可以存儲在同一個集合里面:
{"greeting" : "Hello, world!"} {"foo" : 5}
需要注意的是,上面的文檔不光值的類型不同(一個是字符串,一個是整數),它們的鍵也完全不同。因為集合里面可以放置任何文檔,隨之而來的一個問題是:還有必要使用多個集合嗎?這的確值得思考:既然沒有必要區分不同類型文檔的模式,為什么還要使用多個集合呢?這里有幾個重要的原因。
如果把各種各樣的文檔不加區分地放在同一個集合里,無論對開發者還是對管理員來說都將是噩夢。開發者要么確保每次查詢只返回特定類型的文檔,要么讓執行查詢的應用程序來處理所有不同類型的文檔。如果查詢博客文章時還要剔除含有作者數據的文檔,這會帶來很大困擾。
在一個集合里查詢特定類型的文檔在速度上也很不劃算,分開查詢多個集合要快得多。例如,假設集合里面一個名為"type"的字段用于指明文檔是skim、whole還是chunky monkey。那么,如果從一個集合中查詢這三種類型的文檔,速度會很慢。但如果將這三種不同類型的文檔拆分為三個不同的集合,每次只需要查詢相應的集合,速度快得多。
把同種類型的文檔放在一個集合里,數據會更加集中。從一個只包含博客文章的集合里查詢幾篇文章,或者從同時包含文章數據和作者數據的集合里查出幾篇文章,相比之下,前者需要的磁盤尋道操作更少。
創建索引時,需要使用文檔的附加結構(特別是創建唯一索引時)。索引是按照集合來定義的。在一個集合中只放入一種類型的文檔,可以更有效地對集合進行索引。
上面這些重要原因促使我們創建一個模式,把相關類型的文檔組織在一起,盡管MongoDB對此并沒有強制要求。
集合使用名稱進行標識。集合名可以是滿足下列條件的任意UTF-8字符串。
集合名不能是空字符串("")。
集合名不能包含0字符(空字符),這個字符表示集合名的結束。
集合名不能以“system.”開頭,這是為系統集合保留的前綴。例如,system.users這個集 合保存著數據庫的用戶信息,而system.namespaces集合保存著所有數據庫集合的信息。
用戶創建的集合不能在集合名中包含保留字符"$"。因為某些系統生成的集合中包含$,很多驅動程序確實支持在集合名里包含該字符。除非你要訪問這種系統創建的集合,否則不應該在集合名中包含$。
子集合組織集合的一種慣例是使用“.”分隔不同命名空間的子集合。例如,一個具有博客功能的應用可能包含兩個集合,分別是blog.posts和blog.authors。這是為了使組織結構更清晰,這里的blog集合(這個集合甚至不需要存在)跟它的子集合沒有任何關系。
雖然子集合沒有任何特別的屬性,但它們卻非常有用,因而很多MongoDB工具都使用了子集合。
GridFS(一種用于存儲大文件的協議)使用子集合來存儲文件的元數據,這樣就可以與文件內容塊很好地隔離開來。(第6章會詳細介紹GridFS。)
大多數驅動程序都提供了一些語法糖,用于訪問指定集合的子集合。例如,在數據庫shell中,db.blog代表blog集合,而db.blog.posts代表blog.posts集合。
在MongoDB中,使用子集合來組織數據非常高效,值得推薦。
2.3 數據庫在MongoDB中,多個文檔組成集合,而多個集合可以組成數據庫。一個MongoDB實例可以承載多個數據庫,每個數據庫擁有0個或者多個集合。每個數據庫都有獨立的權限,即便是在磁盤上,不同的數據庫也放置在不同的文件中。按照經驗,我們將有關一個應用程序的所有數據都存儲在同一個數據庫中。要想在同一個MongoDB服務器上存放多個應用程序或者用戶的數據,就需要使用不同的數據庫。
數據庫通過名稱來標識,這點與集合類似。數據庫名可以是滿足以下條件的任意UTF-8字符串。
不能是空字符串("")。
不得含有/、、.、"、*、<、>、:、|、?、$(一個空格)、0(空字符)。基本上,只能使用ASCII中的字母和數字。
數據庫名區分大小寫,即便是在不區分大小寫的文件系統中也是如此。簡單起見,數據庫名應全部小寫。
數據庫名最多為64字節。
要記住一點,數據庫最終會變成文件系統里的文件,而數據庫名就是相應的文件名,這是數據庫名有如此多限制的原因。
另外,有一些數據庫名是保留的,可以直接訪問這些有特殊語義的數據庫。這些數據庫如下所示。
admin
從身份驗證的角度來講,這是“root”數據庫。如果將一個用戶添加到admin數據庫,這個用戶將自動獲得所有數據庫的權限。再者,一些特定的服務器端命令也只能從admin數據庫運行,如列出所有數據庫或關閉服務器。
local
這個數據庫永遠都不可以復制,且一臺服務器上的所有本地集合都可以存儲在這個數據庫中。(第9章會詳細介紹復制及本地數據庫。)
config
MongoDB用于分片設置時(參見第13章),分片信息會存儲在config數據庫中。
把數據庫名添加到集合名前,得到集合的完全限定名,即命名空間(namespace)。例如,如果要使用cms數據庫中的blog.posts集合,這個集合的命名空間就是cms.blog.posts。命名空間的長度不得超過121字節,且在實際使用中應小于100字節。(參考附錄B,了解MongoDB中集合的命名空間及內部表示的更多信息。)
2.4 啟動MongoDB通常,MongoDB作為網絡服務器來運行,客戶端可連接到該服務器并執行操作。下載MongoDB(http://www.mongodb.org/downloads)并解壓,運行mongod命令,啟動數據庫服務器:
$ mongod mongod --help for help and startup options Thu Oct 11 12:36:48 [initandlisten] MongoDB starting : pid=2425 port=27017 dbpath=/data/db/ 64-bit host=spock Thu Oct 11 12:36:48 [initandlisten] db version v2.4.0, pdfile version 4.5 Thu Oct 11 12:36:48 [initandlisten] git version: 3aaea5262d761e0bb6bfef5351cfbfca7af06ec2 Thu Oct 11 12:36:48 [initandlisten] build info: Darwin spock 11.2.0 Darwin Kernel Version 11.2.0: Tue Aug 9 20:54:00 PDT 2011; root:xnu-1699.24.8~1/RELEASE_X86_64 x86_64 BOOST_LIB_VERSION=1_48 Thu Oct 11 12:36:48 [initandlisten] options: {} Thu Oct 11 12:36:48 [initandlisten] journal dir=/data/db/journal Thu Oct 11 12:36:48 [initandlisten] recover : no journal files present, no recovery needed Thu Oct 11 12:36:48 [websvr] admin web console waiting for connections on port 28017 Thu Oct 11 12:36:48 [initandlisten] waiting for connections on port 27017
在Windows系統中,執行這個命令:
$ mongod.exe
mongod在沒有參數的情況下會使用默認數據目錄/data/db(Windows系統中為C:datadb)。如果數據目錄不存在或者不可寫,服務器會啟動失敗。因此,在啟動MongoDB前,先創建數據目錄(如mkdir -p /data/db/),以確保對該目錄有寫權限,這點非常重要。
sudo mkdir -p /data/db/ sudo chmod -R 777 /data/db
啟動時,服務器會打印版本和系統信息,然后等待連接。默認情況下,MongoDB監聽27017端口。如果端口被占用,啟動將失敗。通常,這是由于已經有一個MongoDB實例在運行了。
mongod還會啟動一個非常基本的HTTP服務器,監聽數字比主端口號高1000的端口,也就是28017端口。這意味著,通過瀏覽器訪問http://localhost:28017,能獲取數據庫的管理信息。
中止mongod的運行,只須在運行著服務器的shell中按下Ctrl-C。
MongoDB自帶JavaScript shell,可在shell中使用命令行與MongoDB實例交互。shell非常有用,通過它可以執行管理操作,檢查運行實例,亦或做其他嘗試。對MongoDB來說,mongo shell是至關重要的工具,其應用之廣泛將體現在本書接下來的部分中。
2.5.1 運行shell運行mongo啟動shell:
$ mongo MongoDB shell version: 2.4.0 connecting to: test
啟動時,shell將自動連接MongoDB服務器,須確保mongod已啟動。
shell是一個功能完備的JavaScript解釋器,可運行任意JavaScript程序。為說明這一點,我們運行幾個簡單的數學運算:
> x = 200 200 > x / 5; 40
另外,可充分利用JavaScript的標準庫:
> Math.sin(Math.PI / 2); 1 > new Date("2010/1/1"); "Fri Jan 01 2010 00:00:00 GMT-0500 (EST)" > "Hello, World!".replace("World", "MongoDB"); Hello, MongoDB! 再者,可定義和調用JavaScript函數: > function factorial (n) { ... if (n <= 1) return 1; ... return n * factorial(n - 1); ... } > factorial(5); 120
需要注意,可使用多行命令。shell會檢測輸入的JavaScript語句是否完整,如沒寫完可在下一行接著寫。在某行連續三次按下回車鍵可取消未輸入完成的命令,并退回到>-提示符。
2.5.2 MongoDB客戶端能運行任意JavaScript程序聽上去很酷,不過shell的真正強大之處在于,它是一個獨立的MongoDB客戶端。啟動時,shell會連到MongoDB服務器的test數據庫,并將數據庫連接賦值給全局變量db。這個變量是通過shell訪問MongoDB的主要入口點。
如果想要查看db當前指向哪個數據庫,可以使用db命令:
> db test
為了方便習慣使用SQL shell的用戶,shell還包含一些非JavaScript語法的擴展。這些擴展并不提供額外的功能,而是一些非常棒的語法糖。例如,最重要的操作之一為選擇數據庫:
> use foobar switched to db foobar
現在,如果查看db變量,會發現其正指向foobar數據庫:
> db foobar
因為這是一個JavaScript shell,所以鍵入一個變量會將此變量的值轉換為字符串(即數據庫名)并打印出來。
通過db變量,可訪問其中的集合。例如,通過db.baz可返回當前數據庫的baz集合。因為通過shell可訪問集合,這意味著,幾乎所有數據庫操作都可以通過shell完成。
在shell中查看或操作數據會用到4個基本操作:創建、讀取、更新和刪除(即通常所說的CRUD操作)。
1. 創建insert函數可將一個文檔添加到集合中。舉一個存儲博客文章的例子。首先,創建一個名為post的局部變量,這是一個JavaScript對象,用于表示我們的文檔。它會有幾個鍵:"title"、"content"和"date"(發布日期)。
> post = {"title" : "My Blog Post", ... "content" : "Here"s my blog post.", ... "date" : new Date()} { "title" : "My Blog Post", "content" : "Here"s my blog post.", "date" : ISODate("2012-08-24T21:12:09.982Z") }
這個對象是個有效的MongoDB文檔,所以可以用insert方法將其保存到blog集合中:
> db.blog.insert(post)
這篇文章已被存到數據庫中。要查看它可用調用集合的find方法:
> db.blog.find() { "_id" : ObjectId("5037ee4a1084eb3ffeef7228"), "title" : "My Blog Post", "content" : "Here"s my blog post.", "date" : ISODate("2012-08-24T21:12:09.982Z") }
可以看到,我們曾輸入的鍵/值對都已被完整地記錄。此外,還有一個額外添加的鍵"_id"。"_id"突然出現的原因將在本章末尾解釋。
2. 讀取find和findOne方法可以用于查詢集合里的文檔。若只想查看一個文檔,可用findOne:
> db.blog.findOne() { "_id" : ObjectId("5037ee4a1084eb3ffeef7228"), "title" : "My Blog Post", "content" : "Here"s my blog post.", "date" : ISODate("2012-08-24T21:12:09.982Z") }
find和findOne可以接受一個查詢文檔作為限定條件。這樣就可以查詢符合一定條件的文檔。使用find時,shell會自動顯示最多20個匹配的文檔,也可獲取更多文檔。第4章會詳細介紹查詢相關的內容。
3. 更新使用update修改博客文章。update接受(至少)兩個參數:第一個是限定條件(用于匹配待更新的文檔),第二個是新的文檔。假設我們要為先前寫的文章增加評論功能,就需要增加一個新的鍵,用于保存評論數組。
首先,修改變量post,增加"comments"鍵:
> post.comments = [] [ ]
然后執行update操作,用新版本的文檔替換標題為“My Blog Post”的文章:
> db.blog.update({title : "My Blog Post"}, post)
現在,文檔已經有了"comments"鍵。再用find查看一下,可以看到新的鍵:
> db.blog.find() { "_id" : ObjectId("5037ee4a1084eb3ffeef7228"), "title" : "My Blog Post", "content" : "Here"s my blog post.", "date" : ISODate("2012-08-24T21:12:09.982Z"), "comments" : [ ] }4. 刪除
使用remove方法可將文檔從數據庫中永久刪除。如果沒有使用任何參數,它會將集合內的所有文檔全部刪除。它可以接受一個作為限定條件的文檔作為參數。例如,下面的命令會刪除剛剛創建的文章:
> db.blog.remove({title : "My Blog Post"})
現在,集合又是空的了。
上一篇文章:MongoDB指南---1、MongoDB簡介
下一篇文章:MongoDB指南---3、MongoDB基礎知識-數據類型
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/19566.html
摘要:上一篇文章指南簡介下一篇文章指南基礎知識數據類型非常強大但很容易上手。把同種類型的文檔放在一個集合里,數據會更加集中。命名集合使用名稱進行標識。集合名不能是空字符串。簡單起見,數據庫名應全部小寫。 上一篇文章:MongoDB指南---1、MongoDB簡介下一篇文章:MongoDB指南---3、MongoDB基礎知識-數據類型 MongoDB非常強大但很容易上手。本章會介紹一些Mon...
摘要:如將構造函數作為函數進行調用即不包括的方式,返回的是日期的字符串表示,而非日期對象。如果不注意這一點,沒有始終使用日期構造函數,將得到一堆混亂的日期對象和日期的字符串。關于日期類的完整解釋,以及構造函數的參數格式,參見規范節。 上一篇文章:MongoDB指南---2、MongoDB基礎知識-文檔、集合、數據庫、客戶端下一篇文章:MongoDB指南---4、MongoDB基礎知識-使用M...
摘要:如將構造函數作為函數進行調用即不包括的方式,返回的是日期的字符串表示,而非日期對象。如果不注意這一點,沒有始終使用日期構造函數,將得到一堆混亂的日期對象和日期的字符串。關于日期類的完整解釋,以及構造函數的參數格式,參見規范節。 上一篇文章:MongoDB指南---2、MongoDB基礎知識-文檔、集合、數據庫、客戶端下一篇文章:MongoDB指南---4、MongoDB基礎知識-使用M...
摘要:不采用關系模型主要是為了獲得更好的擴展性。易于擴展應用程序數據集的大小正在以不可思議的速度增長。過去非常罕見的級別數據,現在已是司空見慣了。這種精簡方式的設計是能夠實現如此高性能的原因之一。下一篇文章指南基礎知識文檔集合數據庫客戶端 下一篇文章:MongoDB指南---2、MongoDB基礎知識-文檔、集合、數據庫、客戶端 MongoDB是一款強大、靈活,且易于擴展的通用型數據庫。它...
摘要:不采用關系模型主要是為了獲得更好的擴展性。易于擴展應用程序數據集的大小正在以不可思議的速度增長。過去非常罕見的級別數據,現在已是司空見慣了。這種精簡方式的設計是能夠實現如此高性能的原因之一。下一篇文章指南基礎知識文檔集合數據庫客戶端 下一篇文章:MongoDB指南---2、MongoDB基礎知識-文檔、集合、數據庫、客戶端 MongoDB是一款強大、靈活,且易于擴展的通用型數據庫。它...
閱讀 2816·2023-04-25 15:01
閱讀 3044·2021-11-23 10:07
閱讀 3362·2021-10-12 10:12
閱讀 3452·2021-08-30 09:45
閱讀 2191·2021-08-20 09:36
閱讀 3584·2019-08-30 12:59
閱讀 2429·2019-08-26 13:52
閱讀 932·2019-08-26 13:24