1. 程式人生 > >MongoDB基礎之入門

MongoDB基礎之入門

MongoDB基礎之入門

一、MONGODB簡介

MongoDB由C/C++開發,是一種強大、靈活、可擴充套件的資料儲存方式。它擴充套件了關係型資料庫的眾多有用功能,例如:輔助索引、範圍查詢和排序。MongoDB還內建了對MapReduce式聚合的支援,以及對地裡空間索引的支援。

MongoDB容易上手,便於使用。

MongoDB是為快速開發網際網路Web應用而設計的資料庫系統。其資料模型和持久化策略就是為了構建高讀、寫吞吐量和高自動災備伸縮性的系統。無論系統需要單個還是多個節點,MongoDB都可以提供高效能。

1、歷史

2007年由10gen的創業團隊開發,最終形成了MongoDB專案,10gen公司也更名為MongoDB,Inc。

MongoDB的設計目標就是極簡、靈活、作為Web應用棧的一部分。

MongoDB1.0釋出於2009年11月。

2、MONGODB的特點

MongoDB有以下幾個特點:

  • 1.高效能。
  • 2.豐富的查詢語言。
  • 3.高可用。
  • 4.水平可伸縮。
  • 5.支援多個儲存引擎。

二、MONGODB入門

1、BSON文件

MongoDB將資料記錄儲存為BSON文件,BSON文件是JSON文件的二進位制表示,但它包含的資料型別多於JSON。

BSON文件是MongoDB中資料的基本單元,非常類似於關係型資料庫管理系統中的行。同時也是MongoDB的核心概念。

多個鍵及其關聯的值有序的放置在一起便是文件。每種程式語言表示文件的方法不太一樣。

1.BSON文件的特點

  • 1.文件中的鍵值對是有序的。通常文件中鍵的順序並不重要。
  • 2.文件中的值可以是MongoDB中包含的所有資料型別。

2.BSON文件鍵的命名規則

BSON文件的鍵有以下幾條命名規則:

  • 1.文件的鍵是字串。
  • 2.鍵中不能含有\0(空字元),這個字元用來表示鍵的結尾。
  • 3.點(.)和$有特殊含義,只能在特定的環境下才能使用。
  • 4.以下劃線(_)開頭的鍵是保留鍵,沒有做強制規定。
  • 5.鍵區分大小寫。一個文件中不能存在重複的鍵。

3.檔案限制

最大的BSON文件大小為16M。過大的文件,MongoDB提供了GridFS進行儲存。

MongoDB在寫操作之後保留文件欄位的順序,_id欄位始終是文件中的第一個欄位。更改欄位名稱可能會導致文件中欄位的順序重新排序。

2.6版本開始MongoDB主動保留文件中的欄位順序,2.6之前MongoDB沒有主動保留文件中欄位的順序。

4._id

在MongoDB中,儲存在集合中的每個文件都需要一個唯一的_id欄位作為主鍵。如果插入的文件省略了該_id欄位,MongoDB驅動程式會自動為該欄位生成ObjectId型別作為其值。

_id欄位具有以下功能:

  • 1.預設情況下,MongoDB在建立集合期間會使用_id為集合建立唯一索引。
  • 2._id欄位始終是文件中的第一個欄位。如果伺服器收到的文件_id欄位不在第一位,則伺服器會將該欄位移動到開頭。
  • 3._id欄位可以包含除陣列之外的任何BSON資料型別的值。(不要儲存BSON正則表示式型別。)

_id常用的資料型別:

  • 1.使用ObjectId。
  • 2.使用自然唯一識別符號。可以節省空間並避免額外的索引。
  • 3.自動遞增的數字。
  • 4.在應用程式程式碼中生成UUID。為了更有效地儲存集合和_id 索引中的UUID值,請將UUID儲存為BSON BinData型別的值。
  • 5.使用驅動程式的BSON UUID工具生成UUID。請注意,驅動程式可能以不同方式實現UUID序列化和反序列化邏輯,可能會與其他驅動程式不完全相容。

