MongoDB簡介 MongoDB在功能和複雜性之間取得了很好的平衡,並且大大簡化了原先十分複雜的任務,它具備支撐今天主流web應用的關鍵功能:索引、複製、分片、豐富的查詢語法,特別靈活的數據模型。與此同時還不犧牲速度。 MongoDB是一款強大、靈活,且易於擴展的通用型資料庫。能擴展出非常多的功能 ...
MongoDB簡介
MongoDB在功能和複雜性之間取得了很好的平衡,並且大大簡化了原先十分複雜的任務,它具備支撐今天主流web應用的關鍵功能:索引、複製、分片、豐富的查詢語法,特別靈活的數據模型。與此同時還不犧牲速度。
MongoDB是一款強大、靈活,且易於擴展的通用型資料庫。能擴展出非常多的功能,如二級索引、範圍查詢、排序、聚合,以及地理空間索引。
設計特點
易於使用
MongoDB是一個面向文檔的資料庫,比關係型資料庫有更好的擴展性。用文檔代替行。能夠僅使用一條記錄來表現發展的層次關係。
文檔的鍵和值不再是固定的類型和大小。
易於擴展
MongoDB的設計採用橫向擴展。面向文檔的數據模型使它能很容易的在多台伺服器之間進行數據分割。
MongoDB能自動處理跨集群的數據和負載,自動重新分配文檔,以及將用戶請求路由到正確的機器上。如果一個集群需要很大的容量,只需向集群添加新伺服器,MongoDB就會自動將現有數據向新伺服器傳送。
豐富的功能
MongoDB作為一款通用型資料庫,除了能夠增刪改查之外,還有一系列不斷擴展的獨特功能。
索引
MongoDB支持通用二級索引,允許多種快速查詢,且提供唯一索引、符合索引、地理空間索引,以及全文索引。
聚合
MongoDB支持“聚合管道”。用戶能通過簡單的片段創建複雜的聚合,並通過資料庫自動優化。
特殊的集合類型
MongoDB支持存在時間有限的集合,適用於那些將在某個時刻過期的數據,如會話。類似的,MongoDB也支持固定大小的集合,用於保存近期數據,如日誌。
文件存儲
MongoDB支持一種非常易用的協議,用於存儲大文件和文件元數據。
MongoDB不具備連接和複雜的多行事務
卓越的性能
MongoDB能對文檔進行動態填充,也能預分配數據文件以利用額外的空間換取穩定的性能。MongoDB把儘可能多的記憶體用作緩存,試圖為每次查詢自動選擇正確的索引。
MongoDB基礎知識
1.文檔是MongoDB中數據的基本單元,非常類似mysql的行,但更具表現力。
2.集合可以看作是一個擁有動態模式的表。
3.MongoDB的一個實例可以擁有多個相互獨立的資料庫,每一個資料庫都擁有自己的集合。
4.每一個文檔都有一個特殊的鍵“_id”,在文檔所屬的集合中是唯一的。
5.MongoDB自帶js shell,可用於管理MongoDB的實例或數據操作。
文檔(類似mysql的行)
文檔就是鍵值對的一個有序集。比如:{“greeting”:”hello world!”,”foo”:3},文檔的鍵是字元串。鍵可以是任意utf-8字元。除了少數情況:
- 鍵不能含有\0(空字元)。這個字元用於表示鍵的結尾。
- .和$具有特殊意義,只能在特定環境下使用。
MongoDB不但區分類型,而且區分大小寫,{“foo”:3}、{“foo”:”3”}、{“Foo”:3}三個文檔是不同的。
MongoDB的文檔不能有重覆的鍵。{“foo”:”3”,”foo”,3}文檔非法。
文檔中的鍵值對是有序的。{“x”:1,”y”:2}與{“y”:2,”x”:1}是不同的。
集合(類似mysql中的表)
集合就是一組文檔。
動態模式
集合是動態模式的。這意味著一個集合裡面的文檔可以是各式各樣的。可以放置任何文檔,既然如此,為何還要把相關類型的文檔組織在一起,使用多個集合,而不是通通放在一個集合里呢?原因如下:
- 難以管理
- 速度不划算,分開查詢多個集合要快得多。
- 把同種類型的文檔放在一個集合里,數據會更加集中。磁碟尋道操作更少。
- 在一個集合中只放入一種類型的文檔,可以更加有效地對集合進行索引。
命名
集合使用名稱進行標識,可以是任意的utf-8字元串,除了以下特殊情況:
- 不能是空字元串(“”)
- 不能包含\0字元(空字元),這個字元表示集合名的結束。
- 不能以”system.”開頭,這是為系統集合保留的首碼。例如:system.users保存著資料庫的用戶信息,system.namespaces保存著所有資料庫集合的信息。
- 不能包含保留字元’$’
子集合
組織集合的一種慣例是使用“.”分隔不同命名空間的子集合。為了使組織結構更清晰,比如(blog.posts和blog.authors),雖然子集合沒有任何特別的屬性,但他們卻非常有用。使用子集合來組織數據非常高效。
資料庫
多個集合可以組成資料庫。一個MongoDB實例可以承載多個資料庫,每個資料庫擁有0個或多個集合。每個資料庫都有獨立的許可權。不同的資料庫放置在不同的文件中。
命名
資料庫最終會變成文件系統里的文件,資料庫名就是相應的文件名,因此命名會有很多限制。資料庫通過名稱來標識。可以是任意的utf-8字元串,除了以下特殊情況:
- 不能是空字元串(“”)
- 不得含有/、\、.、’’、*、<、>、:、|、 ?、$(一個空格)、\0(空字元)。基本上,只能使用ASCII中的字母和數字。
- 區分大小寫,為簡單起見,應全部小寫。
- 資料庫名最多64位元組。
保留資料庫名
有一些資料庫名是保留的,可以直接訪問這些有特殊語義的資料庫。
admin
從身份驗證的角度看,這是“root”資料庫。如果將一個用戶添加到了admin資料庫,將自動獲得所有資料庫的許可權。再者,一些特定的服務端命令也只能從admin資料庫運行,如列出所有資料庫或關閉伺服器。
local
這個資料庫永遠都不可以複製,且一臺伺服器上的所有本地集合都可以存儲在這個資料庫中。
config
MongoDB用於分片設置時,分片信息會存儲在config資料庫中。
啟動MongoDB
window下,如果配置了環境變數,直接使用 mongod 命令即可。
mongod在沒有任何參數的情況下會預設使用數據目錄 /data/db (window系統中為C:\data\db).如果不存在或不可寫,伺服器會啟動失敗。
啟動時,伺服器會列印版本和系統信息,然後等待連接。預設監聽發27017埠。埠被占用,啟動將失敗。通常是已經有一個實例在運行了。
mongod還會啟動一個非常基本的http伺服器,監聽28017埠,因此,通過http://localhost:28017,能獲取資料庫的管理信息。(測試時找不到網頁,不知道哪裡沒對。)
Shell中 ctrl+c,中止mongod的運行。
Linux下,啟動方式
[root@yang ~]# cd /usr/local/mongodb/
[root@yang mongodb]# ./bin/mongod --dbpath /home/m17/ --logpath /home/mlog/m17.log --fork --port 27017
其中 --dbpath 指定資料庫存放數據目錄,--logpath 指定日誌存放目錄,--fork 指定為後臺線程,--port 指定埠。
啟動shell
Shell中可以使用命令行與MongoDB實例交互。可通過它執行管理操作,檢查運行實例等等。啟動shell使用 mongo 命令,啟動時,shell將自動連接MongoDB伺服器,須確保 mongod 已啟動。
Linux下,啟動方式:
[root@yang mongodb]# ./bin/mongo
MongoDB shell version: 3.2.10
connecting to: test
Server has startup warnings:
2016-11-18T20:35:22.477+0800 I CONTROL [initandlisten] ** WARNING: You are running this process as the root user, which is not recommended.
2016-11-18T20:35:22.477+0800 I CONTROL [initandlisten]
2016-11-18T20:35:22.478+0800 I CONTROL [initandlisten]
2016-11-18T20:35:22.478+0800 I CONTROL [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/enabled is 'always'.
2016-11-18T20:35:22.478+0800 I CONTROL [initandlisten] ** We suggest setting it to 'never'
2016-11-18T20:35:22.478+0800 I CONTROL [initandlisten]
2016-11-18T20:35:22.478+0800 I CONTROL [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/defrag is 'always'.
2016-11-18T20:35:22.478+0800 I CONTROL [initandlisten] ** We suggest setting it to 'never'
2016-11-18T20:35:22.478+0800 I CONTROL [initandlisten]
Shell是一個功能完備的js解釋器。
MongoDB客戶端
Shell是一個獨立的MongoDB客戶端。啟動時,shell會連到MongoDB伺服器的test資料庫,並將資料庫連接賦值給全局變數db。這個變數是通過shell訪問MongoDB的主要入口點。
查看當前指向哪個資料庫,使用 db命令
Shell還包含了一些非js語法的擴展。這些擴展並不提供額外的功能,而是一些非常棒的語法糖。比如:
通過db變數,可訪問其中的集合。幾乎所有資料庫操作都可以通過shell完成。
Shell中的基本操作
創建 insert()
> 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("2016-12-11T13:28:54.930Z")
}
> db.blog.insert(post)
WriteResult({ "nInserted" : 1 })
讀取 find() 、findOne()
find():shell會自動顯示最多20個匹配的文檔
findOne() 只查看一個文檔
> db.blog.find()
{ "_id" : ObjectId("584d57e5bf1475cad287df45"), "title" : "My Blog Post", "content" : "Here's my blog post.", "date" : ISODate("2016-12-11T13:42:52.351Z") }
> db.blog.findOne()
{ "_id" : ObjectId("584d57e5bf1475cad287df45"), "title" : "My Blog Post", "content" : "Here's my blog post.", "date" : ISODate("2016-12-11T13:42:52.351Z") }
更新update()
接受至少兩個參數:
參數1:限定條件,參數2:新的文檔
> post={
... "title":"My Blog Post",
... "content":"Here's my blog post.",
... "date":new Date(),
... "comments":[]
... }
{
"title" : "My Blog Post",
"content" : "Here's my blog post.",
"date" : ISODate("2016-12-11T13:43:23.118Z"),
"comments" : [ ]
}
> db.blog.update({title:"My Blog Post"},post)
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.blog.find()
{ "_id" : ObjectId("584d57e5bf1475cad287df45"), "title" : "My Blog Post", "content" : "Here's my blog post.", "date" : ISODate("2016-12-11T13:43:23.118Z"), "comments" : [ ] }
刪除remove()
參數:限制條件
無參數,刪除所有文檔
> db.blog.remove({title:"My Blog Post"})
WriteResult({ "nRemoved" : 1 })
> db.blog.find()