㈠ 如何正確的使用MongoDB並優化其性能
資料庫性能對軟體整體性能的影響是不言而喻的,那麼,當我們使用MongoDB時改如何提高資料庫性能呢?
1.範式化與反範式化
在項目設計階段,明確集合的用途是對性能調優非常重要的一步。
從性能優化的角度來看,集合的設計我們需要考慮的是集合中數據的常用操作,例如我們需要設計一個日誌(log)集合,日誌的查看頻率不高,但寫入頻率卻很高,那麼我們就可以得到這個集合中常用的操作是更新(增刪改)。如果我們要保存的是城市列表呢?顯而易見,這個集合是一個查看頻率很高,但寫入頻率很低的集合,那麼常用的操作就是查詢。
對於頻繁更新和頻繁查詢的集合,我們最需要關注的重點是他們的範式化程度,在上篇範式化與反範式化的介紹中我們了解到,範式化與反範式化的合理運用對於性能的提高至關重要。然而這種設計的使用非常靈活,假設現在我們需要存儲一篇圖書及其作者,在MongoDB中的關聯就可以體現為以下幾種形式:
1.完全分離(範式化設計)
示例1:
View Code
{
"_id" : ObjectId("5124b5d86041c7dca81917"),
"title" : "如何使用MongoDB",
"author" : [
ObjectId("144b5d83041c7dca84416"),
ObjectId("144b5d83041c7dca84418"),
ObjectId("144b5d83041c7dca84420"),
]
}
我們將作者(comment) 的id數組作為一個欄位添加到了圖書中去。這樣的設計方式是在非關系型資料庫中常用的,也就是我們所說的範式化設計。在MongoDB中我們將與主鍵沒有直接關系的圖書單獨提取到另一個集合,用存儲主鍵的方式進行關聯查詢。當我們要查詢文章和評論時需要先查詢到所需的文章,再從文章中獲取評論id,最後用獲得的完整的文章及其評論。在這種情況下查詢性能顯然是不理想的。但當某位作者的信息需要修改時,範式化的維護優勢就凸顯出來了,我們無需考慮此作者關聯的圖書,直接進行修改此作者的欄位即可。
2.完全內嵌(反範式化設計)
示例2:
View Code
{
"_id" : ObjectId("5124b5d86041c7dca81917"),
"title" : "如何使用MongoDB",
"author" : [
{
"name" : "丁磊"
"age" : 40,
"nationality" : "china",
},
{
"name" : "馬雲"
"age" : 49,
"nationality" : "china",
},
{
"name" : "張召忠"
"age" : 59,
"nationality" : "china",
},
]
}
在這個示例中我們將作者的欄位完全嵌入到了圖書中去,在查詢的時候直接查詢圖書即可獲得所對應作者的全部信息,但因一個作者可能有多本著作,當修改某位作者的信息時時,我們需要遍歷所有圖書以找到該作者,將其修改。
3.部分內嵌(折中方案)
示例3:
View Code
{
"_id" : ObjectId("5124b5d86041c7dca81917"),
"title" : "如何使用MongoDB",
"author" : [
{
"_id" : ObjectId("144b5d83041c7dca84416"),
"name" : "丁磊"
},
{
"_id" : ObjectId("144b5d83041c7dca84418"),
"name" : "馬雲"
},
{
"_id" : ObjectId("144b5d83041c7dca84420"),
"name" : "張召忠"
},
]
}
這次我們將作者欄位中的最常用的一部分提取出來。當我們只需要獲得圖書和作者名時,無需再次進入作者集合進行查詢,僅在圖書集合查詢即可獲得。
這種方式是一種相對折中的方式,既保證了查詢效率,也保證的更新效率。但這樣的方式顯然要比前兩種較難以掌握,難點在於需要與實際業務進行結合來尋找合適的提取欄位。如同示例3所述,名字顯然不是一個經常修改的欄位,這樣的欄位如果提取出來是沒問題的,但如果提取出來的欄位是一個經常修改的欄位(比如age)的話,我們依舊在更新這個欄位時需要大范圍的尋找並依此進行更新。
在上面三個示例中,第一個示例的更新效率是最高的,但查詢效率是最低的,而第二個示例的查詢效率最高,但更新效率最低。所以在實際的工作中我們需要根據自己實際的需要來設計表中的欄位,以獲得最高的效率。
㈡ mongodb 索引是什麼數據結構
MongoDB索引使用B-tree數據結構。
索引支持MongoDB中查詢的高效執行。如果沒有索引,MongoDB必須執行集合掃描,即掃描集合中的每個文檔,以選擇與查詢語句匹配的文檔。如果查詢存在適當的索引,MongoDB可以使用索引來限制它必須檢查的文檔數。
(2)mongodb關鍵詞過濾擴展閱讀
MongoDB索引的類型
1、單欄位索引(Single Field Index)
這個是最簡單最常用的索引類型,比如我們上邊的例子,為id建立一個單獨的索引就是此種類型。
2、復合索引(Compound Index)
索引field的先後順序很關鍵,影響有兩方面:
(1)MongoDB在復合索引中是根據prefix排序查詢,就是說排在前面的可以單獨使用。
(2)過濾出的document越少的field越應該放在前面,比如此例中id如果是唯一的,那麼就應該放在最前面,因為這樣通過id就可以鎖定唯一一個文檔。而如果通過city或者score過濾完成後還是會有大量文檔,這就會影響最終的性能。
索引的排序順序不同:復合索引最末尾的field,其排序順序不同對於MongoDB的查詢排序操作是有影響的。
3、多key索引(Multikey Index):主要針對數據類型為數組的類型。
4、其它類型索引:另外,MongoDB中還有其它如哈希索引,地理位置索引以及文本索引,主要用於一些特定場景。
㈢ MongoDB問題,下載完配置好服務可以連接但就是無法進入資料庫似乎缺少什麼東西但不知道怎麼解決
@MongoDB安裝後的一些簡要配置:
1)在和bin目錄同級的目錄下面建一個data文件夾,data文件夾下面分別建立db和log文件夾來存儲數據文件和日誌文件【ps:也可以建立其他文件夾,自己知道在什麼地方即可】
2)在和bin目錄同級的目錄下面建一個mongo.config文件(編碼格式為utf8無bom格式,否則會報錯),作為mongodb的配置文件。[ps:在啟動的時候會用到]
---mongo.config文件內容如下:
##數據文件
dbpath=D:\mongodb\data\db
##日誌文件
logpath=D:\mongodb\data\log\mongo.log
#錯誤日誌採用追加模式,配置這個選項後mongodb的日誌會追加到現有的日誌文件,而不是從新創建一個新文件
logappend=true
#啟用日誌文件,默認啟用
journal=true
#這個選項可以過濾掉一些無用的日誌信息,若需要調試使用請設置為false
㈣ PHP操作MongoDB,怎麼把一個集合轉為數組
簡單的格式匹配用腳本或者批處理就行了。
linux shell可以很容易的過濾出你想要的關鍵字,windows下的DOS批處理應該也可以。
㈤ mongoDB聚合查詢中$unwind為什麼拆分的不徹底
mongodb中使用aggregate可以返回數組欄位數組的指定索引的元素參考語句: {$match:{'id':15}}, {$project:{id:1,"default":1}}, {$unwind:"$default.styles"}, {$match:{'default.styles.status':1}}, {$group:{_id:"$_id","defaults":{$push:"$default.styles"}}} 解釋: 1:過濾數據{$match:{'id':15}} 2:獲取想要的列{$project:{id:1,"default":1}} 3:獲取展開後數組欄位{$unwind:"$default.styles"} 4:條件查詢數組元素{$match:{'default.styles.status':1}} 5:分組後保存結果{$group:{_id:"$_id","defaults":{$push:"$default.styles"}}}
㈥ 使用SpringMVC + MongoDB時,用or條件匹配關鍵字時遇到的問題
使用SpringMVC + MongoDB時,用or條件匹配關鍵字時遇到的問題如下:
在使用SpringMVC框架時,配置web.xml文件時,springDispatcherServlet的配置:
㈦ mongodb 一個文檔內數組中同一個欄位 同時大於或小於一個值,如何寫查詢條件
mongodb中使用aggregate可以返回數組欄位數組的指定索引的元素
參考語句:
{$match:{'id':15}},
{$project:{id:1,"default":1}},
{$unwind:"$default.styles"},
{$match:{'default.styles.status':1}},
{$group:{_id:"$_id","defaults":{$push:"$default.styles"}}}
解釋:
1:過濾數據{$match:{'id':15}}
2:獲取想要的列{$project:{id:1,"default":1}}
3:獲取展開後數組欄位{$unwind:"$default.styles"}
4:條件查詢數組元素{$match:{'default.styles.status':1}}
5:分組後保存結果{$group:{_id:"$_id","defaults":{$push:"$default.styles"}}}
數據結構如下:
{
"_id" : ObjectId("55dad346ea23e7c11beefce5"),
"id" : 11.0,
"default" : {
"style" : "普通會診",
"alias" : "",
"money" : "0",
"styles" : [{
"code" : 1,
"style" : "普通會診",
"alias" : "一般會診",
"money" : 100,
"status" : 1,
"remark" : "需要患者親自來到醫院"
} {
"code" : 6,
"style" : "夜間門診",
"alias" : "夜間門診",
"money" : 100,
"status" : 0,
"remark" : "夜間門診"
}, {
"code" : 7,
"style" : "其他門診",
"alias" : "其他門診",
"money" : 10,
"status" : 0,
"remark" : "其他門診"
}]
}
}