MongoDB | 數據庫簡介

我因為最近學習做 web app 才認識到 MongoDB,然後發現他們官方提供了初學課程,所以順便也學起來了。雖然筆者之前也不熟悉 mySQL 之類的數據庫,但畢竟 VanTopics 以前是使用 WordPress 的,怎麼樣也會接觸到 mySQL ,印象是感覺很老派。遇見 MongoDB 後,筆者才發現原來數據庫不一定是那個樣子的。

MongoDB 簡介

MongoDB 是一個以文件( document )形式搭建的數據庫系統,相比起傳統的關聯式數據庫(典型例子便是 mySQL),MongoDB 拋開了規範的表格形式,讓用戶可以隨時更改數據的模式( schema ),同時也方便用戶增大數據的規模。也因為沒有固有的規範,根據用戶需求,可以用不同的方法把不同的系列(collection)連接起來,讓數據庫的設計變得更靈活自由,比較符合現代 web app 的需求。

在 MongoDB 裡的每個 document 都是用 json 或者 javascript 的符號編寫的,所以對於已經熟悉 javascript 語言的網頁開發者來說,就很容易上手,不用另外去學 SQL 語言。

MongoDB 與網路應用的關係

網路應用( web app )都需要數據庫來支持,無論你的 web app 用的是什麼語言, MongoDB 都可以通過該語言的驅動程式來與 web app 溝通,從而存取數據。

MongoDB 官方支持的語言包括 Java 、.NET 、Node.js 、Python 等,它們都有官方的驅動程式, MongoDB 官網還提供了針對這些語言的初級訓練課程。除了官方支持的語言外,其實 MongoDB 還可以使用別的語言,坊間有不少非官方的驅動程式,提供給不是用以上幾種語言的 web app 使用。

像筆者使用的 Node.js (用 JS 控制的 C++ 程式 ),就可以用 npm 的 MongoDB (也是 C++ 程式 )驅動程式。當我們需要對 MongoDB 進行任何操作的時候,我們可以使用 JS 透過 Mongo Shell 來溝通。

MongoDB 使用的是 JSON Object

JSON Object 必須由一雙一對的 key 和 value 組成的,而所有的 key 都必須是 string,格式就像以下的:

{ key: value }

如果有多對 key 和 value 的話,記得中間要用逗號隔開:

{
key1: value1,
key2: value2,
key3: value3
} 

使用 JSON Object 的好處是 MongoDB 儲存的 value 就可以支持很多種類,如 string、 number、boolean、array、object 等,也可以無限的嵌套多個 array 或者 object。同時,在訪問數據模式方面,可以更自由的設計,可以一次過呈送一個網頁所需的全部數據,或者是用戶需要某些數據的時候才呈送。

不過要注意一點的是 JSON Objects 分辨不了 integer (整數) 和 float (不是整數的)。

MongoDB 的 document 屬於 BSON 格式

MongoDB 把數據都記載在 BSON 的 document 中,BSON 的 document 最大只能到 16MB,這也是 MongoDB 數據庫的其中一個限制。與 MongoDB 溝通的驅動程式在收發數據的時候,也是用 BSON 格式的,收到 BSON document 後,驅動程式就會把 BSON 轉換成服務器使用的語言。

BSON 格式好幾個好處:

  • 可以讓 document 比較輕小,方便快捷的傳送。
  • 可以隨意轉換成其他編程語言
  • 轉換到 BSON,或者從 BSON 轉換到其他語言,所需的時間很短,讓存取數據更有效率
  • 增加支持的數據種類,包括 integer、double、date、binary data 等,這也彌補了 JSON 不足的地方,讓 MongoDB 的 document 可以支持更多的數據種類。

CRUD (Create, Read, Update, Delete)

由於 document 都是先收集成 collection ,然後再儲存到數據庫裡的,在 Mongo Shell 裡面運行指令的時候,都得先說明是哪個數據庫和哪個 collection ,比如我們有一個叫 vantopics 的數據庫和一個叫 posts (文章)的 collection ,在任何指令之前都得先打上:

vantopics.posts

MongoDB 為了方便用戶使用,便設立了一個 db 的 global variable (全局變量),無論我們在使用哪個數據庫, db 都是指當前正在使用的數據庫,所以指令就可以簡化成:

db.posts

Create – 創建 document

db.collection.insertOne();
// 比如
db.posts.insertOne({ “title”: “MongoDB 的用法”, “content”: “以後可能會寫”, “author”: “橘小佑” });

每個 MongoDB 的 document 都必須有自己獨特的 _id (至少在同一個 collection 裡面不能有一樣的 _id),如果創建的時候,沒有自己制定一個 _id 的話, MongoDB 會自動生成一個。指令輸入後, MongoDB 會返回一個 object ,告訴你是否已經成功創建文件和文件的 objectId (也就是 _id )。

Read – 讀取 document

db.collection.find();
// 比如
db.posts.find();
// 如果想要返回的數據比較方便閱讀的話,可以在後面加上 .pretty()
db.posts.find().pretty();

使用以上指令,  MongoDB 就會給你返回在該 collection 裡面的所有 document 。我們也可以跟 MongoDB 說明我們要那些數據,只要在括號裡說明篩選條件, MongoDB 就會返回符合條件的 document 。

// 比如
db.posts.find({ “author”: “橘小佑” });
// 這便會返回所有「橘小佑」所寫的文章數據

另外還有其他小技巧:

db.collection.find().next();
db.collection.find().hasNext();

如果你想一個個 document 閱讀的話,可以在指令後面加上 .next() ,你可以一直重複這個指令直到 collection 裡的 document 被你讀光為止。如果你想看看之後還有沒有 document 可以閱讀的話,可以在指令後面加上 .hasNext() 來查詢, MongoDB 便會給你返回一個 boolean 數值 (true 或者 false)。

Update – 更新 document

db.collection.update();
// 比如
db.posts.update({ “title”: “MongoDB 的用法” }, { “content”: “以後可能會寫,也可能會寫怎麼篩選 document” });

以上指令的第一個 { } 裡,需要輸入篩選條件,就跟我們用 .find() 的時候一樣,可以是多個條件。第二個 { } 裡需要輸入要更改的項目,可以是多個項目。這個指令一次只能更新一個 document ,所通常也會使用 _id 來找那唯一要更新的 document 。

如果要更新多個 document 的話,可以使用以下的指令:

db.collection.updateMany();
// 比如
db.posts.updateMany({ “author”: “橘小佑” }, { $set: { “title”: “所有文章都是同一個 title 了!” } });

要注意的是使用 .updateMany() 的時候,必須加上 $set 才能進行更新的動作。

Delete – 刪除 document

db.collection.deleteOne();
// 比如
db.posts.deleteOne({ “_id”: “4g8g75er5fjoknfr8r56fu” });

以上指令可以用來刪除一個 document ,也是跟用 .find() 的時候一樣,在括號裡輸入篩選條件,通常最保險的做法就是用 _id 來篩選。MongoDB 也提供了刪除的功能:

db.collection.deleteMany();
// 比如
db.posts.deleteMany({ “author”: “橘小佑” });

如非必要,這個指令是很少用得上的。