2、集合

集合就是一組文件的合集。集合類似於關係型資料庫中的表。

1.無模式

集合是無模式的,也就是說一個集合裡面的文件可以是各式各樣的。MongoDB對此沒有做強制要求,讓開發者更靈活。

沒有模式的控制,那麼設計文件以及集合,就成為一個重點。

我們應該將同類型的文件放在一個集合中,這樣可以使資料更加集中,方便管理,同時方便建立索引。

MongoDB3.2版本開始加入了更新和插入操作期間強制執行集合的文件驗證規則。

2.集合命名

集合的命名有以下幾點要求:

  • 1.集合名稱應以下劃線或字母字元開頭。
  • 2.集合名不能是空字串。
  • 3.集合名中不能包含空字元,這個字元表示集合名的結尾。
  • 4.集合名不能以“system.”開頭,這是為系統集合保留的字首。
  • 5.使用者建立的集合名字不能包含$符號。

如果建立的集合中包含特殊字元,例如下劃線、數字開頭,那麼要訪問這個集合,要使用db.getCollection()方法。

集合名稱空間的最大長度為120個位元組。集合名稱空間包含:資料庫名稱、點(.)分隔符和集合名稱。

3.唯一識別符號

MongoDB3.6中增加了一個新功能,在featureCompatibilityVersion設定為3.6,可以為每個集合分配一個不可變的UUID,這個UUID在副本集的所有成員和分片叢集張總的分片中保持一致。

4.系統集合

MongoDB內部對集合的使用方式可以體現它的部分設計思想。

system.namespaces與system.indexes就屬於系統集合。這兩個都是標準的集合,但是MongoDB使用固定集合來做複製。

(1)system.namespaces

可以查詢到當前資料庫中定義的所有名稱空間。

(2)system.indexes

儲存了當前資料庫的所有索引定義。

5.子集合

組織集合的一種慣例是使用點(.)字元分開的按名稱空間劃分的子集合。

3、資料庫

MongoDB中多個文件組成集合,同樣多個集合可以組成資料庫。一個MongoDB例項可以承載多個數據庫,它們之間可視為完全獨立的。每個資料庫都有獨立的許可權控制,在磁碟上,不同的資料庫會放置在不同的檔案中。

把資料庫的名字放到集合名前面,得到的就是集合的完全限定名,稱為名稱空間。

名稱空間的長度不得超過121位元組,在實際使用當中應該小於100位元組。

1.資料庫命名

資料庫命名分兩種情況,一種是Windows系統下,一種是Linux系統下。

MongoDB中的資料庫名稱不區分大小寫,且長度要少於64個字元。

