字符串可以用來表示任何一種值,所以它是最基本的類型之一。我們可以用字符串類型來存儲圖象或聲音之類的二進制數據,也可存儲用gzip壓縮的數據。下表介紹了各種字符串類型:
Table 1.3. 字符串類數據列類型
類型最大長度占用存儲空間
CHAR[(M)] M字節 M字節
VARCHAR[(M)] M字節 L+1字節
TINYBLOD,TINYTEXT 2^8-1字節 L+1字節
BLOB,TEXT 2^16-1字節 L+2
MEDIUMBLOB,MEDIUMTEXT 2^24-1字節 L+3
LONGBLOB,LONGTEXT 2^32-1字節 L+4
ENUM('value1','value2',...) 65535個成員 1或2字節
SET('value1','value2',...) 64個成員 1,2,3,4或8字節
L+1、L+2是表示數據列是可變長度的,它占用的空間會根據數據行的增減面則改變。數據行的總長度取決於存放在這些數據列裡的數據值的長度。L+1或L+2裡多出來的字節是用來保存數據值的長度的。在對長度可變的數據進行處理時,MySQL要把數據內容和數據長度都保存起來。
如果把超出字符串最大長度的數據放到字符類數據列中,MySQL會自動進行截短處理。
ENUM和SET類型的數據列定義裡有一個列表,列表裡的元素就是該數據列的合法取值。如果試圖把一個沒有在列表裡的值放到數據列裡,它會被轉換為空字符串(“”)。
字符串類型的值被保存為一組連續的字節序列,並會根據它們容納的是二進制字符串還是非二進制字符而被區別對待為字節或者字符:
二進制字符串被視為一個連續的字節序列,與字符集無關。MySQL把BLOB數據列和帶BINARY屬性的CHAR和VARCHAR數據列裡的數據當作二進制值。
非二進制字符串被視為一個連續排列的字符序列。與字符集有關。MySQL把TEXT列與不帶BINARY屬性的CHAR和VARCHAR數據列裡的數據當作二進制值對待。
在MySQL4.1以後的版本中,不同的數據列可以使用不同的字符集。在MySQL4.1版本以前,MySQL用服務器的字符集作為默認字符集。
非二進制字符串,即我們通常所說的字符串,是按字符在字符集中先後次序進行比較和排序的。而二進制字符串因為與字符集無關,所以不以字符順序排序,而是以字節的二進制值作為比較和排序的依據。下面介紹兩種字符串的比較方式:
二進制字符串的比較方式是一個字節一個字節進行的,比較的依據是兩個字節的二進制值。也就是說它是區分大小寫的,因為同一個字母的大小寫的數值編碼是不一樣的。
非二進制字符串的比較方式是一個字符一個字符進行的,比較的依據是兩個字符在字符集中的先後順序。在大多數字符集中,同一個字母的大小寫往往有著相同的先後順序,所以它不區分大小寫。
二進制字符串與字符集無關,所以無論按字符計算還是按字節計算,二進制字符串的長度都是一樣的。所以VARCHAR(20)並不表示它最多能容納20個字符,而是表示它最多只能容納可以用20個字節表示出來的字符。對於單字節字符集,每個字符只占用一個字節,所以這兩者的長度是一樣的,但對於多字節字符集,它能容納的字符個數肯定少於20個。
1.2.2.1. CHAR和VARCHAR
CHAR和VARCHAR是最常用的兩種字符串類型,它們之間的區別是:
CHAR是固定長度的,每個值占用相同的字節,不夠的位數MySQL會在它的右邊用空格字符補足。
VARCHAR是一種可變長度的類型,每個值占用其剛好的字節數再加上一個用來記錄其長度的字節即L+1字節。
CHAR(0)和VARCHAR(0)都是合法的。VARCHAR(0)是從MySQL4.0.2版開始的。它們的作用是作為占位符或用來表示各種on/off開關值。
如何選擇CHAR和VARCHAR,這裡給出兩個原則:
如果數據都有相同的長度,選用VARCHAR會多占用空間,因為有一位用來存儲其長度。如果數據長短不一,選用VARCHAR能節省存儲空間。而CHAR不論字符長短都需占用相同的空間,即使是空值也不例外。
如果長度出入不大,而且是使用MyISAM或ISAM類型的表,則用CHAR會比VARCHAR好,因為MyISAM和ISAM類型的表對處理固定長度的行的效率高。
在一個數據表裡,只要有一個數據列的長度是可變的,則所有數據列的長度將是可變的。MySQL會進行自動地轉換。一個例外,CHAR長度小於4的不會進行自動轉換,因為MySQL會認為這樣做沒必要,節省不了多少空間。反而MySQL會把大量長度小的VARCHAR轉換成CHAR,以減少空間占用量。