前述
VARCHAR和CHAR是兩個最主要的字串型別。不幸的是,很難精確地解釋這些值是如何儲存在磁碟和記憶體中的,因為這與儲存引擎的具體實作有關。下面的描述假設使用的儲存引擎是InnoDB和/或MyISAM。如果使用的不是這兩種儲存引擎,請參考所使用的儲存引擎的文件。
先看看VARCHAR和CHAR值通常在磁碟上怎麼儲存。請注意,儲存引擎儲存CHAR或VARCHAR值的方式在記憶體中和在磁碟上可能不一樣,所以MySQL伺服器從儲存引擎讀出的值可能需要轉換成另一種儲存格式。
VARCHAR類型
VARCHAR類型用於儲存可變長字串,是最常見的字串資料型別。它比定長類型更節省空間,因為它只使用必要的空間(例如,越短的字串使用越少的空間)。有一種情況例外,如果MySQL表使用ROW_FORMAT=FIXED創建的話,每一行都會使用定長存儲,這會很浪費空間。
VARCHAR需要使用1或2個額外位元組記錄字串的長度:如果列的最大長度小於或等於255位元組,則只使用1個位元組表示,否則使用2個位元組。假設採用latin1字元集,一個VARCHAR(10)的欄位需要11個位元組的儲存空間。 VARCHAR(1000)的欄位則需要1002個位元組,因為需要2個位元組儲存長度資訊。
VARCHAR節省了儲存空間,所以對效能也有幫助。但是,由於行是變長的,在UPDATE時可能會使行變得比原來更長,這就導致需要做額外的工作。如果一個行佔用的空間增長,並且在頁內沒有更多的空間可以存儲,在這種情況下,不同的存儲引擎的處理方式是不一樣的。例如,MyISAM會將行拆成不同的片段存儲,InnoDB則需要分裂頁來使行可以放進頁內。其他一些儲存引擎也許從不在原始資料位置更新資料。
VARCHAR適用情況
下面這些情況下適用VARCHAR是適當的:
字串列的最大長度比平均長度大很多
列的更新很少,所以碎片不是問題
使用了像UTF-8這樣複雜的字元集,每個字元都使用不同的位元組數進行儲存
#CHAR類型
CHAR類型是定長的:MySQL總是根據定義的字串長度分配足夠的空間。當儲存CHAR值時,MySQL會刪除所有的末尾空格。 CHAR值會根據需要採用空格進行填充以方便比較。
CHAR適合儲存很短的字串,或是所有值都接近同一個長度。例如,CHAR非常適合儲存密碼的MD5值,因為這是一個定長的值。對於經常變更的數據,CHAR也比VARCHAR更好,因為定長的CHAR類型不容易產生碎片。對於非常短的資料列,CHAR比VARCHAR在儲存空間上也更有效率。例如用CHAR(1)來儲存只有Y和N的值,如果採用單字節字元集只需要一個位元組,但是VARCHAR(1)卻需要兩個位元組,因為還有一個記錄長度的額外位元組。
測試
下面透過範例來具體說明CHAR與VARCHAR行為上的不同,首先,我們建立一張只有一個CHAR(10)欄位的表,並且在裡面插入一些值:
CREATE TABLE char_test ( char_col CHAR(10) ); INSERT INTO char_test VALUES ('string1'). (' string2'). ('string3 ');
當我們檢索這些值的時候,會發現string3末尾的空格被截斷了。
SELECT CONCAT("'", char_col, "'") FROM char_test;
執行結果:
如果用VARCHAR(10)欄位儲存相同的值,可以得到下列結果:
CREATE TABLE varchar_test ( varchar_col VARCHAR(10) ); INSERT INTO varchar_test VALUES ('string1'). (' string2'). ('string3 '); SELECT CONCAT("'", varchar_col, "'") FROM varchar_test;
執行結果
VARCHAR(5)與VARCHAR(200)的差異
我們倘若用VARCHAR(5)和VARCHAR(200 )來儲存'hello',我們知道這兩者的空間開銷是一樣的。那我們可以讓VARCHAR的長度始終保持很大嗎?使用更短的列有什麼優勢嗎?
事實證明有很大的優勢。更長的列會消耗更多的內存,因為MySQL通常會分配固定大小的記憶體區塊來保存內部值。尤其是使用記憶體臨時表進行排序或操作時會特別糟糕。在利用磁碟臨時表進行排序時也同樣糟糕。
所以最好的策略是只分配真正需要的空間。
總結
當我們為字串型別的欄位選取類型的時候,判斷該選取VARCHAR或CHAR,我們可以從以下幾個方面來考慮:
該欄位資料集的平均長度與最大長度是否相差很小,若相差很小優先考慮CHAR類型,反之,考慮VARCHAR類型。
若欄位儲存的是MD5後的雜湊值,或一些定長的值,優先選取CHAR類型。
若欄位經常需要更新,優先考慮CHAR類型,由於CHAR類型為定長,因此不容易產生碎片。
對於欄位值儲存很小的信息,如性別等,優先選取CHAR類型,因為VARCHAR類型會佔用額外的位元組保存字串長度資訊。
總之一句話,當我們能夠選取CHAR類型的時候,或是空間消耗相對不是影響因素的重點時,盡量選取CHAR類型,因為在其他方面,CHAR類型都有著或多或少的優勢。而當空間消耗成為了很大的影響因素以後,我們則考慮使用VARCHAR類型。
推薦教學:《Mysql教學》
###以上是MySQL中CHAR和VARCHAR的差別的詳細內容。更多資訊請關注PHP中文網其他相關文章!