2012-08-17 21 views
0

我做了一個測試,以確保我知道ENUM是如何工作的以及它如何處理存儲空間......並獲得了與預期不同的結果。MySql - 爲什麼ENUM需要比預期多的空間?

一個表格,其中一個字段的類型爲VARCHAR(100),填充1,000,000行。每行有一個值是從6個字符串中的1個隨機選擇的,長度爲100.

然後,轉換爲ENUM,然後回到VARCHAR(100)。這裏是結果(數據大小)。

1行百萬= 99.2 MIB,VARCHAR(100)

2.行百萬= 6,835.9 KIB,枚舉 ( 'blah100Characters1', 'blah100Characters2',..., 'blah100Characters6')

3.行百萬99.2 MIB,VARCHAR(100)

VARCHAR(100)類型如預期和MySQL說明書手冊中匹配報道的( 「L + 1個字節,0 < = L < = 255」) 百萬×100 =億= 99.2 MIB

---編輯:好,加上一個額外的字節,但是這是不相關的討論: o)

然而,根據ENUM的MySQL規範(「1或2字節,取決於枚舉值的數量(最大值爲65,535)」),有6種可能的組合,我希望有一個數據每行需要1個字節。 1,000,000 x 1 = 1,000,000 = 976.5 KiB

任何人都可以向我解釋爲什麼轉換後的表格需要6,835.9 KiB,奇怪的是,這幾乎是預期的7倍多?

+0

看起來像一些數據填充正在應用,雖然金額不是2次輪;-) – 2012-08-17 03:46:59

+0

您正在使用哪種存儲引擎?你如何計算大小? – Matthew 2012-08-17 03:48:07

+0

存儲引擎是MyISAM,我將按照phpMyAdmin中該表的「Structure」區域底部的「Space Usage」表中報告的內容進行操作。 – Rickaroo 2012-08-17 03:50:48

回答

0

它增加了7個字節(我得到相同的結果);一些空間是填充,一些是用於刪除標記。

爲了證明有填充,添加額外的枚舉(或微小的整數)。表格的大小不會改變。

要證明存在刪除標記,請刪除中間的一行。表格的大小不會改變。

根據this page,它與myisam_data_pointer_size的默認值爲6個字節(加上1個字節的刪除)有關。

而且他似乎是正確的,因爲如果我這樣做:

alter table foo MAX_ROWS=10; 

表的尺寸減小。

此外,從this "bug" report,它聽起來像刪除的記錄存儲爲指向下一個記錄的指針。如果是這樣,這意味着任何行的最小空間將是指針大小(默認情況下爲6個字節)加上一個刪除字節。這是因爲如果記錄被刪除,刪除字節被設置,然後其他6個字節被用來指向下一個記錄。

如果你想了解更多信息,我可以閱讀MyISAM表格的「刪除鏈接鏈」(當使用固定記錄數時)。

+0

嘿,我想你已經知道了。我發現這[鏈接在mysql手冊](http://dev.mysql.com/doc/refman/5.0/en/server-system-variables.html#sysvar_myisam_data_pointer_size),默認是6個字節,其中加1我的數據的實際參考字節是7. – Rickaroo 2012-08-17 04:21:59

+0

@Rickaroo,我敢肯定附加字節是刪除標誌。每條記錄都有一個隱藏的刪除標誌。您的枚舉的字節是爲可能的行指針保留的那6個字節的一部分。 (如果刪除標誌是0,那麼它知道這6個字節屬於你的數據。)我相信這隻適用於具有固定長度的記錄。即您的varchar版本不是固定長度的,所以它不會得到相同類型的刪除+指針處理。 – Matthew 2012-08-17 04:24:00

+0

我想我開始明白了。而當我沒有指定我的表將是一個較短的最大長度,它只是分配6個字節,知道該表可能會變得很大並且需要它們進行行索引?我學到的一件事是,雖然我假設VARCHAR沒有添加值,但實際上一個VARCHAR(100)單個字段的行長度爲104.所以我的錯誤是假定沒有填充VARCHAR。謝謝! – Rickaroo 2012-08-17 04:49:33

相關問題