Windows系統下:

  • 不能包含斜槓(/)、反斜槓(\)、點(.)、空格、雙引號(")、美元符號($)、星號(*)、左尖括號(<)、右尖括號(>)、冒號(:)、豎槓(|)、問號(?)、空字元。

類Unix系統下:

  • 不能是空字串、空格、點(.)、斜槓(/)、反斜槓(\)和空字元(\0)。

注意:資料庫名最終會變成檔案系統裡的檔名,這也就是有這些限制的原因。

2.系統中保留的資料庫

有一些資料庫是保留的,可以直接訪問這些有特殊作用的資料庫。

(1)admin

此資料庫是許可權資料庫,也就是root資料庫,將一個使用者新增到這個資料庫,那麼這個使用者自動繼承所有資料庫的許可權。一些特定的伺服器端命令也只能從這個資料庫執行,比如列出所有的資料庫或者關閉伺服器。

(2)local

這個資料庫永遠不會被複制,可以用來儲存限於本地單臺伺服器的任意集合。

(3)config

當MongoDB用於分片設定時,config資料庫在內部內部會使用,用於儲存分片的相關資訊。

4、安裝

在選擇版本的時候要注意:

MongoDB的穩定版本用偶數次版本號來標記,例如:1.8、2.0和2.2這些是版本是穩定版本;1.9和2.1是開發版本,不應該在生產環境中使用。

1.在Windows上安裝MongoDB

參見部落格:Windows下安裝MongoDB

2.在Linux上安裝MongoDB

(1)下載安裝

官方下載地址:https://www.mongodb.com/download-center/community

可以使用瀏覽器或者curl工具下載安裝包:

curl https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-3.6.12.tgz mongo.tgz
tar –zxvf mongo.tgz

建立資料目錄並授權:

mkdir –p /data/db/
chow `id –u` /data/db
(2)啟動服務
/mongodbHome/bin/mongod

MongoDB預設使用27017埠,如果這個埠被佔用,那麼可以使用如下命令更改埠:

mongod --port 27018

注意命令中間是兩個橫槓。

(3)啟動命令選項
<1> --dbpath

指向存放資料檔案的目錄路徑,預設是/data/db。每個mongod程序都需要獨立的資料目錄。

當mongod啟動時,會在資料目錄中建立mongod.lock檔案,這個檔案用於防止其他mongod進行使用該資料目錄。如果使用同一個資料目錄啟動另一個MongoDB伺服器,這會報錯:

“Unable to acquire lock for lockfilepath:/data/db/mongod.lock.”
<2> --logpath

指向日誌輸出檔案的路徑。日誌預設會輸出在標準輸出(stdout)裡。

如果對資料夾有寫許可權的話,系統會在檔案不存在時建立它。它會將已有檔案覆蓋掉,清除所有原來的日誌記錄。如果想要保留原來的日誌,還需要使用--logappend選項。

<3> --logappend

將日誌輸出到日誌檔案中的模式,其值有true,表示追加輸出,false表示覆蓋輸出,即每次都會將原有的日誌檔案刪除,重新建立日誌檔案。

<4> --port

指定MongoDB監聽埠,預設使用27017。

如果要執行多個mongod程序,則需要給每個程序指定不同的埠號,如果啟動mongod時埠被佔用,則報錯:

“Address already in use for socket” 0.0.0.0:27017”
<5> --rest

該標誌將開啟簡單REST介面,增強伺服器的預設Web控制檯。Web控制檯的預設埠號為mongodprot+1000,MongoDB使用了27017,那麼Web控制檯的埠則為28017。可以使用 http://localhost:28017 來獲取資料庫的管理資訊。

(此項功能,本人暫時沒有測試出來!)

<6> --nohttpinterface

關閉管理介面,和rest是相反選項。

<7> --fork

讓程序以守護程序方式執行。

<8> --config

指定啟動要使用的配置檔案,載入命令列未指定的額各種選項。

<9> --auth

開啟安全檢查。開啟之後,需要做安全相應的安全驗證,才能對資料庫進行操作。

<10> --bindip

指定mongod繫結的IP地址。

<11> --noscripting

禁止服務端執行JavaScript程式碼。

(4)配置檔案

以上配置資訊也可以在配置檔案中全部指定,建立一個新的文字檔案:mongodb.conf,內容如下:

dbpath=/var/local/mongodb
logpath=/var/log/mongodb.log
port=27017
rest=true
fork=true

在啟動mongod時,通過以下命令來使用配置檔案:

mongod –f mongodb.conf

檢視啟動選項列表:

use admin
db.runCommand({getCmdLineOpts:1})

注意:

  • mongod在沒有引數的情況下或使用預設資料目錄/data/db,並使用27017埠,如果資料目錄不存在或者不可寫,服務會啟動失敗。所以在啟動服務之前一定要建立資料目錄並確保對該目錄有寫許可權。如果埠被佔用啟動也會失敗。
(5)停止服務

停止MongoDB服務有兩種方式:

  • 其一:檢視mongod的程序號,使用kill -2 port或者kill prot。mongod收到SINGINT或者SIGTERM時,會穩妥退出。
  • 其二:使用shutdown命令停止服務,這是管理命令,需要在admin資料庫下使用,shell提供了輔助函式,簡化了這一過程:
db.sutdownServer()

當mongod收到這兩種操作的的指令時,會等到資料庫當前執行的操作或者檔案預分配完成,關閉所有開啟的連線,將快取的資料重新整理到磁碟,最後才會停止服務。

注意:千萬不要使用kill -9來強制關閉資料庫,這樣上述的穩妥關閉過程就不存在了,會導致資料丟失。

5、MongoDB Shell

MongoDB Shell是一個基於JavaScript的工具,用於管理資料庫和操作資料。

可執行檔案mongo會載入Shell並連線到指定的mongod程序。MongoDB Shell的功能和MySQL Shell差不多,主要區別在於不使用SQL,大多數命令使用的是JavaScript表示式。

MongoDB JavaScript Shell能讓你玩轉資料,對文件、集合以及MongoDB的特殊查詢語言有切實的體驗。

1.執行Shell

啟動Shell的命令如下:

mongo

shell會在啟動時自動連線MongoDB伺服器,所以在shell啟動之前要保證mongod已經啟動。如果啟動時沒有指定其他資料庫,Shell會選擇則名為test的預設資料庫。

shell是一個功能完備的JavaScript直譯器,可以執行任何JavaScript程式。也可以呼叫JavaScript的標準庫,還可以定義和呼叫JavaScript函式。

例如:

#進行數學運算
>x = 200
200
>x / 5;
40
#呼叫標準庫函式
>Math.sin(Math.PI / 2);
1
>new Date(“2019/8/21”);
ISODate("2019-08-20T16:00:00Z")
# 定義並呼叫函式
> function factorial (n) {
... if(n<=1) return 1;
... return n* factorial(n-1);
... }
> factorial(5);
120

注意:shell中可以使用多行命令,它會檢測輸入的JavaScript語句是否寫完。

2.MongoDB客戶端

shell其實是一個獨立的MongoDB客戶端,開啟的時候shell會連線到MongoDB伺服器的test資料庫,並將這個資料庫了連結賦值給全域性變數db,這個變數是通過shell訪問MongoDB的主要入口點。

shell為了方便習慣於SQL shell的使用者添加了一些語法糖,如下:

使用use命令切換或建立資料庫。

use tutorial

在MongoDB中建立資料庫並不是必須的操作,資料庫與集合只有在第一次插入文件時才會被建立。這個行為與MongoDB對資料的動態處理方式是一致的;因為不用事先定義文件的結構,單獨的集合和資料庫可以在執行時被建立。

db變數此時就等於tutorial:

>db
tutorial

3.shell中的基本操作

在shell中操作資料會用到4個基本操作:建立、讀取、更新和刪除(CRUD)。

(1)建立

MongoDB對文件的操作格式如下:

db.collcetion.method(操作符)

MongoDB中集合中儲存的都是文件,文件需要使用JSON來表示,如下:

{username:”jones”}

該文件包含一個鍵值對,那麼下面我們將它儲存到users集合中:

>db.users.insert({username:”jones”})
#檢視資料
> db.users.find()
{ "_id" : ObjectId("5ce51398177285a95d705d4f"), "username" : "jones" }

因為這是儲存的第一個文件,所以insert()方法不僅儲存了文件,而且還建立了users集合以及tutorial庫,同時還給此文件添加了一個額外的鍵“_id”。這個欄位可以認為是文件的主鍵。每個MongoDB文件都要求有一個_id,如果文件在建立時沒有提供此欄位,那麼就會生成一個MongoDB物件ID並新增到文件裡。這個欄位全域性唯一。

(2)讀取

檢視資料的方法是find(),如下:

> db.users.find()
{ "_id" : ObjectId("5ce51398177285a95d705d4f"), "username" : "jones" }
{ "_id" : ObjectId("5ce51477177285a95d705d50"), "username" : "smith", "country" : "Canada" }

find()方法會返回集合中所有的文件,findOne()方法只會返回一條文件:

> db.users.findOne();
{ "_id" : ObjectId("5ce51398177285a95d705d4f"), "username" : "jones" }

在使用find()方法時,shell自動顯示最多20個匹配的文件。

(3)更新

所有更新文件的操作都要求至少有兩個引數:第一個引數指明要更新的文件;第二個引數定義被選中的文件應該如何更新。

MongoDB中支援針對性更新(targeted modification),這是MongoDB獨有特性中最具代表性的。這種更新操作預設只會更新一個文件。

例如:

#建立一個變數
> king = {username:"LongKing",
... age:21,
... gender:"man"}
{ "username" : "LongKing", "age" : 21, "gender" : "man" }
#將變數插入到集合中
> db.users.insert(king);
WriteResult({ "nInserted" : 1 })
#更改變數
> king.address = []
[ ]
#更新文件
> db.users.update({username:"LongKing"},king)
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.users.find();
{ "_id" : ObjectId("5ce51398177285a95d705d4f"), "username" : "jones" }
{ "_id" : ObjectId("5d5cb4bcbff45893172e233e"), "username" : "LongKing", "age" :
 21, "gender" : "man", "address" : [ ] }
# 還可以進行如下的更新操作
> jones = db.users.findOne();
{ "_id" : ObjectId("5ce51398177285a95d705d4f"), "username" : "jones" }
> jones
{ "_id" : ObjectId("5ce51398177285a95d705d4f"), "username" : "jones" }
> jones.age = 18;
18
> jones
{
        "_id" : ObjectId("5ce51398177285a95d705d4f"),
        "username" : "jones",
        "age" : 18
}
> db.users.update({username:"jones"},jones);
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.users.find();
{ "_id" : ObjectId("5ce51398177285a95d705d4f"), "username" : "jones", "age" : 18 }
(4)刪除

remove()方法用來從資料庫中永久性地刪除文件。該方法接受一個可選的查詢選擇器,只刪除那些匹配選擇器的文件。如果沒有提供選擇器,就刪除集合中的所有文件。

例如:

db.users.remove({username:”jones”}) #刪除名為jones的文件
db.users.remove() #清空集合

remove()方法此操作不會刪除集合,它只是從集合中刪除文件,哪怕是清空操作,也會保留集合。

4.shell幫助

shell本身內建了幫助文件,可以通過help命令檢視。

> help
        db.help()                    help on db methods
        db.mycoll.help()             help on collection methods
        sh.help()                    sharding helpers
        rs.help()                    replica set helpers
        help admin                   administrative help
        help connect                 connecting to a db help
        help keys                    key shortcuts
        help misc                    misc things to know
        help mr                      mapreduce

        show dbs                     show database names
        show collections             show collections in current database
        show users                   show users in current database
        show profile                 show most recent system.profile entries with time >= 1ms
        show logs                    show the accessible logger names
        show log [name]              prints out the last segment of log in memory, 'global' is default
        use <db_name>                set current database
        db.foo.find()                list objects in collection foo
        db.foo.find( { a : 1 } )     list objects in foo where a == 1
        it                           result of the last line evaluated; use to further iterate
        DBQuery.shellBatchSize = x   set default number of items to display on shell
        exit                         quit the mongo shell
>

使用db.help()可以檢視資料庫級別的命令幫助。

集合的相關幫助通過db.collectionName.help()來檢視。

想要了解函式的功能,在輸入的時候不要帶括號,那樣就會顯示函式的JavaScript原始碼。

例如:

db.users.update

5.shell中的注意事項

使用db.集合名的方式來訪問集合一般不會有文件,但如果集合名恰好是資料庫類的一個屬性就有問題了。

例如:要訪問version這個集合,使用db.version就不行了,因為db.version是個資料庫函式。

當JavaScript只有在db中找不到指定的屬性時,才會將其作為集合返回,當有屬性與目標集合同名時,可以使用getCollection()函式:

>db.getCollection(“version”);
test.version

所以在設計集合名時,要注意規避這些問題。

上一篇:Windows下安裝MongoDB