字串類型
MySQL支援很多字串類型,以及它們的許多變化類型。這些資料類型在4.1和5.0版本變化都比較大。可以說變得更複雜了。早在4.1版本中,每個字串列都有自己的字元集和對於那些字元集的定序,或者叫做collation(校對)。
VARCHAR和CHAR
有兩個主要的字串類型就是VARCHAR和CHAR。它們都儲存了字元值。不幸的是,很難準確解釋這些值怎樣儲存在硬碟和記憶體中,因為這些都是有儲存引擎實現的。我們假設你使用的是MyISAM和/或者InnoDB.如果不是,你最好查閱你使用儲存引擎的相關文檔。
讓我們先看看VARCHAR和CHAR是怎樣儲存在硬碟上的。要注意的是儲存引擎可能儲存的CHAR或者VARCHAR在存入記憶體和硬碟上有所不同的,以及當伺服器從儲存引擎獲得了這個值的時候,會把這個值轉為另一個儲存引擎的格式。下面就是兩種類型的比較
VARCHAR:
VARCHAR儲存了變長的字串以及它是最常見的字串資料型別。它佔用的空間要少於定長的類型,因為它根據所需來決定需要的空間大小。特例就是MyISAM參數設為ROW_FORMAT=FIXED.這個參數使表的每一行使用固定大小的空間以及浪費大量的空間。
varchar使用了1或者2額外的位元組記錄值的長度:如果長度大約為255位元組的話,大概使用1個位元組,如果更多的話,那麼就是2個位元組。假如是latin1字元節,一個varchar(10)將會佔用11位元組的儲存空間。一個varchar(1000)使用上限為1002位元組。因為需要2位元組儲存長度資訊。
VARCHAR會對效能有所協助,因為它節約了空間。然而,因為行是變長,當你更新它們的時候,它們就會增長。這樣會導致需要額外的一些工作。如果一行增長以及並不在原來的地址了。這些行為依賴於儲存引擎。舉個例子,MyISAM可能把行分為片段。以及InnoDB可能切開頁,把行填充到它的內部。其他的儲存引擎可能在適當的地方不會更新資料。
當最大列長度比平均長度要大的時候就值得使用VARCHAR.當很少更新欄位的時候,儲存片段就不是一個問題。以及當你使用複雜的字元集如UTF-8時,每個字元都使用變數的位元組數儲存。
在5.0以及最新的版本,當你儲存和擷取值的時候,MySQL會保留尾部的空格。在4.1和更早的版本,MySQL去掉尾部空格。
CHAR
CHAR是定長的:MySQL總是分配指定的記憶體空間去儲存字元。當儲存了一個CHAR值,MySQL去掉尾部空格。值附加了空格是比較的需要。
如果你儲存的字串是非常短的,用CHAR是非常有用的。舉個例子,儲存密碼的MD5值使用CHAR是個好的選擇。因為這個MD5一直是定長的。如果資料經常修改的話CHAR要優於VARCHAR。因為定長的行並不會有儲存殘片。對於非常短的列,CHAR要比VARCHAR高效。一個CHAR(1)用來儲存Y和N值。這隻會使用1個位元組,但是一個VARCHAR(1)會使用兩個位元組。有個位元組用來儲存它的長度資訊。
這個行為讓人有點困惑,因此我們舉一個例子。首先,我們建立一個有單獨CHAR(10)列的表以及儲存一些數值。
mysql> CREATE TABLE char_test( char_col CHAR(10));
mysql> INSERT INTO char_test(char_col) VALUES
-> ('string1'), (' string2'), ('string3 ');
當我們擷取這個值的時候,尾部空格被去掉了。
mysql> SELECT CONCAT("'", char_col, "'") FROM char_test;
+----------------------------+
| CONCAT("'", char_col, "'") |
+----------------------------+
| 'string1' |
| ' string2' |
| 'string3' |
+----------------------------+