MongoDB的文檔存儲結構


MongoDB的文檔存儲結構

MongoDB文檔數據庫的存儲結構分為四個層次,從小到大依次是:鍵值對、文檔(document)、集合(collection)、數據庫(database)。

圖 1 描述了 MongoDB 的存儲與MySQL存儲的對應關系,可以看出,MongoDB中的文檔、集合、數據庫對應於關系數據庫中的行數據、表、數據庫。

img
圖 1:MongoDB 存儲與 Mysql 存儲的對比

鍵值對

文檔數據庫存儲結構的基本單位是鍵值對,具體包含數據和類型。鍵值對的數據包含鍵和值,鍵的格式一般為字符串,值的格式可以包含字符串、數值、數組、文檔等類型。

按照鍵值對的復雜程度,可以將鍵值對分為基本鍵值對和嵌套鍵值對。

  • 圖 2 中的鍵值對中的鍵為字符串,值為基本類型,這種鍵值對就稱為基本鍵值。
  • 嵌套鍵值對類型如圖 3 所示,從圖中可以看岀, contact 的鍵對應的值為一個文檔,文檔中又包含了相關的鍵值對,這種類型的鍵值對稱為嵌套鍵值對。

img
圖 2:MongoDB 文檔數據模型

img
圖 3:嵌套鍵值對

鍵(Key)起唯一索引的作用,確保一個鍵值結構里數據記錄的唯一性,同時也具有信息記錄的作用。例如,country:"China",用:實現了對一條地址的分割記錄,“country”起到了 “China”的唯一地址作用,另外,“country”作為鍵的內容說明了所對應內容的一些信息。

值(Value)是鍵所對應的數據,其內容通過鍵來獲取,可存儲任何類型的數據,甚至可以為空。

鍵和值的組成就構成了鍵值對(Key-Value Pair)。它們之間的關系是一一對應的,如定義了 “country:China”鍵值對,"country”就只能對應“China”,而不能對應“USA”。

文檔中鍵的命名規則如下。

  • UTF-8 格式字符串。
  • 不用有\0的字符串,習慣上不用.$
  • 以開頭的多為保留鍵,自定義時一般不以開頭。
  • 文檔鍵值對是有序的,MongoDB 中嚴格區分大小寫。

文檔

文檔是 MongoDB 的核心概念,是數據的基本單元,與關系數據庫中的行十分類似,但是比行要復雜。文檔是一組有序的鍵值對集合。文檔的數據結構與 JSON 基本相同,所有存儲在集合中的數據都是 BSON 格式。

BSON 是一種類 JSON 的二進制存儲格式,是 Binary JSON 的簡稱。 一個簡單的文檔例子如下:

{"country" : "China", "city": "BeiJing"}

MongoDB 中的數據具有靈活的架構,集合不強制要求文檔結構。但數據建模的不同可能會影響程序性能和數據庫容量。文檔之間的關系是數據建模需要考慮的重要因素。文檔與文檔之間 的關系包括嵌入和引用兩種。

下面舉一個關於顧客 patron 和地址 address 之間的例子,來說明在某些情況下,嵌入優於引用。

{    _id: "joe",    name: "Joe Bookreader"}{    patron_id: "joe",    street: "123 Fake Street",    city: "Faketon",    state: "MA",    zip: "2345"}

關系數據庫的數據模型在設計時,將 patron 和 address 分到兩個表中,在查詢時進行關聯, 這就是引用的使用方式。如果在實際查詢中,需要頻繁地通過 _id 獲得 address 信息,那么就需要頻繁地通過關聯引用來返回查詢結果。在這種情況下,一個更合適的數據模型就是嵌入。

將 address 信息嵌入 patron 信息中,這樣通過一次查詢就可獲得完整的 patron 和 address 信息,如下所示:

{    _id: "joe",    name: "Joe Bookreader",    address: {        street: "123 Fake Street",        city: "Faketon”,        state: nMAnz        zip: T2345”    }}

如果具有多個 address,可以將其嵌入 patron 中,通過一次查詢就可獲得完整的 patron 和多個 address 信息,如下所示:

{    _id: "joe",    name: "Joe Bookreader",    addresses:[        {            street: "123 Fake Streetn,            city: "Faketon",            state: "MA",            zip: "12345"        },        {            street: "l Some Other Street",            city: "Boston",            state: "MA",            zip: "12345"        }    ]}

但在某種情況下,引用用比嵌入更有優勢。下面舉一個圖書出版商與圖書信息的例子,代碼如下:

{    title: "MongoDB: The Definitive Guide",    author: [ "Kristina Chodorow", "Mike Dirolfn"],    published_date: ISODate("2010-09-24"),    pages: 216,    language: "English",    publisher: {        name: "O'Reilly Media",        founded: 1980,        location: "CA"    }}{    title: "50 Tips and Tricks for MongoDB Developer",    author: "Kristina Chodorow",    published_date: ISODate("2011-05-06"),    pages: 68,    language: "English",    publisher: {        name: "O'Reilly Media",        founded: 1980,        location: "CA"    }}

從上邊例子可以看出,嵌入式的關系導致出版商的信息重復發布,這時可采用引用的方式描述集合之間的關系。使用引用時,關系的增長速度決定了引用的存儲位置。如果每個出版商的圖書數量很少且增長有限,那么將圖書信息存儲在出版商文檔中是可行的。

通過 books 存儲每本圖書的 id 信息,就可以查詢到指定圖書出版商的指定圖書信息,但如果圖書出版商的圖書數量很多, 則此數據模型將導致可變的、不斷增長的數組 books,如下所示:

{    name: "O'Reilly Media",    founded: 1980,    location: "CA",    books: [123456789, 234567890, …]}{    _id: 123456789,    title: "MongoDE: The Definitive Guide",    author: ["Kristina Chodorow", "Mike Dirolf"],    published_date: ISODate("2010-09-24"),    pages: 216,    language: "English"}{    _id: 234567890,    title: "50 Tips and Tricks for MongoDB Developer",    author: "Kristina Chodorow",    published_date: ISODate("2011-05-06"),    pages: 68,    language: "English"} 

為了避免可變的、不斷增長的數組,可以將出版商引用存放到圖書文檔中,如下所示:

{    _id: "oreilly",    name: "O'Reilly Media",    founded: 1980,    location: "CA"}{    _id: 123456789,    title: "MongoDB: The Definitive Guiden,    author: [ "Kristina Chodorow", "Mike Dirolf"],    published_date: ISODate("2010-09-24"),    pages: 216,    language: "English",    publisher_id: "oreilly"}{    _id: 234567890,    title: "50 Tips and Tricks for MongoDB Developer",    author: "Kristina Chodorow",    published date: ISODate("2011-05-06"),    pages: 68,    language: "English",    publisher_id: "oreilly"}

集合

MongoDB 將文檔存儲在集合中,一個集合是一些文檔構成的對象。如果說 MongoDB 中的文檔類似於關系型數據庫中的“行”,那么集合就如同“表”。

集合存在於數據庫中,沒有固定的結構,這意味着用戶對集合可以插入不同格式和類型的數據。但通常情況下插入集合的數據都會有一定的關聯性,即一個集合中的文檔應該具有相關性。

集合的結構如圖 4 所示。

img
圖 4:文檔數據庫中的一個集合

數據庫

在 MongoDB 中,數據庫由集合組成。一個 MongoDB 實例可承載多個數據庫,互相之間彼此獨立,在開發過程中,通常將一個應用的所有數據存儲到同一個數據庫中,MongoDB 將不同數據庫存放在不同文件中。

數據庫結構示例如圖 5 所示。

img
圖 5:一個名為 DB 的數據庫的結構


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM