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 的行式存儲、嚴格表結構有本質區別。