最初據說 MongoDB 的時候,我老是以爲它的穩定性堪憂,後來用了差很少一年的時間,其實也沒有遇到過什麼問題,反而是 MySQL 出現過幾回丟失數據的狀況。配合 Node.js 使用 MongoDB 是一件很是舒暢的事情,從前端,到後端,再到數據庫,通通全是 JSON.前端
本文的定位是一篇對 MongoDB 的一個概覽性的介紹,告訴你 MongoDB 的特色和功能,以及若是須要了解某個功能,應當搜索什麼關鍵詞,並不直接涉及技術細節。數據庫
無模式編程
MongoDB 中的每一條文檔,都是一個 JSON 對象,所以你無需預約義一個集合的結構,集合中的每一個文檔也能夠有不一樣的結構。後端
異步寫入數組
MongoDB 默認全部的寫操做都是『不安全』的,即當請求被 MongoDB 收到時,不等寫入操做完成,就返回一個『成功』的響應。
這是默認的行爲,固然你設置一些選項,讓操做等待等待寫入完成後再返回響應。不過對於大多數應用,這種『不安全』已經足夠安全了。安全
簡單查詢服務器
MongoDB 只支持簡單的查詢,MongoDB 只儲存數據,更多的邏輯應該在應用中解決。所以 MongoDB 有着簡單的且在各編程語言下高度一致的 API 接口。運維
無需運維異步
MongoDB 幾乎沒有什麼選項能夠設置,集羣也是設置一次以後就能夠自動地解決故障,極少須要維護。編程語言
MongoDB 的安裝很簡單,直接在官網下載二進制版本,運行其中的 mongod 便可啓動數據庫,運行 mongo 便可啓動客戶端 Shell, 或者你也能夠從軟件源中安裝。
MongoDB 被設計運行於 64bit 的操做系統,在 32bit 的狀況下,數據文件最大限制爲 2GiB.
MongoDB 在運行時並不會實時地將修改寫入磁盤,所以在關閉服務器時須要給 MongoDB 時間將全部數據寫入磁盤。當出現服務器忽然掉電的狀況時,MongoDB 的數據庫文件會損壞,須要進行修復才能從新運行,這個過程當中會丟失掉電時正在進行的寫入操做。在對運行中的 MongoDB 進行備份時,須要使用自帶的 mongodump 工具,不能直接複製其數據庫文件。
ObjectID
MongoDB 會爲每個文檔默認添加一個名爲 _id, 類型爲 Object 的字段,這個字段用來惟一地標識每個文檔。這個 ID 經過時間,服務器,進程號被生成,甚至能夠認爲是全世界惟一的。
除了 MongoDB 默認爲 _id 添加 ObjectID, 你也能夠本身在文檔中建立 ObjectID, 來起到惟一地標識某個對象的功能。
例如咱們有一個 topic 集合,topic 都是 account 建立的,因此 topics 中要引用來自 accounts 中的 account.
// accounts { _id: <ObjectID 1>, name: "jysperm" } // topics { _id: <ObjectID 2>, account_id: <ObjectID 1> }
每一個 topic 會有一些 reply, 因此在 topic 中能夠嵌入 reply.
// topics { _id: <ObjectID 2>, account_id: <ObjectID 1> replies: [ { _id: <ObjectID 3>, content: "xxoo" } ] }
在上面第一個例子中,topic 其實也能夠嵌入 account 中;而第二個例子中,reply 也可使用一個新的集合,而後來引用 topic, 那麼應該如何選擇這兩種關係呢。
咱們主要從幾個出發點來考慮:
查詢
咱們能夠考慮查詢 account 時,是否須要他全部的 topic, 或者查詢 topic 時,是否須要它全部的 reply.
從查詢的角度來考慮,若是須要一同得到這兩種數據,那麼就應該嵌入,若是不須要,就應該引用。
數據的增加性
咱們還能夠考慮 account 的 topic 數量在從此會有怎樣的增加,topic 的 reply 數量會有怎樣的增加。
若是增加是沒有限度的,那麼就應該引用,若是增加是有限的,那麼就能夠嵌入。
對應關係
若是是一對一關係,或者一對多關係,那麼能夠考慮嵌入,若是是多對多關係,那麼應該引用。
原子性
MongoDB 僅在文檔層面提供原子性,若是有兩個很是敏感的數據須要同時被更新,那麼他們有必要存在於同一個文檔中。
所謂『增刪查改』在 MongoDB 裏對應:
在 MongoDB 中,操做符以 $
開頭,主要分爲三類:查詢操做符,更新操做符,聚合查詢操做符。
查詢操做符
用於 find 和 update 中的查詢器,如 $gt(大於), $ne(不等於), $in(匹配幾個值之一), 邏輯運算:$and, $not.
更新操做符
用於 update 中的更新器,如 $inc(對數字進行增量), $set(修改文檔的一部分), $unset(刪除一個字段).
MongoDB 對嵌入式的文檔和數組有很是好的支持:$addToSet(向集合中添加元素), $push(向數組添加元素), $pull(從數組移除元素).
聚合查詢(Aggregation)
相似於 SQL 數據庫中的 GROUP, 提供統計和計算的功能,要多強大有多強大,畢竟能夠直接在數據庫中運行 JavaScript 代碼,不過由於性能的關係,不適合在應用中頻繁調用。
查詢命令還有幾個選項:
MongoDB 的副本集採用一主多從的的集羣方式。副本集中只有主節點能夠寫入,其餘節點從主節點同步。當主節點故障時,從節點中會自動推選出一個新的主節點。當故障的節點恢復後,會向其餘節點同步到最新的數據,而後成爲一個從節點。
MongoDB 的分片是指,按照某個字段的值,將數據分爲多份,儲存在不一樣的服務器上。客戶端會運行一個 mongos 代替 mongod, mongos 至關於一個路由,會根據請求和分片的設置,將請求拆分後發給不一樣的服務器,獲得結果後再將結果組合起來發給客戶端。
分片能夠與副本集同時使用,此時,每一個分片都是一個副本級,這樣能夠提供很是高的可用率和擴展性。