除了varchar問題,您還需要了解大多數數據庫將記錄存儲在已分配的存儲塊中(有時稱爲範圍 - 儘管精確的術語取決於rdbms),其中包含一定量的可用空間。這樣做的目的是允許更新,同時最小化表和索引碎片。當然,即使沒有實際的數據,分配的可用空間也會增加數據庫文件的大小。
這些開銷一般可以指定並創建一個使用RDBMS特定的條款表時控制,如果它是一個只讀快照甚至幾乎消除。 OTOH你可能想讓這個填充比平常大,如果你的桌子會看到很多的IUD活動。
一個好的經驗法則是計算你所期望表大小爲你做 - 雖然在其他職位(或樣本數據更好的運行分析)討論再加入20%的VARCHAR大小guesstimating - 一個常見的默認自由空間分配。其實在實踐中是不尋常的自由空間分配造成的問題,特別是如果你部署一個明智的日常維護(所以大多數人從來沒有想過它),但未能預見並通過非常高的IUD活動打了一個表適合分配可以導致追蹤性能問題變得棘手。
要在600GB的磁盤司空見慣它,因爲我已經認真比快速瞎猜其他任何級別大小的數據庫中的很長一段時間,這些天誠實。
*編輯以回覆發表評論 - 「什麼是IUD和你通過維護的意思是刪除舊的記錄? - ?SNEG」
IUD =插入,更新,刪除活動。爲了說明維護問題,可以考慮如果我們創建了一個沒有可用空間的數據庫並且加載了一個表,就像您提出的包含varchar數據的記錄一樣,將會發生什麼情況。所有記錄將被放置在我們的數據庫文件中,它們之間沒有空間。
然後,如果用戶更新了記錄的VARCHAR部分有三種可能性。如果該字段的長度相同,則沒有結構上的變化。如果它更短,我們覆蓋舊字段,並且在字段末尾有幾個備用字節 - 沒有大問題。但是,如果時間更長,那麼我們有一個問題 - 記錄將不再適合。在這種情況下,一種解決方案是將整個修改後的記錄複製到一個新的位置並更新索引(並且在某些管理方案中放下指向舊記錄的指針)。現在的問題是數據的順序讀取 - 不是一種罕見的操作 - 現在必須跳來跳去數據庫文件,而不是通過直讀 - 一個典型的碎片化方案 - 和業績將逐步得到大清洗。
通過給那麼當我們更新我們有一定量還挺大,使我們能夠改變的記錄長度,而不必記錄從頁面上移動表分配的可用空間。當然隨着時間的推移,如果桌子看到很多活動,它仍會碎裂(因爲我們只分配足夠的空餘空間來覆蓋一定比例的記錄變化),這是維護的地方。
這種情況下的維護本質上是一個碎片整理過程來移動記錄,以便重新定位和分配空閒空間,以便再次有效地分配它們。在一些(大多數)RDBMS你可以指定一個維護計劃和安排作業在Q安靜時間(SQL服務器爲例)要做到這一點,但其他人則可能需要手動做到這一點 - 例如在舊版本的Oracle推薦方法是將數據導出,刪除該表並重新創建,然後從備份再重新進口 - 出口/重裝過程中會清理數據,按任何新鮮的負荷。
指數結構有類似的問題。
我當然這裏掩飾了很多,但在一個文件中存儲可變長度的隨機存取數據記錄的基本問題將繼續,不管你堆積在它上面有多少抽象層。好的一點是,這類問題很好理解,大多數情況下它不是你需要擔心的 - 直到你問一個看起來很簡單的問題,例如「這張表需要多少空間」:-)
er ... MB從MB跳到GB從哪裏來? – Powerlord 2008-11-05 21:27:34