1. 程式人生 > >【轉】MongoDBDataModels資料結構設計

【轉】MongoDBDataModels資料結構設計

MongoDBDataModels資料結構設計

1 資料建模介紹

MongoDB的資料結構很靈活,不強制要求資料結構.但是通常一個集合內部使用相同的結構.

資料建模的關鍵是平衡應用的需求和資料庫執行和資料檢索模型的效能.設計資料模型時,要考慮資料的使用情況和資料自身的結構

1.1 文件結構

設計MongoDB應用的資料模型的關鍵在於文件結構和應用程式如何表示資料之間的關係,這有兩種工具允許應用程式來表示這些關係:引用和嵌入型文件.

1.1.1 引用:


類似關係型資料庫中的外來鍵的引用,通常不同的集合中互相引用_id欄位

\

1.1.2 內嵌資料:


某個欄位的值為BSON或者某個欄位值為陣列,陣列中的每個值為BSON

\

1.2 寫操作的原子性

MongoDB在文件級別的寫操作是原子性的,沒有任何單個修改多條文件,或者多個集合的操作是原子性的.包含嵌入型資料的非標準化資料將其所表示的實體的所有的相關資料在單個文件中儲存,這使得對這個實體的操作變為對這個文件的原子性操作.標準化資料的過程將資料跨多個集合儲存,這使得每次對實體的修改需要多次寫操作,並且多次寫操作不是原子性的.

然而,方便原子操作的結構也許會限制應用程式使用資料或者限制修改應用程式.

1.3 文件增長

一些更新操作,比如向陣列中追加元素或者向文件中新增欄位,都會導致文件大小增加.
如果文件大小超過了分配給它的空間,MongoDB將重新在硬碟上為其分配空間.這種增長將影響你選擇使用標準化資料還是非標準化資料

1.4 資料的使用和效能

當設計資料模型的時候,考慮應用程式將怎樣使用你的資料庫.比如說:如果你的應用程式只是使用最近插入的文件,考慮使用Capped Collections,或者你的應用程式主要是讀取操作,為常用的查詢新增索引來改善效能.

2 資料建模概念

2.1 資料模型設計

高效的資料模型迎合應用程式的需求.文件結構考慮的關鍵因素是使用嵌入型文件還是使用引用

2.1.1嵌入型資料模型

\

嵌入型文件允許一個文件中儲存多條相關資訊應用程式可以執行更少的查詢和更新操作.

以下情況使用嵌入型文件:
1.實體間有"包含"的關係
2.實體間有一對多的關係.在這種關係中,多的一方總是在一的一方作為上下文或者作為父文件的時候出現.

嵌入型文件讀操作效能較好,單一資料庫的時候檢索資料快.update相關資料的操作是原子性的.

缺點:嵌入型文件導致文件建立後大小的增長.進一步說,文件必須小於BSON文件的最大值限制

與嵌入型文件進行互動,需要使用"."操作符來訪問嵌入型文件

2.1.2標準化資料模型

標準化資料使用引用來描述文件間的關係

\

以下情況使用標準化資料模型:
1.嵌入型文件模型導致資料重複的同時,查詢效能優勢不能彌補資料重複帶來的不足的時候
2.用以表示更加複雜的多對多的關係
3.用以建模多層的資料集

引用比嵌入更加靈活.然而隨之而來的是應用程式需要查詢並解析相關的引用.換句話說,標準化資料模型會導致程式和MongoDB之間更多的通訊.

2.2 操作的因素和資料模型

需要權衡考慮資料自身和資料庫.

2.2.1 文件增長

陣列的push操作,和增加新的 欄位將會導致文件大小的增長.超過文件已分配的空間大小的時候,MongoDB將會為其重新分配空間,這將導致比原地更新花費更多的時間,同時也會導致碎片化儲存.雖然MongoDB自動會在文件之間新增空隙以減少類似的重新分配,建立模型的時候需要儘可能的避免文件增長

2.2.2 原子操作

上面已有介紹,略

2.2.3 Sharding

MongoDB使用Sharding技術來提供水平的縮放.這些叢集支援大資料集的開發和高吞吐量的操作.Sharding允許使用者將一個數據庫內的一個集合,通過mongod的例項或者shards的標號,分散到多個集合文件中

2.2.4 索引

使用索引來改善查詢效能.在某些欄位上建立索引,通常是在這些欄位上的查詢返回排序的結果的時候.MongoDB自動在_id欄位上建立索引.

建立索引時要考慮以下內容:
1.每個索引需要至少8KB的空間
2.建立索引會對寫操作有負面影響,對於寫操作很多的集合來說,索引的所花費的代價很高因為每次插入的操作都必須更新所有的索引
3.對於讀操作較多的集合來說,索引通常是有益的.索引不影響沒有建立索引的讀操作.
4.當啟用的時候,每個索引都會消耗硬碟和記憶體空間.這些開銷對於容量計劃,特別是超過工作集的大小的考慮,是極為關鍵的,應該追蹤的.

2.2.5 大量的集合

在某些情況下,需要選擇將相關的資訊儲存字多個集合中而不是一個集合中,比如不同的log內容儲存在不同的log集合中

\

通常大量的集合沒有效能的減弱而是效能的優化.不同的集合對於高吞吐量的批處理程序是非常重要的.

當使用有大量集合的資料模型的時候,考慮以下內容:
1.每個集合至少需要即k空間
2.每個索引,包括_id上的索引,需要至少8KB空間
3.對於資料庫來說,一個,名稱空間檔案儲存著該資料庫所有的元資料,每個索引和集合在這個名稱空間檔案中有其自己的入口.
4.MongoDB對於名稱空間的數量有限制.你也許想知道當前的名稱空間數,以決定資料庫還可以支援多少額外的 名稱空間,查詢當前名稱空間的數量,在mongo的shell中執行:db.system.namespaces.count()

2.2.6 資料生命週期管理

資料建模的時候應該考慮資料的生命週期管理.
如果你的應用程式需要使用限定時間段內的資料,考慮使用TTL屬性.
另外,如果你的應用程式僅僅使用最近插入的文件,考慮使用Capped Collections.它提供了對於文件的FIFO(也就是佇列式)的管理,有效的支援哪些依賴於插入順序的插入和讀取操作.

2.3 GridFS

GridFS是對於超過BSON文件大小限制16M的文件儲存和檢索的規範.
不是將檔案儲存在單個文件中,GridFS將檔案分割為多個部分,或者資料庫,將每個資料塊作為單獨的文件進行儲存.預設的GridFS限制資料塊大小為255k.GridFS使用兩個集合來儲存檔案.一個結合儲存檔案的資料塊,另一個儲存檔案的元資料資訊.

當你查詢GridFS儲存的檔案的時候,驅動,或者客戶端將重新組裝你需要的資料塊.你可以對儲存在GridFS中的檔案執行多種查詢.你也可以獲取檔案的某一塊的資訊,這使得你可以跳到視訊或者音訊的中間部分.

GridFS不僅僅對於儲存大小超過16M的檔案有用,它可以用於儲存任何你在訪問時不想將整個檔案載入到記憶體中的檔案