最近收到一個業務需求,需求是基于電影票售賣的不同管道價格存儲。某一個場次的電影,不同的銷售管道對應不同的價格。整理需求為:
資料字段:
場次資訊;
播放影片資訊;
管道資訊,與其對應的價格;
管道數量最多幾十個;
業務查詢有兩種:
根據電影場次,查詢某一個管道的價格;
根據管道資訊,查詢對應的所有場次資訊;
我們先來看其中一種典型的不好模組化設計:
資料表達上基本沒有字段備援,非常緊湊。再來看業務查詢能力:
建立<code>createindex({scheduleid:1, movie:1})</code>索引,雖然對price來說沒有建立索引優化,但通過前面兩個次元,已經可以定位到唯一的文檔,查詢效率上來說尚可;
為了優化這種查詢,需要對每個管道分别建立索引,例如:
<code>createindex({"price.gewala":1})</code>
<code>createindex({"price.maoyan":1})</code>
<code>createindex({"price.taopiao":1})</code>
但管道會經常變化,并且為了支援此類查詢,肯能需要建立幾十個索引,對維護來說簡直就是噩夢;
此設計行不通,否決。
與上面的方案相比,把整個存儲對象結構進行了平鋪展開,變成了一種表結構,傳統的關系資料庫多數采用這種類型的方案。資訊表達上,把一個對象按照管道次元拆成多個,其他的字段進行了備援存儲。如果業務需求再複雜點,造成的資訊備援膨脹非常巨大。膨脹後帶來的副作用會有磁盤空間占用上升,記憶體命中率降低等缺點。對查詢的處理呢:
建立<code>createindex({scheduleid:1, movie:1, channel:1})</code>索引;
建立<code>createindex({channel:1})</code>索引;
更進一步的優化呢?
]說明
建立<code>createindex({scheduleid:1, movie:1, "provider.channel":1})</code>索引;
建立<code>createindex({"provider.channel":1})</code>索引;
再通過<code>explain</code>來驗證上面兩個索引是否起到作用:
這個案例并不複雜,需求也很清晰,但确實非常典型的mongodb模組化設計,開發人員在進行模組化設計時經常也會受傳統資料庫的思路影響,沿用之前的思維慣性,而忽略了“文檔”的價值。