2011-10-04 200 views
27

由於Varchar字段的存儲要求基於輸入的字符串的實際長度,將每個Varchar字段指定爲最大可能值的缺點是:Varchar(65535)?那麼,除了最大字段大於255個字符的1個額外字節?爲什麼不將每個VARCHAR指定爲VARCHAR(65535)?

[貯藏Reqts爲長度L的字符串:如果列值需要0 L + 1個字節 - 255字節,L + 2個字節,如果值可能需要超過255個字節]

謝謝!

+1

相關如果不相同的問題:http://stackoverflow.com/questions/262238/are-there-disadvantages-to-using-a-generic-varchar255-for-all-text-based-fields – JJJ

+0

謝謝大家你的評論!我是新來的stackoverflow,並真誠感謝每個人的迴應。 :-) – tgoneil

回答

7

我認爲varchar列長度不僅僅是關於存儲。它們也是關於數據語義的。

I.E.指定name列爲varchar(100)意味着系統中存儲的名稱不能超過100個字符。

在存儲方面,它們應該是一樣的。儘管在沒有它們的情況下(不需要統計數據收集系統在varchar尺寸上保留數據分佈),但在varchar列上的特定長度的行大小估計會更準確。

13

documents - 表列計數和行大小限制:

每個表(無論存儲引擎的)具有65535個字節的最大行大小。存儲引擎可能會對此限制添加其他約束,從而減少有效的最大行大小。

由於所有列的總長度不能超過此大小,因此最大行大小限制了列的數量(以及可能的大小)。例如,utf8字符每個字符最多需要三個字節,因此對於CHAR(255)CHARACTER SET utf8列,服務器必須爲每個值分配255×3 = 765個字節。因此,一個表不能包含超過65,535/765 = 85個這樣的列。

可變長度列的存儲包括長度字節,這是根據行大小進行評估的。例如,VARCHAR(255)CHARACTER SET utf8列需要兩個字節來存儲值的長度,因此每個值最多可能需要767個字節。

所以,制定一個統一VARCHAR(65535)列,有效地限制了你的行中的單列(假設你已經填滿它)。

除了這麼大的尺寸對於某些類型的數據完全錯誤這一事實之外 - 如果您的電話號碼列可能包含本地和國際號碼,則可以選擇使用VARCHAR字段來執行此操作,但將其設置爲20以上的任何內容都可能毫無意義(我很慷慨)。

this answer比爾Karwin這也預示可能的性能損失,如果臨時表與得到不必要的長時間VARCHAR字段(做這樣的領域CHAR和背部的轉換再 - 見職位的詳細信息)生成。

+7

@Downvoter - 謹慎評論? – Oded

+0

但我的表確實有額外的列,除了VARCHAR(65535)列(稱之爲'data1')。由於沒有data1列實際上包含任何接近最大大小的字符串,所有這些列都填充了輸入的數據。 – tgoneil

+2

@tgoneil - 嘗試在該列中插入65535個字符,並將數據插入到其他列中。 – Oded

1

一個可能的原因是提高與其他應用程序的兼容性。例如,如果您的應用使用了長度爲100個字符的「product_no」字段,並且您希望與使用類似字段(如40字符長的「model_no」)的應用進行交互,那將會很痛苦。您應用中超過40個字符的任何product_nos都會被截斷,您必須找出某種方式在應用程序之間轉換它們。

0

原因之一是該字段的大小是對輸入數據的檢查。你真的希望有人輸入一個1000字符的電話號碼嗎?讓字段太大是保證垃圾將被輸入到數據庫中的一種方法。您將有電話號碼是說這樣的話(例如隨機不採取):

「只聊到大的金髮女郎在前線辦公室」

,而不是一個真正的電話號碼或者是包含Notes電子郵件領域關於客戶,因爲他們沒有筆記字段?當您嘗試向其發送電子郵件時效果不佳。

寬表可能會在數據庫中創建各自的問題,因爲您可能會遇到意外的記錄限制(您可以設計一個表,使其比實際存儲在一條記錄中更寬,有時這會導致插入意外失敗)和性能數據頁面之間的數據分離問題。我知道你可以從SQL Server中的寬表中獲得,如果mysql遇到類似的問題,我也不會感到驚訝。 MySQL專家將不得不真正解決這個問題。索引也可能是廣泛領域的問題。數據庫引擎可能不太願意認爲索引是有用的。再說一遍,我不確定mysql是否會遇到這個問題,但這是需要研究的。我知道這些是在SQL Server中對所有內容使用最大字段大小的問題,mysql可能有這些問題或其他SQL Server不支持的問題。

0

例如,MySQL中的MEMORY引擎不能很好地支持VARCHAR-Fields。引擎將爲每一行預留最大字節數量,而不是真正使用的長度。因此,如果您定義一個包含單個VARCHAR(1000)列的表,那麼即使它們是空字符串,您添加的每行都會有1000 * 3字節的內存使用量。