Mongodb

長字元串欄位名稱如何影響 MongoDB 數據庫大小?

  • September 9, 2021

我正在使用 MongoDB,我的欄位名稱是 10-20 個字元的字元串。一個典型的文件由 30.000 列組成,其中大部分都填充了浮點數,例如 1.2、10.5、2.55。它的大小是 1MB。

長字元串欄位名稱會影響 MongoDB 數據庫的大小嗎?

這在開發人員常見問題解答中有所介紹,一些相關摘錄:

MongoDB 將所有欄位名稱儲存在每個文件中。對於大多數文件,這僅代表文件使用的空間的一小部分;但是,對於小型文件,欄位名稱可能會按比例代表大量空間

而且,只是關於索引的註釋:

較短的欄位名稱不會減小索引的大小,因為索引具有預定義的結構

所以,是的,減少欄位名稱大小將使儲存更有效,儘管它不會影響索引大小。您將做出的節省是否值得(相對於失去描述性)將取決於您。作為一個近似值,如果您從 20 個字元欄位名稱(例如)減少到 2 個字元欄位名稱,您可能會為每個欄位節省大約 16 個字節,這意味著文件大小將減少 40% 以上(~400k)。

這是使用 MongoDB shell 來估計這一點的簡單方法:

$ ./mongo --nodb
MongoDB shell version: 3.0.2
> testObject = {"12345678901234567890" : 1.23324}
{ "12345678901234567890" : 1.23324 }
> Object.bsonsize(testObject)
35
> testObject = {"1" : 1.23324}
{ "1" : 1.23324 }
> Object.bsonsize(testObject)
16
> testObject = {"12" : 1.23324}
{ "12" : 1.23324 }
> Object.bsonsize(testObject)
17

Object.bsonsize方法將為您提供任何文件的近似大小(以字節為單位),但不包括在數據庫中儲存文件時實際使用的填充、索引等。因此,這些都是非常近似的數字——我建議使用實際數據進行測試以獲得更明確的範例。

我執行了一個小基準測試,我將 252 行數據從 Excel 上傳到兩個集合 testShortNames 和 testLongNames,如下所示:

長名稱:

{
   "_id": ObjectId("6007a81ea42c4818e5408e9c"),
   "countryNameMaster": "Andorra",
   "countryCapitalNameMaster": "Andorra la Vella",
   "areaInSquareKilometers": 468,
   "countryPopulationNumber": NumberInt("77006"),
   "continentAbbreviationCode": "EU",
   "currencyNameMaster": "Euro"
}

簡稱:

{
   "_id": ObjectId("6007a81fa42c4818e5408e9d"),
   "name": "Andorra",
   "capital": "Andorra la Vella",
   "area": 468,
   "pop": NumberInt("77006"),
   "continent": "EU",
   "currency": "Euro"
}

然後我得到了每個的統計數據,保存在磁碟文件中,然後對這兩個文件做了一個“差異”:

pprint.pprint(db.command("collstats", dbCollectionNameLongNames))

下圖顯示了兩個感興趣的變數:size 和 storageSize。我的閱讀表明 storageSize 是壓縮後使用的磁碟空間量,基本上 size 是未壓縮的大小。所以我們看到 storageSize 是相同的。顯然,Wired Tiger 引擎很好地壓縮了欄位名。 在此處輸入圖像描述

該問題僅詢問磁碟空間。但是,我隨後執行了一個程序來檢索每個集合中的所有數據,並檢查了響應時間。

儘管這是一個亞秒級查詢,但長名稱始終花費大約 7 倍的時間。當然,將較長的名稱從數據庫伺服器發送到客戶端程序需要更長的時間。

-------LongNames-------
Server Start DateTime=2021-01-20 08:44:38
Server End   DateTime=2021-01-20 08:44:39
StartTimeMs= 606964546  EndTimeM= 606965328
ElapsedTime MilliSeconds= 782
-------ShortNames-------
Server Start DateTime=2021-01-20 08:44:39
Server End   DateTime=2021-01-20 08:44:39
StartTimeMs= 606965328  EndTimeM= 606965421
ElapsedTime MilliSeconds= 93

在 Python 中,我只是執行了以下操作(我實際上必須循環遍歷項目以強制讀取,否則查詢僅返迴游標):

results = dbCollectionLongNames.find(query)
for result in results:
   pass

引用自:https://dba.stackexchange.com/questions/117683