MongoDB 使用經驗

最初據說 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"
        }
    ]
}

引用 Vs 嵌入

在上面第一個例子中,topic 其實也能夠嵌入 account 中;而第二個例子中,reply 也可使用一個新的集合,而後來引用 topic, 那麼應該如何選擇這兩種關係呢。

咱們主要從幾個出發點來考慮:

  • 查詢

    咱們能夠考慮查詢 account 時,是否須要他全部的 topic, 或者查詢 topic 時,是否須要它全部的 reply.
    從查詢的角度來考慮,若是須要一同得到這兩種數據,那麼就應該嵌入,若是不須要,就應該引用。

  • 數據的增加性

    咱們還能夠考慮 account 的 topic 數量在從此會有怎樣的增加,topic 的 reply 數量會有怎樣的增加。
    若是增加是沒有限度的,那麼就應該引用,若是增加是有限的,那麼就能夠嵌入。

  • 對應關係

    若是是一對一關係,或者一對多關係,那麼能夠考慮嵌入,若是是多對多關係,那麼應該引用。

  • 原子性

    MongoDB 僅在文檔層面提供原子性,若是有兩個很是敏感的數據須要同時被更新,那麼他們有必要存在於同一個文檔中。

查詢和更新

所謂『增刪查改』在 MongoDB 裏對應:

  • find/findOne: 查詢
  • update/save: 修改
  • insert/save: 新增
  • remove: 刪除

在 MongoDB 中,操做符以 $ 開頭,主要分爲三類:查詢操做符,更新操做符,聚合查詢操做符。

  • 查詢操做符

    用於 find 和 update 中的查詢器,如 $gt(大於), $ne(不等於), $in(匹配幾個值之一), 邏輯運算:$and, $not.

  • 更新操做符

    用於 update 中的更新器,如 $inc(對數字進行增量), $set(修改文檔的一部分), $unset(刪除一個字段).
    MongoDB 對嵌入式的文檔和數組有很是好的支持:$addToSet(向集合中添加元素), $push(向數組添加元素), $pull(從數組移除元素).

  • 聚合查詢(Aggregation)

    相似於 SQL 數據庫中的 GROUP, 提供統計和計算的功能,要多強大有多強大,畢竟能夠直接在數據庫中運行 JavaScript 代碼,不過由於性能的關係,不適合在應用中頻繁調用。

查詢命令還有幾個選項:

  • limit: 限制返回的結果數
  • skip: 跳過一些結果
  • sort: 對結果進行排序
  • fields: 只返回指定的字段

副本集(Replica Set)和分片(Sharding)

MongoDB 的副本集採用一主多從的的集羣方式。副本集中只有主節點能夠寫入,其餘節點從主節點同步。當主節點故障時,從節點中會自動推選出一個新的主節點。當故障的節點恢復後,會向其餘節點同步到最新的數據,而後成爲一個從節點。

MongoDB 的分片是指,按照某個字段的值,將數據分爲多份,儲存在不一樣的服務器上。客戶端會運行一個 mongos 代替 mongod, mongos 至關於一個路由,會根據請求和分片的設置,將請求拆分後發給不一樣的服務器,獲得結果後再將結果組合起來發給客戶端。

分片能夠與副本集同時使用,此時,每一個分片都是一個副本級,這樣能夠提供很是高的可用率和擴展性。

http://jysperm.me/technology/1575

相關文章
相關標籤/搜索