MongoDB高階「正反」正規化設計講解

2021-10-09 01:33:47 字數 3223 閱讀 4670

命名規範

資料庫名稱使用全小寫以』_』隔開,長度最多為64個字元。

集合名稱使用全小寫以』_』隔開,長度最好不超三個英文單詞。

文件key的名稱使用全小寫以』_』隔開,不能以$開頭;不能包含.(點號),長度最好不超三個英文單詞。

索引命名:idx_《構成索引的欄位名》。

注:以上如果欄位名字過長,可採用字段縮寫,縮寫需加說明。

索引

建立「適當」索引可以提高查詢的執行效率,mongodb可以使用索引來限制它必須檢查的文件數。如果沒有索引,mongodb必須執行集合掃瞄,即掃瞄集合中的每個文件,以選擇與查詢語句匹配的文件。

預設_id 索引

mongodb 在建立集合期間在_id欄位上建立了唯一索引。該索引可防止客戶端插入兩個_id字段值相同的文件。_id欄位的索引不能刪除,在分片群集中,如果不將該_id欄位用作分片鍵,則應用程式必須確保_id字段值的唯一性以防止出錯。通常使用標準的自動生成的objectid來完成。

單索引

單鍵索引顧名思義就是單個字段作為索引列,mongodb的所有collection預設都有乙個單鍵索引_id,我們也可以對一些經常作為過濾條件的字段設定索引,如給level欄位新增乙個索引,語法很簡單

db.userinfos.createindex()

復合索引

mongodb支援使用者在多個欄位上定義索引,即 復合索引。

復合索引中字段的順序很重要。例如,如果復合索引為,則索引首先以userid欄位進行排序,然後在每個userid 值以score欄位進行排序。

對於復合索引和排序操作,索引鍵的排序順序(即公升序或降序)可以確定索引是否可以支援排序操作。有關索引順序對復合索引中結果的影響的詳細資訊,請參閱 排序順序。

多鍵索引

多鍵索引是建在陣列上的索引,在mongodb的document中,有些欄位的值為陣列,多鍵索引就是為了提高查詢這些陣列的效率。看乙個栗子:準備測試資料,product集合中新增產品,每個產品都有乙個imgs陣列

db.product.insertmany([,,

]},,,

]}])為了提高查詢product的效率,我們使用 db.classes.createindex() 給students的age欄位新增索引。

索引屬性

唯一索引(unique indexes)用於為collection新增唯一約束,即強制要求collection中的索引字段沒有重複值。

區域性索引(partial indexes)顧名思義,只對collection的一部分新增索引。建立索引的時候,根據過濾條件判斷是否對document新增索引,對於沒有新增索引的文件查詢時採用的全表掃瞄,對新增了索引的文件查詢時使用索引。

稀疏索引(sparse indexes)在有索引欄位的document上新增索引,如在address欄位上新增稀疏索引時,只有document有address欄位時才會新增索引。而普通索引則是為所有的document新增索引,使用普通索引時如果document沒有索引字段的話,設定索引欄位的值為null。

ttl索引(ttl indexes)是一種特殊的單鍵索引,用於設定document的過期時間,mongodb會在document過期後將其刪除,ttl非常容易實現類似快取過期策略的功能。

嵌入

嵌入意味著要把某一型別的資料,如包含更多資料的陣列,嵌入到文件本身。

db.product.findone();,,

]},引用

引用意味著建立乙個引用,包含另乙個文件的資料。

例如:以產品零件訂貨系統為例。每個商品有數百個可替換的零件,但是不會超過數千個。這個用例很適合使用間接引用—將零件的objectid作為陣列存放在商品文件中(在這個例子中的objectid我使用更加易讀的2位元組,現實世界中他們可能是由12個位元組組成的)。

db.parts.findone();

每個產品的文件物件中parts陣列中將會存放多個零件的objectid

db.product.findone();,,

],parts:[

objectid(『1』),

objectid(『2』),

objectid(『3』),

objectid(『4』)]},

你可以採取內嵌,或者建立one端或者n端的引用,也可以三者兼而有之。

你可以在one端或者n端冗餘多個字段

下面這些是你需要謹記的:

1、優先考慮內嵌,除非有什麼迫不得已的原因。

2、需要單獨訪問乙個物件,那這個物件就不適合被內嵌到其他物件中。

3、陣列不應該無限制增長。如果many端有數百個文件物件就不要去內嵌他們可以採用引用objectid的方案;如果有數千個文件物件,那麼就不要內嵌objectid的陣列。該採取哪些方案取決於陣列的大小。

4、不要害怕應用層級別的join:如果索引建的正確並且通過投影條件(第二章提及)限制返回的結果,那麼應用層級別的join並不會比關聯式資料庫中join開銷大多少。

5、在進行反正規化設計時請先確認讀寫比。乙個幾乎不更改只是讀取的字段才適合冗餘到其他物件中。

6、在mongodb中如何對你的資料建模,取決於你的應用程式如何去訪問它們。資料的結構要去適應你的程式的讀寫場景。

設計指南

當你在mongodb中對「一對多」關係進行建模,你有很多的方案可供選擇,所以你必須很謹慎的去考慮資料的結構。下面這些問題是你必須認真思考的:

關係中集合的規模有多大:是一對很少,很多,還是非常多?

對於一對多中」多「的那一端,是否需要單獨的訪問它們,還是說它們只會在父物件的上下文中被訪問。

被冗餘的字段的讀寫的比例是多少?

資料建模設計指南

在一對很少的情況下,你可以在父文件中內嵌陣列。

在一對很多或者需要單獨訪問「n」端的資料時,你可以採用陣列引用objectid的方式。如果可以加速你的訪問也可以在「n」端使用父引用。

在一對非常多的情況下,可以在「n」端使用父引用。

如果你打算在你的設計中引入冗餘等反正規化設計,那麼你必須確保那些冗餘的資料讀取的頻率遠遠大於更新的頻率。而且你也不需要很強的一致性。因為反正規化化的設計會讓你在更新冗餘欄位時付出一定的代價(更慢,非原子化)。

Python高階正則

1 importre2 3 p re.compile 0 9 45 m p.match 13435asadb 67print m.group 一 上面的第二行和第三行也可以合併成一行來寫 m p.match 0 9 13435asadb 效果是一樣的,區別在於第一種方式是提前對要匹配的格式進行編譯,...

js高階正則解析

1.var reg var reg 前者代表任意乙個字元而後者代表這個字串中得有乙個.2.的使用 如果單獨的乙個字元後面帶?var reg d?n?代表乙個或0個這個字元的出現 如果是量詞 和 後面帶?取消正則的貪婪性 在捕獲階段 var reg d var st ahfuoi6565232 con...

高階正則用法 預查

工欲善其事必先利其器,正規表示式無疑是乙個非常強大的工具,從txt,excel,word還有眾多編輯器,還有各種開發語言都有它的蹤影.下面就說下正規表示式較為高階的預查用法 包含4個關鍵字元順序 只能同時出現乙個 預查校驗的標誌 否定 肯定 表示捕獲分組,會把每個分組裡的匹配的值儲存起來,使用 n ...