您好,登錄后才能下訂單哦!
這期內容當中小編將會給大家帶來有關利用聚合概念指導MongoDB的Schema設計是怎么樣的,文章內容豐富且以專業的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。
習慣的力量強大卻往往無法察覺。往往不經意之間,陷入習慣的陷阱中卻不自知。
在我們的項目中,為了能夠保存分析報表以及用戶設置的報表查詢條件,我們將這些信息視為報表元數據存儲在MongoDB中。要存儲的元數據包括:
報表分類(ReportCategory)
報表(Report)
報表查詢條件(QeuryCondition)
一個報表分類會包含多個報表,同一個報表只能屬于一個分類。每個報表提供了多個標準查詢條件和多個用戶自定義查詢條件。
我需要為這些元數據設計MongoDB的DB Schema。最初考慮將這三個概念合起來定義為元數據表的一條記錄。之后想到對于一個報表而言,需要頻繁對報表的查詢條件進行增刪操作,似乎又應該將查詢條件單獨分離出來。那么報表分類與報表呢?是否將報表也獨立出來才合適?對于MongoDB這樣的Document數據庫而言,將Report作為ReportCategory的embedded屬性也是可行的,至少不會像關系型數據庫那樣會產生數據冗余。倘若要分開,當需要查詢某個分類下的所有報表時,還得多余地做一次Link。
好糾結啊!似乎怎么設計都是可行的,又仿佛總有不如意處。
正在思索中,突然想起對于這樣面向文檔的NoSQL數據庫而言,使用聚合(Aggregate)來觀察表記錄會更加恰當。這個想法恍若閃電般迅捷而銳利,猛地撞向腦中的思緒,一下子點燃了我的設計思維。
這里所謂“聚合”,非面向對象中表達對象關系的概念,而是領域驅動設計(DDD)對對象邊界的思考。關于聚合(Aggregate)的設計,我根據過往的經驗,整理出五條設計原則:
聚合作為一種邊界,主要用于維護業務完整性,此時應遵循業務規則中定義的不變量(Invariant)
作為聚合邊界內的非聚合根實體對象,若可能被別的調用者單獨調用,則應該作為單獨的聚合分離出來
在聚合邊界內的非聚合根對象,與聚合根之間應該存在直接或間接的引用關系,且可以通過對象的引用方式;若必須采用Id來引用,則說明被引用的對象不屬于該聚合
若一個對象缺少另一個對象作為其主對象就不可能存在,則該對象一定屬于該主對象的聚合邊界內
若一個實體對象,可能被多個聚合引用,則該實體對象應首先考慮作為單獨的聚合
這些設計原則都是我在探索聚合設計時的一些思考,多次實踐下來,竊以為頗有指導價值。這里不再鋪開,留待以后的文章詳述。單說本例,我們該如何運用這些原則來思考ReportCategory、Report與QueryCondition之間的關系?
顯然,套用這些原則,我認為前面糾纏不清的混亂思路已可迎刃而解。從業務完整性看,Report雖屬于ReportCategory,但二者未嘗有強的約束關系,即不存在業務上的不變量(Invariant)。例如ReportCategory可以沒有Report,成為一個空的分類,我們也可以撇開ReportCategory,單獨查詢所有的Report。倘若我們將Report放到ReportCategory聚合中,由于Report可能會被單獨調用,聚合的邊界保護反而成為了障礙,不合理。
于是,我們可以得出***個結論:ReportCategory和Report應該屬于兩個不同的聚合。
基于第四條原則,我們可以提出問題:當QueryCondition缺少Report對象后,還有存在意義嗎?答案一目了然,沒有Report,就沒有QueryCondition。皮之不存毛將焉附!第二個結論自然得來:Report與QueryCondition應屬于同一個聚合。于是,模型呼之欲出:
上圖是領域模型而非數據模型。站在領域驅動設計的角度,這才是正確的打開姿勢。那么,使用該領域模型去指導MongoDB的Schema設計,是否有將領域混入技術實現之嫌呢?從設計方向看,先考慮領域模型才是正解,DB的技術實現應為了滿足該領域模型而設計。只有當領域模型可能阻礙技術實現,又或者依據領域模型得到的Schema設計不滿足性能或其他質量屬性需求時,才應該反過來調整領域模型。對于MongoDB這種面向Document的數據庫,以聚合概念指導Schema設計,可謂水到渠成,不僅沒有違和之感,反而讓Repository的實現變得更加簡單、自然。
在項目開發過程中,我先入為主地做了技術選型,從而習慣性地開始針對MongoDB進行Schema設計,反而忘了領域驅動設計的指導原則。技術人員對技術實現往往見獵心喜,因而忽略了領域設計的驅動力,慎之慎之!
上述就是小編為大家分享的利用聚合概念指導MongoDB的Schema設計是怎么樣的了,如果剛好有類似的疑惑,不妨參照上述分析進行理解。如果想知道更多相關知識,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。