動態

詳情 返回 返回

MongoDB必知必會 - 動態 詳情

MongoDB的知識點梳理,內容有chatgpt4.1輔助完成,使用的提示詞(文章大致內容)如下,可按需“食用”😊:
mongodb 定義
關鍵概念
如何增刪改查
如何持久化
如何用go語言操作他
是否支持事務,如果是實現原理,他相對於mysql他存儲數據的底層邏輯是?

1. MongoDB 定義

MongoDB 是一個開源的、面向文檔的 NoSQL 數據庫,以高性能、高可用、易擴展著稱。它用 BSON(一種類 JSON 的二進制格式)存儲數據,適合存儲結構靈活、變化頻繁的數據。


2. 關鍵概念

  • 數據庫(Database):MongoDB 可以有多個數據庫,類似 MySQL 的庫。
  • 集合(Collection):類似 MySQL 的表,但不需要預定義結構(schema-less)。
  • 文檔(Document):集合中的一條數據,類似 MySQL 的一行,但是 JSON/BSON 格式,可以嵌套和靈活擴展。
  • 字段(Field):文檔中的 key-value 對,類似表的列。
  • 主鍵(_id):每個文檔都有唯一的 _id 字段,類似 MySQL 的主鍵。
  • 索引(Index):加速查詢。
  • 副本集(Replica Set):實現高可用的主從複製機制。
  • 分片(Sharding):實現大數據量的分佈式存儲和負載均衡。

3. 如何增刪改查(CRUD)

以 MongoDB Shell 為例:

  • 插入(Insert)

    db.collection.insertOne({name: "Tom", age: 18})
    db.collection.insertMany([{name: "Jerry"}, {name: "Spike"}])
  • 查詢(Find)

    db.collection.find({name: "Tom"})
    db.collection.findOne({_id: ObjectId("...")})
  • 更新(Update)

    db.collection.updateOne({name: "Tom"}, {$set: {age: 20}})
    db.collection.updateMany({age: {$lt: 18}}, {$set: {status: "minor"}})
  • 刪除(Delete)

    db.collection.deleteOne({name: "Tom"})
    db.collection.deleteMany({status: "minor"})

4. 如何持久化

MongoDB 默認將數據持久化到磁盤,數據文件存儲在 dbPath 目錄(如 /data/db)。

  • 寫入時先寫到內存(WiredTiger 緩存),然後定期(或通過 fsync)刷到磁盤。
  • 支持預寫日誌(WiredTiger Journal),保證崩潰恢復。
  • 副本集機制可實現多節點冗餘備份。

5. 如何用 Go 語言操作 MongoDB

使用官方驅動 go.mongodb.org/mongo-driver:

安裝:

go get go.mongodb.org/mongo-driver/mongo

基本用法:

import (
    "context"
    "go.mongodb.org/mongo-driver/mongo"
    "go.mongodb.org/mongo-driver/mongo/options"
    "go.mongodb.org/mongo-driver/bson"
    "time"
)

func main() {
    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()
    client, err := mongo.Connect(ctx, options.Client().ApplyURI("mongodb://localhost:27017"))
    if err != nil { panic(err) }
    collection := client.Database("testdb").Collection("users")

    // 插入
    res, err := collection.InsertOne(ctx, bson.M{"name": "Tom", "age": 18})

    // 查詢
    var result bson.M
    err = collection.FindOne(ctx, bson.M{"name": "Tom"}).Decode(&result)

    // 更新
    _, err = collection.UpdateOne(ctx, bson.M{"name": "Tom"}, bson.M{"$set": bson.M{"age": 20}})

    // 刪除
    _, err = collection.DeleteOne(ctx, bson.M{"name": "Tom"})
}

6. 是否支持事務?實現原理?

支持事務

  • MongoDB 4.0+ 開始支持多文檔事務(類似 MySQL 的事務),但僅限於副本集,4.2+ 支持分片集羣事務。
  • 事務保證原子性、一致性、隔離性、持久性(ACID)

實現原理

  • 事務期間,所有操作先寫入事務日誌,只有 commit 後才真正寫入數據文件。
  • 採用兩階段提交協議(2PC),保證分佈式一致性。
  • 事務期間,相關文檔會加鎖,防止併發寫入衝突。

Go 事務用法示例

sess, err := client.StartSession()
defer sess.EndSession(ctx)
result, err := sess.WithTransaction(ctx, func(sc mongo.SessionContext) (interface{}, error) {
    collection.InsertOne(sc, bson.M{"name": "A"})
    collection.InsertOne(sc, bson.M{"name": "B"})
    return nil, nil
})

7. MongoDB vs MySQL 存儲底層邏輯

MongoDB

  • 面向文檔:每條數據是 BSON 文檔,結構靈活,可以嵌套。
  • 無固定表結構:同一集合的文檔可以有不同字段。
  • WiredTiger 存儲引擎(默認):B+樹索引,數據以塊為單位存儲,支持壓縮。
  • 預寫日誌(Journal):保證崩潰恢復。
  • 副本集/分片:天然支持分佈式和高可用。

MySQL

  • 面向行的關係型數據庫:表結構固定,數據按行存儲。
  • InnoDB 存儲引擎(默認):B+樹索引,數據頁存儲,支持事務、行級鎖。
  • 表結構嚴格:每行數據字段必須一致。
  • 支持外鍵、JOIN:適合複雜關係建模。
  • 分佈式需依賴外部方案(如 MyCat、ShardingSphere)。

總結對比

特性 MongoDB MySQL
數據模型 文檔(BSON/JSON) 行(表結構)
結構 靈活、無 schema 嚴格 schema
存儲引擎 WiredTiger(B+樹+壓縮) InnoDB(B+樹)
事務 4.0+ 支持多文檔事務 天生支持事務
分佈式 原生副本集、分片 需外部中間件
適用場景 大數據量、靈活結構、快速開發 結構化數據、強一致性、複雜查詢

8. 總結

  • MongoDB 是面向文檔的 NoSQL 數據庫,靈活、易擴展,支持事務和分佈式。
  • Go 語言可用官方驅動操作 MongoDB,支持 CRUD 和事務。
  • MongoDB 底層以 BSON 文檔存儲,結構靈活,和 MySQL 的行式存儲、嚴格表結構有本質區別。

Add a new 評論

Some HTML is okay.