01 MongoDB 介紹

← 回到 MongoDB 資料建模設計 | 下一篇 → 02 關聯模型 Linking Models

MongoDB 是什麼

  • 現代的 document-model 資料庫(Modern Document-model database)。
  • 設計目標是支撐現代商業應用:
    • Developer and Operations oriented:對開發與維運友善。
    • Easy to scale horizontally:容易水平擴展。
    • Business Critical:可承載關鍵業務。
    • Lessons learned from 50 years of RDBMS:吸收了關聯式資料庫 50 年的經驗教訓。

投影片留的思考題:哪兩個 RDBMS 功能在分散式系統裡很難有效率地做到? 答案就是講師接著講的兩大痛點(見下)。

為什麼需要 MongoDB —— 分散式下的兩大痛點

講師解釋 MongoDB 主要解決關聯式資料庫在分散式環境下難做的兩件事:

  1. 關聯(Join / Link)

    • 關聯式資料庫的關聯設計在資料量大、需要切分(sharding)時,效能會受影響——因為關聯的資料可能分散在不同的 server / partition 上,跨節點關聯很慢。
    • MongoDB 用 document 把相關資料放在一起,很大程度避免了跨節點關聯。這是它花最大力氣解決的問題之一。
  2. 交易 / 事務(Transaction,ACID)

    • 傳統關聯式資料庫用多張表拆解一筆業務,一個增刪操作可能牽動多張表,天然需要跨表 ACID 事務。
    • MongoDB 傾向把「一個業務單位」放進同一個 document,靠 document 內部原本就完整的 ACID 特性,減少對跨 document 事務的依賴。
    • 講師的設計建議:設計 schema 時盡可能考量「同一個聚合單位裡的資料一起使用」,因為事務的開啟與提交會影響效能。

對應投影片 §Modern Document-model database 與講師關於「1️⃣ Join 2️⃣ Transaction」的展開。

從關聯式到 document 的演進(Employee 範例)

投影片用同一筆員工資料,展示三種資料模型的演進:

  • Relational Data Model(投影片 p.5):員工、福利計畫、Title、Department 等拆成多張表,用 FK(EmpFK / PlanFK / BenFK…)關聯。
  • Relational - Denormalization(p.6):把部分關聯資料攤平(denormalize)進來,減少 join。
  • Document Model - Arrays(p.7):MongoDB 用陣列把一個員工的多個 benefits 直接放進同一列/同一個 document。

同一筆資料在 MongoDB 的兩種表示:

  • JSON 表示(p.8)——這是我們平常看到的、可讀的樣子:

    {
      "_id" : 9950,
      "pay_band": "C",
      "employee_name": "Dunham, Justin",
      "department" : "Marketing",
      "title" : "Product Manager, Web",
      "report_up": "Neray, Graham",
      "benefits" : [
        { "type" : "Health", "plan" : "PPO Plus" },
        { "type" : "Dental", "plan" : "Standard" }
      ]
    }
  • BSON 儲存(p.9)——MongoDB 底層實際存的是 BSON(Binary JSON)。JSON 是給人看的表示,真正落地是二進位格式(含型別標記與長度)。

術語對照:RDBMS ↔ MongoDB(p.10)

RDBMSMongoDB
DatabaseDatabase
TableCollection
RowDocument
ColumnField
IndexIndex
  • 一份 Document = 一個 JSON/BSON 物件:key 是 field,value 可以是各種型別(含巢狀物件、陣列)。
  • Collection = 關聯式的 Table,但因為是 document 型資料庫,同一個 collection 裡可以裝多個結構不完全一樣的 document。
  • Namespace(命名空間)database.collection 的組合,是集合的唯一識別。
    • 講師補充:查看官方文件時常看到欄位或名字叫 NS,就是 namespace 的縮寫。
    • 一個 database 裡不能有兩個同名 collection;DB2 與另一個 DB2 若指不同 database,其 collection 名稱各自唯一。database + collection 兩者加在一起才唯一確定一個 collection。

_id 與主鍵

  • 每個 collection 的 document 都有 _id,是唯一、固定不變的主鍵。
  • 若插入時沒指定 _id,MongoDB 會自動產生一個 ObjectId 當作 _id。也可以自己指定 _id 的值。
  • 延伸:只有 _id 這個下劃線欄位會自動建立唯一索引;其他欄位不會自動索引(見 05 索引與優化 的 index 迷思)。

多語言支援(p.11)

MongoDB 官方 driver 支援主流語言:Java、Python、Node、C#、C、C++、Rust、Go、Kotlin、PHP、Ruby、Scala 等約 20 種。

  • 選型時要看該語言的 driver 成熟度與活躍度、以及社群的維護情況。
  • 可以依團隊自己的開發語言需求來選 driver。

小結

MongoDB 是為現代應用、分散式場景而生的 document 資料庫,用「把相關資料放在一起」的 document 模型,緩解了 RDBMS 在分散式下難處理的 JoinTransaction 兩大痛點。理解術語對照(Collection/Document/Field/Namespace)是後面所有設計討論的基礎。

→ 接著看關聯怎麼在 MongoDB 表達:02 關聯模型 Linking Models