序列不從1開始的另一個原因從技術的角度來說可能不值一提。例如,在分配會員號時,序列號不要從1開始,以免出現關於誰是第一號的政治爭論。
(4) 不用AUTO_INCREMENT 生成序列生成序列號的另一個方法根本就不需要使用AUTO_INCREMENT 列。它利用取一個參數的L A S T _ INSERT_ID( ) 函數的變量來生成序列號。(這種形式在MySQL3.22.9. 中引入)如果利用L A S T _ INSERT_ID(expr) 來插入或更新一個列, 則下一次不用參數調用L A S T _ INSERT_ID( ) 時,將返回expr 的值。換句話說,就像由AUTO_INCREMENT 機制生成的那樣對expr 進行處理。這樣使得能生成一個序列號,然後可在以後的客戶會話中利用它,用不著取受其他客戶機影響的值。利用這種策略的一種方法是創建一個包含一個值的單行表,該值在想得到序列中下一個值時進行更新。例如,可創建如下的表:
上面的語句創建了表seq_table 並用包含seq 值0 的行對其進行初始化。可利用這個表產生下一個序列號,如下所示:
該語句取出seq 列的當前值並對其加1,產生序列中的下一個值。利用L A S T _ INSERT _ID(seq + 1) 生成新值使它就像一個AUTO_INCREMENT 值一樣,而且此值可在以後的語句中通過調用無參數的L A S T _ INSERT_ID( ) 來取出。即使某個其他客戶機同時生成了另一個序列號,上述作用也不會改變,因為L A S T _ INSERT_ID( ) 是客戶機專用的。如果希望生成增量不是1的編號序列或負增量的編號序列,也可以利用這個方法。例如,下面兩個語句可以用來分別生成一個增量為100 的編號序列和一個負的編號序列:
通過將seq 列設置為相應的初始值,可利用這個方法生成以任意值開始的序列。關於將此序列生成方法用於多個計數器的應用,可參閱第3章。
2.2.3 串列類型
MySQL提供了幾種存放字符數據的串類型。串常常用於如下這樣的值:
在某種意義上,串實際是一種“通用”類型,因為可用它們來表示任意值。例如,可用串類型來存儲二進制數據,如影像或聲音,或者存儲gzip 的輸出結果,即存儲壓縮數據。對於所有串類型,都要剪裁過長的值使其適合於相應的串類型。但是串類型的取值范圍很不同,有的取值范圍很小,有的則很大。取值大的串類型能夠存儲近4GB 的數據。因此,應該使串足夠長以免您的信息被切斷(由於受客戶機/服務器通信協議的最大塊尺寸限制,列
值的最大限額為2 4 MB)。
表2 - 8給出了MySQL定義串值列的類型,以及每種類型的最大尺寸和存儲需求。對於可變長的列類型,各行的值所占的存儲量是不同的,這取決於實際存放在列中的值的長度。這個長度在表中用L 表示。
L 以外所需的額外字節為存放該值的長度所需的字節數。MySQL通過存儲值的內容及其長度來處理可變長度的值。這些額外的字節是無符號整數。請注意,可變長類型的最大長度、此類型所需的額外字節數以及占用相同字節數的無符號整數之間的對應關系。例如,
MEDIUMBLOB 值可能最多22 4 - 1字節長並需要3 個字節記錄其結果。3 個字節的整數類型MEDIUMINT 的最大無符號值為22 4 - 1。這並非偶然。
1. CHAR 和VARCHAR 列類型
CHAR 和VARCHAR 是最常使用的串類型。它們是有差異的, CHAR 是定長類型而VARCHAR 是可變長類型。CHAR(M) 列中的每個值占M 個字節;短於M 個字節的值存儲時在右邊加空格(但右邊的空格在檢索時去掉)。VARCHAR(M) 列的值只用所必需的字節數來存放(結尾的空格在存儲時去掉,這與ANSI SQL 的VARCHAR 值的標准不同),然後再加一個字節記錄其長度。如果所需的值在長度上變化不大,則CHAR 是一種比VARCHAR 好的選擇,因為處理行長度固定的表比處理行長度可變的表的效率更高。如果所有的值長度相同,由於需要額外的字節來記錄值的長度,VARCHAR 實際占用了更多的空間。在MySQL3.23 以前,CHAR 和VARCHAR 列用最大長度為1到255 的M 來定義。從MySQL3.23 開始,CHAR(0) 也是合法的了。在希望定義一個列,但由於尚不知道其長度,所以不想給其分配空間的情況下, CHAR(0) 列作為占位符很有用處。以後可以用ALTE RTABLE 來加寬這個列。如果允許其為NULL,則CHAR(0) 列也可以用來表示o n / o ff 值。這樣的列可能取兩個值,NULL 和空串。CHAR(0) 列在表中所占的空間很小,只占一位。除少數情況外,在同一個表中不能混用CHAR 和VARCHAR。MySQL根據情況甚至會將列從一種類型轉換為另一種類型。這樣做的原因如下: