MongoDB文檔關系設計——基礎篇

近些年,No-SQL數(shù)據(jù)庫興起,在存儲與處理大數(shù)據(jù)方面具備天然的優(yōu)勢。但對于如何設計No-SQL數(shù)據(jù)庫的資料少之又少,很多人都是在邊實踐、邊學習,踩過不少坑。MongoDB是目前主流的No-SQL之一,文檔關系的設計是其中常見的難點。本系列文章將從基礎談起,聊聊如何將文檔關系設計做好。本文是此系列文章的第一篇,介紹文檔關系設計的基礎知識。

當開始設計MongoDB的結構(schema)時,你需要考慮一個在SQL關系型數(shù)據(jù)庫(RMDBS)不會遇到的問題:文檔之間的數(shù)量對應關系。具體來說,你需要思考one-to-N關系是one-to-few,one-to-many或者one-to-squillions三種中的哪種。根據(jù)具體的對應關系不同,你將會使用不同的關系模型。

1. 基本模型:One-to-Few

一個one-to-few的例子就是一個人的地址。在這個例子中,地址文檔(Address)適合被內嵌(embedded)在人(Person)的文檔中,可以將Address文檔以數(shù)組的方式存儲在Person的文檔中。

這種設計具有內嵌關系的優(yōu)點和缺點。優(yōu)點在于你無須利用一個單獨的查詢來讀取內嵌文檔的細節(jié);主要的缺點在于你無法作為一個單獨的實體來訪問內嵌文檔的細節(jié)。

在人-地址的例子中,你可以非常方便查詢到一個人名下的所有地址,但對于查詢所有地址在某個城市的人,將會是相當困難。

2. 基本模型:One-to-Many

一個典型one-to-many的例子就是電商系統(tǒng)中的顧客與訂單之間的關系,而且隨著時間的增加,顧客的訂單數(shù)會逐漸增長,會達到上百,甚至上萬個。在這種情形下,非常適合使用引用(reference),將訂單的ObjectIDs存儲在一個數(shù)組中,然后內嵌在顧客的文檔中。

在這種設計中,每個訂單是一個文檔,每個顧客也是一個文檔,而且包含一個指向訂單引用的數(shù)組。那么為了獲取某個顧客的所有訂單,可以通過應用程序層面(application-level)的關聯(lián)操作來實現(xiàn)。為了提高查詢效率,需要對顧客的_id建立索引。由于orders._id本身就存在索引(因為_id存儲在一個數(shù)組中),所以對訂單的查詢效率通常很高。

這種內嵌文檔引用的方式既有好處,也有壞處。由于每個子文檔(訂單)是一個獨立的文檔,因而對于搜索與更新子文檔(訂單)來說,非常方便。但這種設計的一個不足之處在于,需要兩個查詢才能獲得子文檔(訂單)的詳情。比如要查詢名為張三顧客的未付款訂單詳情:第一步,根據(jù)姓名查詢顧客集合,獲取顧客張三的文檔;第二步,根據(jù)查的顧客文檔,再查詢所有未付款訂單詳情。

這種設計的一個額外好處,就是可以拓展到N-to-N關系模型,由于子文檔是獨立存在的文檔,那么子文檔可以內嵌在多個不同的父文檔中。比如在一個學校中,學生與老師之間是一個N-to-N關系,老師可以給多名學生授課,一名學生可以擁有多名授課老師。

3. 基本模型:One-to-Squillions

這是一對超多的關系,這個超多的概念可以理解為千萬級別的數(shù)據(jù)量。一個常見的例子就是應用的日志系統(tǒng),日志系統(tǒng)收集分布式主機上的各種事件日志,這個數(shù)據(jù)非常大,而且增長迅速。即使采用日志文檔引用數(shù)組的方式進行存儲,任何一臺主機上的日志數(shù)量可以很容易超過16MB的文檔大小。此時,非常適合采用常見的父引用(parent-referencing)方式進行存儲:每臺主機擁有一個文檔,然后將主機日志文檔的引用存儲在日志消息的文檔中。

在此種情形下,你可以利用應用程序級別上的關聯(lián)查詢,來獲取某個主機上的最近5000條日志。

說明:對于BSON-document方式存儲的文件,其大小的限制是16MB,如果希望存儲更大數(shù)據(jù)大小的集合文件,可以考慮GridFS方式。更多關于GridFS的說明,可以參考官方文檔。

總結

以上是三種基本的one-to-N關系模型,當你設計MongoDB的數(shù)據(jù)庫結構時,你需要考慮兩個因素:

  • 對于N類文檔,是否需要單獨被存儲?
  • 文檔之間的具體關系是什么,是one-to-few,one-to-many,還是one-to-sequillions?

基于這兩方面的因素,你可以選擇上述三種的一種方式進行設計:

  • 如果是one-to-few關系,并且無須從父文檔之外的方式訪問N類文檔,內嵌N類文檔;
  • 如果是one-to-many關系,并且希望N類文檔以獨立的文檔存儲,那么使用N類文檔的引用數(shù)組,并內嵌在父文檔中;
  • 如果是one-to-sequillions關系,在N類文檔中存儲一個指向one類文檔的引用。

N類文檔,代表處在N這邊的文檔,在一個顧客訂單(one-to-many)關系中,N類文檔指訂單文檔,one類文檔代指顧客文檔

如果覺得此文能夠給你帶來幫助和啟發(fā),請不要吝嗇你的贊_。同時關注該該專題,后面的章節(jié)會陸續(xù)奉獻給大家。祝各位周末愉快!

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • Spring Cloud為開發(fā)人員提供了快速構建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,578評論 19 139
  • 95天 (一)打電話 昨晚夢見姥姥生病了,我和姐姐去看她,她很瘦,生病了。看見我和姐姐走進房間,她努力的掙眼睛,說...
    青衣雨翼_shape閱讀 200評論 0 0
  • 變量、作用域和內存問題 變量基本類型值和引用類型值 執(zhí)行環(huán)境和作用域當代碼在一個環(huán)境中執(zhí)行時,會創(chuàng)建變量對象的一個...
    回調的幸福時光閱讀 330評論 0 0
  • 人人都自私,都恨不得為自己的行為找藉口,為自己的際遇尋發(fā)泄。人生根本涼薄如此,并不能深怪,反倒是稍稍肯讓步,容忍,...
    靜然說秩序生活閱讀 569評論 0 0
  • 今下午和女兒一起去書店買書,上次我們去書店買《紅星照耀中國》沒買到,今天但愿能買到。 到了書店,店...
    于佳禾媽媽閱讀 200評論 0 4

友情鏈接更多精彩內容