第11章:列類型

目錄

11.1. 列類型概述
11.1.1. 數值類型概述
11.1.2. 日期和時間類型概述
11.1.3. 字串類型概述
11.2. 數值類型
11.3. 日期和時間類型
11.3.1. DATETIME、DATE和TIMESTAMP類型
11.3.2. TIME類型
11.3.3. YEAR類型
11.3.4. Y2K事宜和日期類型
11.4. String類型
11.4.1. CHAR和VARCHAR類型
11.4.2. BINARY和VARBINARY類型
11.4.3. BLOB和TEXT類型
11.4.4. ENUM類型
11.4.5. SET類型
11.5. 列類型儲存需求
11.6. 選擇正確的列類型
11.7. 使用來自其他資料庫引擎的列類型

MySQL支援多種列類型:數值類型、日期/時間類型和字串(字元)類型。本章首先對這些列類型進行了概述,然後更加詳細地描述了各種列的類型,以及列類型儲存需求的總結。概述很簡單。關於具體列類型的詳細訊息應查閱詳細的描述,例如指定值時允許使用的格式。

MySQL支援處理空間數據的延伸名。關於空間類型的訊息參見第19章:MySQL中的空間延伸

幾種列類型描述使用了下述慣例:

·         M

資料表示最大顯示寬度。最大有效顯示寬度是255

·         D

適用於浮點和定點類型,並資料表示小數點後面的位數。最大可能的值是30,但不應大於M-2

·         方括號([』和『])資料表示可選部分。

11.1. 列類型概述

11.1.1. 數值類型概述

下面為數值列類型的概述。詳細訊息參見11.2節,「數值類型」。列儲存需求參見11.5節,「列類型儲存需求」

M指示最大顯示寬度。最大有效顯示寬度是255。顯示寬度與儲存大小或類型包含的值的範圍無關,相關描述見11.2節,「數值類型」

如果為一個數值列指定ZEROFILLMySQL自動為該列新增UNSIGNED屬性。

SERIALBIGINT UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE的一個別名。

在整數列定義中,SERIAL DEFAULT VALUENOT NULL AUTO_INCREMENT UNIQUE的一個別名。

警告:應當清楚,當使用在整數值(其中一個是UNSIGNED類型)之間使用減號時,結果是無符號。參見12.8節,「Cast函數和操作符」

·         BIT[(M)]

位元類型。M資料表示每個值的位數,範圍為從164。如果M被省略, 預設為1

·         TINYINT[(M)] [UNSIGNED] [ZEROFILL]

很小的整數。帶符號的範圍是-128127。無符號的範圍是0255

·         BOOLBOOLEAN

TINYINT(1)的同義詞。zero值被視為假。非zero值視為真。

在將來,將根據標準SQL引入完全布爾類型的處理。

·         SMALLINT[(M)] [UNSIGNED] [ZEROFILL]

小的整數。帶符號的範圍是-3276832767。無符號的範圍是065535

·         MEDIUMINT[(M)] [UNSIGNED] [ZEROFILL]

中等大小的整數。帶符號的範圍是-83886088388607。無符號的範圍是016777215

·         INT[(M)] [UNSIGNED] [ZEROFILL]

普通大小的整數。帶符號的範圍是-21474836482147483647。無符號的範圍是04294967295

·         INTEGER[(M)] [UNSIGNED] [ZEROFILL]

這是INT的同義詞。

·         BIGINT[(M)] [UNSIGNED] [ZEROFILL]

大整數。帶符號的範圍是-92233720368547758089223372036854775807。無符號的範圍是018446744073709551615

應清楚BIGINT列的下述內容:

o        使用帶符號的BIGINTDOUBLE值進行所有算法,因此除了位函數,不應使用大於9223372036854775807(63)的無符號的大整數! 如果這樣做,結果中的最後幾位可能出錯,這是由於將BIGINT值轉換為DOUBLE進行四捨五入時造成的錯誤。

MySQL可以在以下情況下處理BIGINT

§         當使用整數在一個BIGINT列保存大的無符號的值時。

§         MIN(col_name)MAX(col_name)中,其中col_nameBIGINT列。

§         使用操作符(+-*等等)並且兩個操作數均為整數時。

o        總是可以使用一個字串在BIGINT列中保存嚴格整數值。在這種情況下,MySQL執行字串-數字轉換,其間不存在雙精度資料表示。

o        當兩個操作數均為整數值時,-+* 操作符使用BIGINT算法。這說明如果乘兩個大整數(或來自返回整數的函數),當結果大於9223372036854775807時,會得到意想不到的結果。

·         FLOAT[(M,D)] [UNSIGNED] [ZEROFILL]

(單精度)浮點數。允許的值是-3.402823466E+38-1.175494351E-3801.175494351E-383.402823466E+38。這些是理論限制,基於IEEE標準。實際的範圍根據硬件或作業系統的不同可能稍微小些。

M是小數縱位數,D是小數點後面的位數。如果MD被省略,根據硬件允許的限制來保存值。單精度浮點數精確到大約7位小數位。

如果指定UNSIGNED,不允許負值。

使用浮點數可能會遇到意想不到的問題,因為在MySQL中的所有計算用雙精度完成。參見A.5.7節,「解決與不匹配行有關的問題」

·         DOUBLE[(M,D)] [UNSIGNED] [ZEROFILL]

普通大小(雙精度)浮點數。允許的值是-1.7976931348623157E+308-2.2250738585072014E-30802.2250738585072014E-3081.7976931348623157E+308。這些是理論限制,基於IEEE標準。實際的範圍根據硬件或作業系統的不同可能稍微小些。

M是小數總位數,D是小數點後面的位數。如果MD被省略,根據硬件允許的限制來保存值。雙精度浮點數精確到大約15位小數位。

如果指定UNSIGNED,不允許負值。

·         DOUBLE PRECISION[(M,D)] [UNSIGNED] [ZEROFILL], REAL[(M,D)] [UNSIGNED] [ZEROFILL]

DOUBLE的同義詞。除了:如果SQL伺服器模式包括REAL_AS_FLOAT選項,REALFLOAT的同義詞而不是DOUBLE的同義詞。

·         FLOAT(p) [UNSIGNED] [ZEROFILL]

浮點數。p資料表示精度(以位數資料表示),但MySQL只使用該值來確定是否結果列的數據類型為FLOATDOUBLE。如果p為從024,數據類型變為沒有MD值的FLOAT。如果p為從2553,數據類型變為沒有MD值的DOUBLE。結果列範圍與本節前面描述的單精度FLOAT或雙精度DOUBLE數據類型相同。

FLOAT(p)語法與ODBC兼容。

·         DECIMAL[(M[,D])] [UNSIGNED] [ZEROFILL]

壓縮的「嚴格」定點數。M是小數位數(精度)的總數,D是小數點(標度)後面的位數。小數點和(負數)的『-』符號不包括在M中。如果D0,則值沒有小數點或分數部分。DECIMAL整數最大位數(M)65。支援的十進制數的最大位數(D)30。如果D被省略, 預設是0。如果M被省略, 預設是10

如果指定UNSIGNED,不允許負值。

所有DECIMAL列的基本計算(+-*/)65位精度完成。

·         DEC[(M[,D])] [UNSIGNED] [ZEROFILL], NUMERIC[(M[,D])] [UNSIGNED] [ZEROFILL], FIXED[(M[,D])] [UNSIGNED] [ZEROFILL]

DECIMAL的同義詞。FIXED同義詞適用於與其它伺服器的相容性。

11.1.2. 日期和時間類型概述

本節綜合討論了臨時列類型。詳細訊息,參見11.3節,「日期和時間類型」。列儲存需求參見11.5節,「列類型儲存需求」

·         DATE

日期。支援的範圍為'1000-01-01''9999-12-31'MySQL'YYYY-MM-DD'格式顯示DATE值,但允許使用字串或數字為DATE列分配值。

·         DATETIME

日期和時間的組合。支援的範圍是'1000-01-01 00:00:00''9999-12-31 23:59:59'MySQL'YYYY-MM-DD HH:MM:SS'格式顯示DATETIME值,但允許使用字串或數字為DATETIME列分配值。

·         TIMESTAMP[(M)]

時間戳。範圍是'1970-01-01 00:00:00'2037年。

TIMESTAMP列用於INSERTUPDATE操作時記錄日期和時間。如果您不分配一個值,資料表中的第一個TIMESTAMP列自動設置為最近操作的日期和時間。也可以通過分配一個NULL值,將TIMESTAMP列設置為當前的日期和時間。

TIMESTAMP值返回後顯示為'YYYY-MM-DD HH:MM:SS'格式的字串,顯示寬度固定為19個字元。如果想要獲得數字值,應在TIMESTAMP 列新增+0

註釋:MySQL 4.1以前使用的TIMESTAMP格式在MySQL 5.1中不支援;關於舊格式的訊息參見MySQL 4.1 參考手冊

·         TIME

時間。範圍是'-838:59:59''838:59:59'MySQL'HH:MM:SS'格式顯示TIME值,但允許使用字串或數字為TIME列分配值。

·         YEAR[(2|4)]

兩位或四位格式的年。預設是四位格式。在四位格式中,允許的值是190121550000。在兩位格式中,允許的值是7069,資料表示從1970年到2069年。MySQLYYYY 格式顯示YEAR值,但允許使用字串或數字為YEAR列分配值。

11.1.3. 字串類型概述

本節綜合討論了字串列類型。詳細訊息參見11.4節,「String類型」。列儲存需求參見11.5節,「列類型儲存需求」

在某些情況中,MySQL可以將一個字串列更改為不同於CREATE TABLEALTER TABLE語句中所給出的類型。參見13.1.5.1節,「沉寂的列規格變更」

MySQL 5.1字串數據類型包括部分在MySQL 4.1之前的版本中沒有的特性:

·         許多字串數據類型的列定義可以包括指定字元編碼的CHARACTER SET屬性,也可能包括校對規則。(CHARSETCHARACTER SET的一個同義詞)這些屬性適用於CHARVARCHARTEXT類型、ENUMSET。例如:

·                CREATE TABLE t
·                (
·                    c1 CHAR(20) CHARACTER SET utf8,
·                    c2 CHAR(20) CHARACTER SET latin1 COLLATE latin1_bin
·                );

該資料表定義建立了一個名為c1的列,具有一個utf8字元編碼和該字元編碼的預設 校對規則,和一個名為c2的列以及latin1字元編碼和該字元編碼的二元 校對規則。二元校對規則對大小寫不敏感。

·         MySQL 5.1用字元單位解釋在字元列定義中的長度規範。(以前的一些MySQL版本以字節解釋長度)

·         對於CHARVARCHARTEXT類型,BINARY屬性可以為列分配該列字元編碼的 校對規則。

·         字元列的排序和比較基於分配給列的字元編碼。在以前的版本中,排序和比較基於伺服器字元編碼的校對規則。對於CHARVARCHAR 列,您可以用BINARY屬性聲明列讓排序和 校對規則使用當前的字元代碼值而不是詞彙順序。

關於MySQL 5.1中字元編碼的支援,參見第10章:字元編碼支援

·         [NATIONAL] CHAR(M) [BINARY| ASCII | UNICODE]

固定長度字串,當保存時在右側填充空格以達到指定的長度。M資料表示列長度。M的範圍是0255個字元。

註釋:當檢索CHAR值時尾部空格被刪除。

如果想要將某個CHAR的長度設為大於255,執行的CREATE TABLEALTER TABLE語句將失敗並提示錯誤:

mysql> CREATE TABLE c1 (col1 INT, col2 CHAR(500));
ERROR 1074 (42000): Column length too big for column 'col' (max = 255); use BLOB or TEXT instead
mysql> SHOW CREATE TABLE c1;
ERROR 1146 (42S02): Table 'test.c1' doesn't exist

CHARCHARACTER的簡寫。NATIONAL CHAR(或其等效短形式NCHAR)是標準的定義CHAR列應使用 預設字元編碼的SQL方法。這在MySQL中為預設值。

BINARY屬性是指定列字元編碼的二元 校對規則的簡寫。排序和比較基於數值字元值。

列類型CHAR BYTECHAR BINARY的一個別名。這是為了保證相容性。

可以為CHAR指定ASCII屬性。它分配latin1字元編碼。

可以為CHAR指定UNICODE屬性。它分配ucs2字元編碼。

MySQL允許建立類型CHAR(0)的列。這主要用於必須有一個列但實際上不使用值的舊版本的應用程式相兼容。當您需要只能取兩個值的列時也很好:沒有定義為NOT NULL的一個CHAR(0)列只佔用一位,只可以取值NULL''(空字串)

·         CHAR

這是CHAR(1)的同義詞。

·         [NATIONAL] VARCHAR(M) [BINARY]

變長字串。M 資料表示最大列長度。M的範圍是065,535(VARCHAR的最大實際長度由最長的行的大小和使用的字元編碼確定。最大有效長度是65,532字節)

註釋:MySQL 5.1遵從標準SQL規範,並且不刪除VARCHAR值的尾部空格。

VARCHAR是字元VARYING的簡寫。

BINARY屬性是指定列的字元編碼的二元 校對規則的簡寫。排序和比較基於數值字元值。

VARCHAR保存時用一個字節或兩個字節長的前綴+數據。如果VARCHAR列聲明的長度大於255,長度前綴是兩個字節。

·         BINARY(M)

BINARY類型類似於CHAR類型,但保存二進制字節字串而不是非二進制字串。

·         VARBINARY(M)

VARBINARY類型類似於VARCHAR類型,但保存二進制字節字串而不是非二進制字串。

·         TINYBLOB

最大長度為255(281)字節的BLOB列。

·         TINYTEXT

最大長度為255(281)字元的TEXT列。

·         BLOB[(M)]

最大長度為65,535(2161)字節的BLOB列。

可以給出該類型的可選長度M。如果給出,則MySQL將列建立為最小的但足以容納M字節長的值的BLOB類型。

·         TEXT[(M)]

最大長度為65,535(2161)字元的TEXT列。

可以給出可選長度M。則MySQL將列建立為最小的但足以容納M字元長的值的TEXT類型。

·         MEDIUMBLOB

最大長度為16,777,215(2241)字節的BLOB列。

·         MEDIUMTEXT

最大長度為16,777,215(2241)字元的TEXT列。

·         LONGBLOB

最大長度為4,294,967,2954GB(2321)字節的BLOB列。LONGBLOB列的最大有效(允許的)長度取決於客戶端/伺服器協議中配置最大包大小和可用的內存。

·         LONGTEXT

最大長度為4,294,967,2954GB(2321)字元的TEXT列。LONGTEXT列的最大有效(允許的)長度取決於客戶端/伺服器協議中配置最大包大小和可用的內存。

·         ENUM('value1','value2',...)

枚舉類型。只能有一個值的字串,從值列'value1''value2'...NULL中或特殊 ''錯誤值中選出。ENUM列最多可以有65,535個截然不同的值。ENUM值在內部用整數資料表示。

·         SET('value1','value2',...)

一個設置。字串對象可以有零個或多個值,每個值必須來自列值'value1''value2'...SET列最多可以有64個成員。SET值在內部用整數資料表示。

11.2. 數值類型

MySQL支援所有標準SQL數值數據類型。這些類型包括嚴格數值數據類型(INTEGERSMALLINTDECIMALNUMERIC),以及近似數值數據類型(FLOATREALDOUBLE PRECISION)。關鍵字INTINTEGER的同義詞,關鍵字DECDECIMAL的同義詞。

BIT數據類型保存位元值,並且支援MyISAMMEMORYInnoDBBDB資料表。

作為SQL標準的延伸,MySQL也支援整數類型TINYINTMEDIUMINTBIGINT。下面的資料表顯示了需要的每個整數類型的儲存和範圍。

類型

字節

最小值

最大值

 

 

(帶符號的/無符號的)

(帶符號的/無符號的)

TINYINT

1

-128

127

 

 

0

255

SMALLINT

2

-32768

32767

 

 

0

65535

MEDIUMINT

3

-8388608

8388607

 

 

0

16777215

INT

4

-2147483648

2147483647

 

 

0

4294967295

BIGINT

8

-9223372036854775808

9223372036854775807

 

 

0

18446744073709551615

MySQL還支援選擇在該類型關鍵字後面的括號內指定整數值的顯示寬度(例如,INT(4))。該可選顯示寬度規定用於顯示寬度小於指定的列寬度的值時從左側填滿寬度。

顯示寬度並不限制可以在列內保存的值的範圍,也不限制超過列的指定寬度的值的顯示。

當結合可選延伸屬性ZEROFILL使用時, 預設補充的空格用零代替。例如,對於聲明為INT(5) ZEROFILL的列,值4檢索為00004。請注意如果在整數列保存超過顯示寬度的一個值,當MySQL為複雜聯接生成臨時資料表時會遇到問題,因為在這些情況下MySQL相信數據適合原列寬度。

所有整數類型可以有一個可選(非標準)屬性UNSIGNED。當您想要在列內只允許非負數和該列需要較大的上限數值範圍時可以使用無符號值。

浮點和定點類型也可以為UNSIGNED。同數類型,該屬性防止負值保存到列中。然而,與整數類型不同的是,列值的上範圍保持不變。

如果為一個數值列指定ZEROFILLMySQL自動為該列新增UNSIGNED屬性。

對於浮點列類型,在MySQL中單精度值使用4個字節,雙精度值使用8個字節。

FLOAT類型用於資料表示近似數值數據類型。SQL標準允許在關鍵字FLOAT後面的括號內選擇用位指定精度(但不能為指數範圍)MySQL還支援可選的只用於確定儲存大小的精度規定。023的精度對應FLOAT列的4字節單精度。2453的精度對應DOUBLE列的8字節雙精度。

MySQL允許使用非標準語法:FLOAT(M,D)REAL(M,D)DOUBLE PRECISION(M,D)。這裡,「(M,D)」資料表示該值一共顯示M位整數,其中D位位於小數點後面。例如,定義為FLOAT(7,4)的一個列可以顯示為-999.9999MySQL保存值時進行四捨五入,因此如果在FLOAT(7,4)列內插入999.00009,近似結果是999.0001

MySQLDOUBLE視為DOUBLE PRECISION(非標準延伸)的同義詞。MySQL還將REAL視為DOUBLE PRECISION(非標準延伸)的同義詞,除非SQL伺服器模式包括REAL_AS_FLOAT選項。

為了保證最大可能的可移植性,需要使用近似數值數據值儲存的代碼應使用FLOATDOUBLE PRECISION,不規定精度或位數。

DECIMALNUMERIC類型在MySQL中視為相同的類型。它們用於保存必須為確切精度的值,例如貨幣數據。當聲明該類型的列時,可以(並且通常要)指定精度和標度;例如:

salary DECIMAL(5,2)

在該例子中,5是精度,2是標度。精度資料表示保存值的主要位數,標度資料表示小數點後面可以保存的位數。

MySQL 5.1中以二進制格式保存DECIMALNUMERIC值。

標準SQL要求salary列能夠用5位整數位和兩位小數保存任何值。因此,在這種情況下可以保存在salary列的值的範圍是從-999.99999.99

在標準SQL中,語法DECIMAL(M)等價於DECIMAL(M,0)。同樣,語法DECIMAL等價於DECIMAL(M,0),可以通過計算確定M的值。在MySQL 5.1中支援DECIMALNUMERIC數據類型的變數形式。M預設值是10

DECIMALNUMERIC的最大位數是65,但具體的DECIMALNUMERIC列的實際範圍受具體列的精度或標度約束。如果此類列分配的值小數點後面的位數超過指定的標度允許的範圍,值被轉換為該標度。(具體操作與作業系統有關,但一般結果均被截取到允許的位數)

BIT數據類型可用來保存位元值。BIT(M)類型允許儲存M位值。M範圍為164

要指定位值,可以使用b'value'符。value是一個用01編寫的二進制值。例如,b'111'b'100000000'分別資料表示7128。參見9.1.5節,「位元值」

如果為BIT(M)列分配的值的長度小於M位,在值的左邊用0填充。例如,為BIT(6)列分配一個值b'101',其效果與分配b'000101'相同。

當要在一個數值列內保存一個超出該列允許範圍的值時,MySQL的操作取決於此時有效的SQL模式。如果模式未設置,MySQL將值裁剪到範圍的相應端點,並保存裁減好的值。但是,如果模式設置為traditional(「嚴格模式),超出範圍的值將被拒絕並提示錯誤,並且根據SQL標準插入會失敗。參見5.3.2節,「SQL伺服器模式」

如果INT列是UNSIGNED,列範圍的大小相同,但其端點會變為到04294967295。如果您試圖保存-99999999999999999999,以非嚴格模式保存到列中的值是04294967296

如果在浮點或定點列中分配的值超過指定(或預設)精度和標度規定的範圍,MySQL以非嚴格模式保存資料表示範圍相應端點的值。

MySQL沒有工作在嚴格模式時,對於ALTER TABLELOAD DATA INFILEUPDATE和多行INSERT語句,由於裁剪髮生的轉換將報告為警告。當MySQL工作在嚴格模式時,這些語句將失敗,並且部分或全部值不會插入或更改,取決於是否資料表為事務資料表和其它因素。詳情參見5.3.2節,「SQL伺服器模式」

11.3. 日期和時間類型

資料表示時間值的DATE和時間類型為DATETIMEDATETIMESTAMPTIMEYEAR。每個時間類型有一個有效值範圍和一個「」值,當指定不合法的MySQL不能資料表示的值時使用「」值。TIMESTAMP類型有專有的自動更新特性,將在後面描述。

如果試圖插入一個不合法的日期,MySQL將給出警告或錯誤。可以使用ALLOW_INVALID_DATES SQL模式讓MySQL接受某些日期,例如'1999-11-31'。當您想要保存一個「可能錯誤的」用戶已經在資料庫中指定(例如,以web形式)用於將來處理的值時很有用。在這種模式下,MySQL只驗證月範圍為從012,日範圍為從031。這些範圍可以包括零,因為MySQL允許在DATEDATETIME列保存日/月和日是零的日期。這在應用程式需要保存一個您不知道確切日期的生日時非常有用。在這種情況下,只需要將日期保存為'1999-00-00''1999-01-00'。如果保存此類日期,DATE_SUB()DATE_ADD等需要完整日期的函數不會得到正確的結果。(如果您不想在日期中出現零,可以使用NO_ZERO_IN_DATE SQL模式)

MySQL還允許將'0000-00-00'保存為「偽日期」(如果不使用NO_ZERO_DATE SQL模式)。這在某些情況下比使用NULL值更方便(並且數據和索引佔用的空間更小)

sql_mode系統變數設置為相應模式值,可以更確切您想讓MySQL支援哪種日期。參見5.3.2節,「SQL伺服器模式」

當使用日期和時間類型時應記住以下幾點:

·         MySQL以標準輸出格式檢索給定日期或時間類型的值,但它盡力解釋您指定的各種輸入值格式(例如,當您指定一個分配給或與日期或時間類型進行比較的值時)。只支援下面章節中描述的格式。期望您能提供有效值。如果您使用其它格式的值會發生意想不到的結果。

·         包含兩位年值的日期會令人模糊,因為世紀不知道。MySQL使用以下規則解釋兩位年值:

o        70-99範圍的年值轉換為1970-1999

o        00-69範圍的年值轉換為2000-2069

·         儘管MySQL嘗試解釋幾種格式的值,日期總是以年--日順序(例如,'98-09-04'),而不是其它地方常用的月--年或日--年順序(例如,'09-04-98''04-09-98')

·         如果值用於數值上下文中,MySQL自動將日期或時間類型的值轉換為數字,反之亦然。

·         MySQL遇到一個日期或時間類型的超出範圍或對於該類型不合法的值時(如本節開始所描述),它將該值轉換為該類的「」值。一個例外是超出範圍的TIME值被裁剪到TIME範圍的相應端點。

下面的資料表顯示了各類「」值的格式。請注意如果啟用NO_ZERO_DATE SQL模式,使用這些值會產生警告。

列類型

」值

DATETIME

'0000-00-00 00:00:00'

DATE

'0000-00-00'

TIMESTAMP

00000000000000

TIME

'00:00:00'

YEAR

0000

·         」值是特殊值,但您可以使用資料表內顯示的值顯式保存或引用它們。您也可以使用值'0'0來保存或引用,寫起來更容易。

·         MyODBC中使用的「」日期或時間值在MyODBC 2.50.12和以上版本中被自動轉換為NULL,因為ODBC不能處理此類值。

11.3.1. DATETIME、DATE和TIMESTAMP類型

DATETIMEDATETIMESTAMP類型是相關的。該節描述了它們的特徵,它們的相似點和不同點。

當您需要同時包含日期和時間訊息的值時則使用DATETIME類型。MySQL'YYYY-MM-DD HH:MM:SS'格式檢索和顯示DATETIME值。支援的範圍為'1000-01-01 00:00:00''9999-12-31 23:59:59'(支援」資料表示儘管先前的值可能工作,但沒有保證)

當您只需要日期值而不需要時間部分時應使用DATE類型。MySQL'YYYY-MM-DD'格式檢索和顯示DATE值。支援的範圍是'1000-01-01''9999-12-31'

TIMESTAMP列類型的屬性不固定,取決於MySQL版本和伺服器運行的SQL模式。這些屬性將在本節後面描述。

可以使用任何常見格式指定DATETIMEDATETIMESTAMP值:

·         'YYYY-MM-DD HH:MM:SS''YY-MM-DD HH:MM:SS'格式的字串。允許「不嚴格」語法:任何標點符都可以用做日期部分或時間部分之間的間割符。例如,'98-12-31 11:30:45''98.12.31 11+30+45''98/12/31 11*30*45''98@12@31 11^30^45'是等價的。

·         'YYYY-MM-DD''YY-MM-DD'格式的字串。這裡也允許使用「不嚴格的」語法。例如,'98-12-31''98.12.31''98/12/31''98@12@31'是等價的。

·         'YYYYMMDDHHMMSS''YYMMDDHHMMSS'格式的沒有間割符的字串,假定字串對於日期類型是有意義的。例如,'19970523091528''970523091528'被解釋為'1997-05-23 09:15:28',但'971122129015'是不合法的(它有一個沒有意義的分鐘部分),將變為'0000-00-00 00:00:00'

·         'YYYYMMDD''YYMMDD'格式的沒有間割符的字串,假定字串對於日期類型是有意義的。例如,'19970523''970523'被解釋為 '1997-05-23',但'971332'是不合法的(它有一個沒有意義的月和日部分),將變為'0000-00-00'

·         YYYYMMDDHHMMSSYYMMDDHHMMSS格式的數字,假定數字對於日期類型是有意義的。例如,19830905132800830905132800被解釋為 '1983-09-05 13:28:00'

·         YYYYMMDDYYMMDD格式的數字,假定數字對於日期類型是有意義的。例如,19830905830905被解釋為'1983-09-05'

·         函數返回的結果,其值適合DATETIMEDATE或者TIMESTAMP上下文,例如NOW()CURRENT_DATE

無效DATETIMEDATE或者TIMESTAMP值被轉換為相應類型的「」值('0000-00-00 00:00:00''0000-00-00'或者00000000000000)

對於包括日期部分間割符的字串值,如果日和月的值小於10,不需要指定兩位數。'1979-6-9''1979-06-09'是相同的。同樣,對於包括時間部分間割符的字串值,如果時、分和秒的值小於10,不需要指定兩位數。'1979-10-30 1:2:3''1979-10-30 01:02:03'相同。

數字值應為6812或者14位長。如果一個數值是814位長,則假定為YYYYMMDDYYYYMMDDHHMMSS格式,前4位數資料表示年。如果數字 是612位長,則假定為YYMMDDYYMMDDHHMMSS格式,前2位數資料表示年。其它數字被解釋為彷彿用零填充到了最近的長度。

指定為非限定符字串的值使用給定的長度進行解釋。如果字串為814字元長,前4位數資料表示年。否則,前2位數資料表示年。從左向右解釋字串內出現的各部分,以發現年、月、日、小時、分和秒值。這說明不應使用少於6字元的字串。例如,如果您指定'9903',認為它資料表示19993月,MySQL將在您的資料表內插入一個「」日期值。這是因為年和月值是9903,但日部分完全丟失,因此該值不是一個合法的日期。但是,可以明顯指定一個零值來代資料表缺少的月或日部分。例如,可以使用'990300'來插入值'1999-03-00'

在一定程度上,可以將一個日期類型的值分配給一個不同的日期類型。但是,值可能會更改或丟失一些訊息:

·         如果您為一個DATETIMETIMESTAMP對像分配一個DATE值,結果值的時間部分被設置為'00:00:00',因為DATE值未包含時間訊息。

·         如果您為一個DATE對像分配一個DATETIMETIMESTAMP值,結果值的時間部分被刪除,因為DATE值未包含時間訊息。

·         記住儘管可以使用相同的格式指定DATETIMEDATETIMESTAMP值,不同類型的值的範圍卻不同。例如,TIMESTAMP值不能早於1970或晚於2037。這說明一個日期,例如'1968-01-01',雖然對於DATETIMEDATE值是有效的,但對於TIMESTAMP值卻無效,如果分配給這樣一個對像將被轉換為0

當指定日期值時請注意某些問題:

·         指定為字串的值允許的非嚴格格式可能會欺騙。例如,值'10:11:12'由於『:』間割符看上去可能像時間值,但如果用於日期上下文值則被解釋為年'2010-11-12'。值'10:45:15'被轉換為'0000-00-00'因為'45'不是合法月。

·         在非嚴格模式,MySQL伺服器只對日期的合法性進行基本檢查:年、月和日的範圍分別是1000999900120031。任何包含超出這些範圍的部分的日期被轉換成'0000-00-00'。請注意仍然允許您保存非法日期,例如'2002-04-31'。要想確保不使用嚴格模式時日期有效,應檢查應用程式。

在嚴格模式,非法日期不被接受,並且不轉換。

詳細訊息參見5.3.2節,「SQL伺服器模式」

·         包含兩位年值的日期會令人模糊,因為世紀不知道。MySQL使用以下規則解釋兩位年值:

o        00-69範圍的年值轉換為2000-2069

o        70-99範圍的年值轉換為1970-1999

11.3.1.1. 自MySQL 4.1以來的TIMESTAMP屬性

註釋:舊版本的MySQL(4.1之前)TIMESTAMP列類型的屬性在許多方面於本節所描述的大大不同。如果您需要對舊的TIMESTAMP數據進行轉化以便在MySQL 5.1中工作,詳情請參見MySQL 4.1 參考手冊

TIMESTAMP列的顯示格式與DATETIME列相同。換句話說,顯示寬度固定在19字元,並且格式為YYYY-MM-DD HH:MM:SS

MySQL伺服器也可以以MAXDB模式運行。當伺服器以該模式運行時,TIMESTAMPDATETIME相等。也就是說,如果建立資料表時伺服器以MAXDB模式運行,TIMESTAMP列建立為DATETIME列。結果是,該列使用DATETIME顯示格式,有相同的值範圍,並且沒有自動對當前的日期和時間進行初始化或更新。

要想啟用MAXDB模式,在啟動伺服器時使用--sql-mode=MAXDB伺服器選項或在運行時通過設置全局sql_mode變數將SQL伺服器模式設置為MAXDB

mysql> SET GLOBAL sql_mode=MAXDB

客戶端可以按照下面方法讓伺服器為它的連接以MAXDB模式運行:

mysql> SET SESSION sql_mode=MAXDB;

 

MySQL不接受在日或月列包括一個零或包含非法日期值的時間戳值。該規則的唯一例外是特殊值'0000-00-00 00:00:00'

您可以非常靈便地確定什麼時候初始化和更新TIMESTAMP和對哪些列進行初始化和更新:

·         您可以將當前的時間戳指定為預設值和自動更新的值。但只能選擇一個,或者兩者都不選。(不可能一個列選擇一個行為而另一個列選擇另一個行為)

·         您可以指定哪個TIMESTAMP列自動初始化或更新為當前的日期和時間。不再需要為第1TIMESTAMP列。

請注意下面討論所訊息只適用於建立時未啟用MAXDB模式的資料表的TIMESTAMP列。(如上所述,MAXDB模式使列建立為DATETIME列)控制TIMESTAMP列的初始化和更新的規則如下所示:

·         如果一個資料表內的第1TIMESTAMP列指定為一個DEFAULT值,則不能忽略。 預設值可以為CURRENT_TIMESTAMP或常量日期和時間值。

·         DEFAULT NULL與第1TIMESTAMP 列的DEFAULT CURRENT_TIMESTAMP相同。對於其它TIMESTAMP列,DEFAULT NULL被視為DEFAULT 0

·         資料表內的任何一個TIMESTAMP列可以設置為自動初始化為當前時間戳和/或更新。

·         CREATE TABLE語句中,可以用下面的任何一種方式聲明第1TIMESTAMP列:

o        DEFAULT CURRENT_TIMESTAMPON UPDATE CURRENT_TIMESTAMP子句,列為預設值使用當前的時間戳,並且自動更新。

o        不使用DEFAULTON UPDATE子句,與DEFAULT CURRENT_TIMESTAMP ON UPDATECURRENT_TIMESTAMP相同。

o        DEFAULT CURRENT_TIMESTAMP子句不用ON UPDATE子句,列為預設值使用當前的時間戳但是不自動更新。

o        不用DEFAULT子句但用ON UPDATE CURRENT_TIMESTAMP子句,列有預設值0並自動更新。

o        用常量DEFAULT值,列有給出的 預設值。如果列有一個ON UPDATE CURRENT_TIMESTAMP子句,它自動更新,否則不。

換句話說,您可以為初始值和自動更新的值使用當前的時間戳,或者其中一個使用,或者兩個皆不使用。(例如,您可以指定ON UPDATE來啟用自動更新而不讓列自動初始化)

·         DEFAULTON UPDATE子句中可以使用CURRENT_TIMESTAMPCURRENT_TIMESTAMP()或者NOW()。它們均具有相同的效果。

兩個屬性的順序並不重要。如果一個TIMESTAMP列同時指定了DEFAULTON UPDATE,任何一個可以在另一個的前面。

例子,下面這些語句是等效的:

CREATE TABLE t (ts TIMESTAMP);
CREATE TABLE t (ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP
                             ON UPDATE CURRENT_TIMESTAMP);
CREATE TABLE t (ts TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
                             DEFAULT CURRENT_TIMESTAMP);

·         要為TIMESTAMP列而不是第1列指定自動預設或更新,必須通過將第1TIMESTAMP列顯式分配一個常量DEFAULT值來禁用自動初始化和更新。(例如,DEFAULT 0DEFAULT'2003-01-01 00:00:00')。然後,對於其它TIMESTAMP列,規則與第1TIMESTAMP列相同,例外情況是不能忽略DEFAULTON UPDATE子句。如果這樣做,則不會自動進行初始化或更新。

例如:下面這些語句是等效的:

CREATE TABLE t (
    ts1 TIMESTAMP DEFAULT 0,
    ts2 TIMESTAMP DEFAULT CURRENT_TIMESTAMP
                  ON UPDATE CURRENT_TIMESTAMP);
CREATE TABLE t (
    ts1 TIMESTAMP DEFAULT 0,
    ts2 TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
                  DEFAULT CURRENT_TIMESTAMP);

可以對每個連接設置當前的時區,相關描述參見5.10.8節,「MySQL伺服器時區支援」TIMESTAMP值以UTC格式保存,儲存時對當前的時區進行轉換,檢索時再轉換回當前的時區。只要時區設定值為常量,便可以得到保存時的值。如果保存一個TIMESTAMP值,應更改時區然後檢索該值,它與您保存的值不同。這是因為在兩個方向的轉換中沒有使用相同的時區。當前的時區可以用作time_zone系統變數的值。

可以在TIMESTAMP列的定義中包括NULL屬性以允許列包含NULL值。例如:

CREATE TABLE t
(
  ts1 TIMESTAMP NULL DEFAULT NULL,
  ts2 TIMESTAMP NULL DEFAULT 0,
  ts3 TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP
);

如果未指定NULL屬性,將列設置為NULL設置則會將它設置為當前的時間戳。請注意允許NULL值的TIMESTAMP列不會採用當前的時間戳,除非要麼其 預設值定義為CURRENT_TIMESTAMP,或者NOW()CURRENT_TIMESTAMP被插入到該列內。換句話說,只有使用如下定義建立,定義為 NULLTIMESTAMP列才會自動更新:

CREATE TABLE t (ts NULLDEFAULT CURRENT_TIMESTAMP)

否則-也就是說,如果使用NULL而不是DEFAULT TIMESTAMP來定義TIMESTAMP列,如下所示...

CREATE TABLE t1 (ts NULL DEFAULT NULL);
CREATE TABLE t2 (ts NULL DEFAULT '0000-00-00 00:00:00');

...則必須顯式插入一個對應當前日期和時間的值。例如:

INSERT INTO t1 VALUES (NOW());
INSERT INTO t2 VALUES (CURRENT_TIMESTAMP);

11.3.2. TIME類型

MySQL'HH:MM:SS'格式檢索和顯示TIME(或對於大的小時值採用'HHH:MM:SS'格式)TIME值的範圍可以從'-838:59:59''838:59:59'。小時部分會因此大的原因是TIME類型不僅可以用於資料表示一天的時間(必須小於24小時),還可能為某個事件過去的時間或兩個事件之間的時間間隔(可以大於24小時,或者甚至為負)

您可以用各種格式指定TIME值:

·         'D HH:MM:SS.fraction'格式的字串。還可以使用下面任何一種「非嚴格」語法:'HH:MM:SS.fraction''HH:MM:SS''HH:MM''D HH:MM:SS''D HH:MM''D HH''SS'。這裡D資料表示日,可以取034之間的值。請注意MySQL還不保存分數。

·         'HHMMSS'格式的沒有間割符的字串,假定是有意義的時間。例如,'101112'被理解為'10:11:12',但'109712'是不合法的(它有一個沒有意義的分鐘部分),將變為'00:00:00'

·         HHMMSS格式的數值,假定是有意義的時間。例如,101112被理解為'10:11:12'。下面格式也可以理解:SSMMSSHHMMSSHHMMSS.fraction。請注意MySQL還不保存分數。

·         函數返回的結果,其值適合TIME上下文,例如CURRENT_TIME

對於指定為包括時間部分間割符的字串的TIME值,如果時、分或者秒值小於10,則不需要指定兩位數。'8:3:2''08:03:02'相同。

TIME列分配簡寫值時應注意。沒有冒號,MySQL解釋值時假定最右邊的兩位資料表示秒。(MySQL解釋TIME值為過去的時間而不是當天的時間)例如,您可能認為'1112'1112資料表示'11:12:00'(11點過12),但MySQL將它們解釋為'00:11:12'(11分,12 )。同樣,'12'12 被解釋為 '00:00:12'。相反,TIME值中使用冒號則肯定被看作當天的時間。也就是說,'11:12'資料表示'11:12:00',而不是'00:11:12'

超出TIME範圍但合法的值被裁為範圍最接近的端點。例如,'-850:00:00''850:00:00'被轉換為'-838:59:59''838:59:59'

無效TIME值被轉換為'00:00:00'。請注意由於'00:00:00'本身是一個合法TIME值,只從資料表內保存的一個'00:00:00'值還不能說出原來的值是 '00:00:00'還是不合法的值。

11.3.3. YEAR類型

YEAR類型是一個單字節類型用於資料表示年。

MySQLYYYY格式檢索和顯示YEAR值。範圍是19012155

可以指定各種格式的YEAR值:

·         四位字串,範圍為'1901''2155'

·         四位數字,範圍為19012155

·         兩位字串,範圍為'00''99''00''69''70''99'範圍的值被轉換為2000206919701999範圍的YEAR值。

·         兩位整數,範圍為1991697099範圍的值被轉換為2001206919701999範圍的YEAR值。請注意兩位整數範圍與兩位字串範圍稍有不同,因為您不能直接將零指定為數字並將它解釋為2000。您必須將它指定為一個字串'0''00'或它被解釋為0000

·         函數返回的結果,其值適合YEAR上下文,例如NOW()

非法YEAR值被轉換為0000

11.3.4. Y2K事宜和日期類型

MySQL本身對於2000(Y2K)是安全的(參見1.4.5節,「2000年相容性」),但輸入給MySQL的值可能不安全。任何包含兩位年值的輸入都會令人模糊,因為世紀不知道。這些值必須解釋為四位形式,因為MySQL內部使用四位來保存年。

對於DATETIMEDATETIMESTAMPYEAR類型,MySQL使用以下規則解釋含模糊年值的日期:

·         00-69範圍的年值轉換為2000-2069

·         70-99範圍的年值轉換為1970-1999

請記住這些規則只是合理猜測數據值資料表示什麼。如果MySQL使用的啟發不能產生正確的值,您應提供包含四位年值的確切輸入。

ORDER BY可以正確排序有兩位年的TIMESTAMPYEAR值。

部分函數如MIN()MAX()TIMESTAMPYEAR轉換為一個數字。這說明使用有兩位年值的值,這些函數不能工作正確。在這種情況下的修復方法是將TIMESTAMPYEAR轉換為四位年格式或使用MIN(DATE_ADD(TIMESTAMP,INTERVAL 0 DAYS))

11.4. String類型

字串類型指CHARVARCHARBINARYVARBINARYBLOBTEXTENUMSET。該節描述了這些類型如何工作以及如何在查詢中使用這些類型。

11.4.1. CHAR和VARCHAR類型

CHARVARCHAR類型類似,但它們保存和檢索的方式不同。它們的最大長度和是否尾部空格被保留等方面也不同。在儲存或檢索過程中不進行大小寫轉換。

CHARVARCHAR類型聲明的長度資料表示您想要保存的最大字元數。例如,CHAR(30)可以佔用30個字元。

CHAR列的長度固定為建立資料表時聲明的長度。長度可以為從0255的任何值。當保存CHAR值時,在它們的右邊填充空格以達到指定的長度。當檢索到CHAR值時,尾部的空格被刪除掉。在儲存或檢索過程中不進行大小寫轉換。

VARCHAR列中的值為可變長字串。長度可以指定為065,535之間的值。(VARCHAR的最大有效長度由最大行大小和使用的字元編碼確定。整體最大長度是65,532字節)

CHAR對比,VARCHAR值保存時只保存需要的字元數,另加一個字節來記錄長度(如果列聲明的長度超過255,則使用兩個字節)

VARCHAR值保存時不進行填充。當值保存和檢索時尾部的空格仍保留,符合標準SQL

如果分配給CHARVARCHAR列的值超過列的最大長度,則對值進行裁剪以使其適合。如果被裁掉的字元不是空格,則會產生一條警告。如果裁剪非空格字元,則會造成錯誤(而不是警告)並通過使用嚴格SQL模式禁用值的插入。參見5.3.2節,「SQL伺服器模式」

下面的資料表顯示了將各種字串值保存到CHAR(4)VARCHAR(4)列後的結果,說明了CHARVARCHAR之間的差別:

CHAR(4)

儲存需求

VARCHAR(4)

儲存需求

''

'    '

4個字節

''

1個字節

'ab'

'ab  '

4個字節

'ab '

3個字節

'abcd'

'abcd'

4個字節

'abcd'

5個字節

'abcdefgh'

'abcd'

4個字節

'abcd'

5個字節

請注意上資料表中最後一行的值只適用不使用嚴格模式時;如果MySQL運行在嚴格模式,超過列長度不的值保存,並且會出現錯誤。

CHAR(4)VARCHAR(4)列檢索的值並不總是相同,因為檢索時從CHAR列刪除了尾部的空格。通過下面的例子說明該差別:

mysql> CREATE TABLE vc (v VARCHAR(4), c CHAR(4));
Query OK, 0 rows affected (0.02 sec)
 
mysql> INSERT INTO vc VALUES ('ab  ', 'ab  ');
Query OK, 1 row affected (0.00 sec)
 
mysql> SELECT CONCAT(v, '+'), CONCAT(c, '+') FROM vc;
+----------------+----------------+
| CONCAT(v, '+') | CONCAT(c, '+') |
+----------------+----------------+
| ab  +          | ab+            |
+----------------+----------------+
1 row in set (0.00 sec)

根據分配給列的字元編碼校對規則對CHARVARCHAR列中的值進行排序和比較。

請注意所有MySQL校對規則屬於PADSPACE類。這說明在MySQL中的所有CHARVARCHAR值比較時不需要考慮任何尾部空格。例如:

mysql> CREATE TABLE names (myname CHAR(10), yourname VARCHAR(10));
Query OK, 0 rows affected (0.09 sec)
 
mysql> INSERT INTO names VALUES ('Monty ', 'Monty ');
Query OK, 1 row affected (0.00 sec)
 
mysql> SELECT myname = 'Monty  ', yourname = 'Monty  ' FROM names;
+--------------------+----------------------+
| myname = 'Monty  ' | yourname = 'Monty  ' |
+--------------------+----------------------+
|                  1 |                    1 |
+--------------------+----------------------+
1 row in set (0.00 sec)

請注意所有MySQL版本均如此,並且它不受SQL伺服器模式的影響。

對於尾部填充字元被裁剪掉或比較時將它們忽視掉的情形,如果列的索引需要唯一的值,在列內插入一個只是填充字元數不同的值將會造成複製鍵值錯誤。

CHAR BYTECHAR BINARY的別名。這是為了保證相容性。

ASCII屬性為CHAR列分配latin1字元編碼。UNICODE屬性分配ucs2字元編碼。

11.4.2. BINARY和VARBINARY類型

BINARYVARBINARY類類似於CHARVARCHAR,不同的是它們包含二進制字串而不要非二進制字串。也就是說,它們包含字節字串而不是字元字串。這說明它們沒有字元編碼,並且排序和比較基於列值字節的數值值。

BINARYVARBINARY允許的最大長度一樣,如同CHARVARCHAR,不同的是BINARYVARBINARY的長度是字節長度而不是字元長度。

BINARYVARBINARY數據類型不同於CHAR BINARYVARCHAR BINARY數據類型。對於後一種類型,BINARY屬性不會將列視為二進制字串列。相反,它致使使用列字元編碼的二元 校對規則,並且列自身包含非二進制字元字串而不是二進制字節字串。例如CHAR(5) BINARY被視為CHAR(5) CHARACTER SET latin1 COLLATE latin1_bin,假定預設字元編碼是latin1。這不同於BINARY(5),它保存5字節二進制字串,沒有字元編碼或 校對規則。

當保存BINARY值時,在它們右邊填充值以達到指定長度。填充值是0x00(零字節)。插入值時在右側新增0x00 on,並且選擇時不刪除尾部的字節。比較時所有字節很重要,包括ORDER BYDISTINCT操作。比較時0x00字節和空格是不同的,0x00<空格。

例如:對於一個BINARY(3)列,當插入時 'a' 變為 'a \0''a\0'插入時變為'a\0\0'。當選擇時兩個插入的值均不更改。

對於VARBINARY,插入時不填充字元,選擇時不裁剪字節。比較時所有字節很重要,包括ORDER BYDISTINCT操作。比較時0x00字節和空格是不同的,0x00<空格。

對於尾部填充字元被裁剪掉或比較時將它們忽視掉的情形,如果列的索引需要唯一的值,在列內插入一個只是填充字元數不同的值將會造成複製鍵值錯誤。

如果您計劃使用這些數據類型來保存二進制數據並且需要檢索的值與保存的值完全相同,應考慮前面所述的填充和裁剪特徵。下面的例子說明了用0x00填充的BINARY值如何影響列值比較:

mysql> CREATE TABLE t (c BINARY(3));
Query OK, 0 rows affected (0.01 sec)
 
mysql> INSERT INTO t SET c = 'a';
Query OK, 1 row affected (0.01 sec)
 
mysql> SELECT HEX(c), c = 'a', c = 'a\0\0' from t;
+--------+---------+-------------+
| HEX(c) | c = 'a' | c = 'a\0\0' |
+--------+---------+-------------+
| 610000 |       0 |           1 |
+--------+---------+-------------+
1 row in set (0.09 sec)

如果檢索的值必須與指定進行儲存而沒有填充的值相同,最好使用BLOB數據類型。

建立資料表時,MySQL可以默默更改BINARYVARBINARY列的類型。參見13.1.5.1節,「沉寂的列規格變更」

11.4.3. BLOB和TEXT類型

BLOB是一個二進制大對象,可以容納可變數量的數據。有4BLOB類型:TINYBLOBBLOBMEDIUMBLOBLONGBLOB。它們只是可容納值的最大長度不同。

4TEXT類型:TINYTEXTTEXTMEDIUMTEXTLONGTEXT。這些對應4BLOB類型,有相同的最大長度和儲存需求。

參見11.5節,「列類型儲存需求」

BLOB 列被視為二進制字串(字節字串)TEXT列被視為非二進制字串(字元字串)BLOB列沒有字元編碼,並且排序和比較基於列值字節的數值值。TEXT列有一個字元編碼,並且根據字元編碼的 校對規則對值進行排序和比較。

TEXTBLOB列的儲存或檢索過程中,不存在大小寫轉換。

當未運行在嚴格模式時,如果您為BLOBTEXT列分配一個超過該列類型的最大長度的值值,值被截取以保證適合。如果截掉的字元不是空格,將會產生一條警告。使用嚴格SQL模式,會產生錯誤,並且值將被拒絕而不是截取並給出警告。參見5.3.2節,「SQL伺服器模式」

在大多數方面,可以將BLOB列視為能夠足夠大的VARBINARY列。同樣,可以將TEXT列視為VARCHAR列。BLOBTEXT在以下幾個方面不同於VARBINARYVARCHAR

·         當保存或檢索BLOBTEXT列的值時不刪除尾部空格。(這與VARBINARYVARCHAR列相同)

請注意比較時將用空格對TEXT進行擴充以適合比較的對象,正如CHARVARCHAR

·         對於BLOBTEXT列的索引,必須指定索引前綴的長度。對於CHARVARCHAR,前綴長度是可選的。參見7.4.3節,「列索引」

·         BLOBTEXT列不能有 預設值。

LONGLONG VARCHAR對應MEDIUMTEXT數據類型。這是為了保證相容性。如果TEXT列類型使用BINARY屬性,將為列分配列字元編碼的二元 校對規則。

MySQL連接程式/ODBCBLOB值定義為LONGVARBINARY,將TEXT值定義為LONGVARCHAR

由於BLOBTEXT值可能會非常長,使用它們時可能遇到一些約束:

·         當排序時只使用該列的前max_sort_length個字節。max_sort_length的 預設值是1024;該值可以在啟動mysqld伺服器時使用--max_sort_length選項進行更改。參見5.3.3節,「伺服器系統變數」

運行時增加max_sort_length的值可以在排序或組合時使更多的字節有意義。任何客戶端可以更改其會話max_sort_length變數的值:

mysql> SET max_sort_length = 2000;
mysql> SELECT id, comment FROM tbl_name
    -> ORDER BY comment;

當您想要使超過max_sort_length的字節有意義,對含長值的BLOBTEXT列使用GROUP BYORDER BY的另一種方式是將列值轉換為固定長度的對象。標準方法是使用SUBSTRING函數。例如,下面的語句對comment列的2000個字節進行排序:

mysql> SELECT id, SUBSTRING(comment,1,2000) FROM tbl_name
    -> ORDER BY SUBSTRING(comment,1,2000);

·         BLOBTEXT對象的最大大小由其類型確定,但在客戶端和伺服器之間實際可以傳遞的最大值由可用內存數量和通信緩存區大小確定。您可以通過更改max_allowed_packet變數的值更改消息緩存區的大小,但必須同時修改伺服器和客戶端程式。例如,可以使用 mysqlmysqldump來更改客戶端的max_allowed_packet值。參見7.5.2節,「調節伺服器參數」8.3節,「mysql:MySQL命令行工具」8.8節,「mysqldump:資料庫備份程式」

每個BLOBTEXT值分別由內部分配的對象資料表示。這與其它列類型形成對比,後者是當打開資料表時為每1列分配儲存引擎。

11.4.4. ENUM類型

ENUM是一個字串對象,其值來自資料表建立時在列規定中顯式枚舉的一列值。

在某些情況下,ENUM值也可以為空字串('')NULL

·         如果您將一個非法值插入ENUM(也就是說,允許的值列之外的字串),將插入空字串以作為特殊錯誤值。該字串與「普通」空字串不同,該字串有數值值0。後面有詳細討論。

·         如果將ENUM列聲明為允許NULLNULL值則為該列的一個有效值,並且 預設值為NULL。如果ENUM列被聲明為NOT NULL,其預設值為允許的值列的第1個元素。

每個枚舉值有一個索引:

·         來自列規定的允許的值列中的值從1開始編號。

·         空字串錯誤值的索引值是0。這說明您可以使用下面的SELECT語句來找出分配了非法ENUM值的行:

·                mysql> SELECT * FROM tbl_name WHERE enum_col=0;

·         NULL值的索引是NULL

例如,定義為ENUM的列('one''two''three')可以有下面所示任何值。還顯示了每個值的索引:

索引

NULL

NULL

''

0

'one'

1

'two'

2

'three'

3

枚舉最多可以有65,535個元素。

當建立資料表時,ENUM成員值的尾部空格將自動被刪除。

當檢索時,保存在ENUM列的值使用列定義中所使用的大小寫來顯示。請注意可以為ENUM列分配字元編碼和 校對規則。對於二進制或大小寫敏感的校對規則,當為列分配值時應考慮大小寫。

如果在數值上下文中檢索一個ENUM值,將返回列值的索引。例如,您可以這樣從ENUM列搜索數值值:

mysql> SELECT enum_col+0 FROM tbl_name;

如果將一個數字保存到ENUM列,數字被視為索引,並且保存的值是該索引對應的枚舉成員。(但是,這不適合LOAD DATA,它將所有輸入視為字串)不建議使用類似數字的枚舉值來定義一個ENUM列,因為這很容易引起混淆。例如,下面的列含有字串值'0''1''2'的枚舉成員,但數值索引值為123

numbers ENUM('0','1','2')

根據枚舉成員在列定義中列出的順序對ENUM值進行排序。(換句話說,ENUM值根據索引編號進行排序)例如,對於ENUM('a''b')'a'排在'b'前面,但對於ENUM('b''a')'b'排在'a'前面。空字串排在非空字串前面,並且NULL值排在所有其它枚舉值前面。要想防止意想不到的結果,按字母順序規定ENUM列。還可以使用GROUP BY  CAST(col AS CHAR)GROUP BY  CONCAT(col)來確保按照詞彙對列進行排序而不是用索引數字。

如果您想要確定一個ENUM列的所有可能的值,使用SHOW COLUMNS FROM tbl_name LIKE enum_col,並解析輸出中第2列的ENUM定義。

11.4.5. SET類型

SET是一個字串對象,可以有零或多個值,其值來自資料表建立時規定的允許的一列值。指定包括多個SET成員的SET列值時各成員之間用逗號(,)間隔開。這樣SET成員值本身不能包含逗號。

例如,指定為SET('one', 'two') NOT NULL的列可以有下面的任何值:

''
'one'
'two'
'one,two'

SET最多可以有64個不同的成員。

當建立資料表時,SET成員值的尾部空格將自動被刪除。

當檢索時,保存在SET列的值使用列定義中所使用的大小寫來顯示。請注意可以為SET列分配字元編碼和 校對規則。對於二進制或大小寫敏感的校對規則,當為列分配值時應考慮大小寫。

MySQL用數字保存SET值,所保存值的低階位對應第1SET成員。如果在數值上下文中檢索一個SET值,檢索的值的位設置對應組成列值的SET成員。例如,您可以這樣從一個SET列檢索數值值:

mysql> SELECT set_col+0 FROM tbl_name;

如果將一個數字保存到SET列中,數字中二進製表示中的位確定了列值中的SET成員。對於指定為SET('a','b','c','d')的列,成員有下面的十進制和二進制值:

SET成員

十進制值

二進制值

'a'

1

0001

'b'

2

0010

'c'

4

0100

'd'

8

1000

 

如果您為該列分配一個值9,其二進制形式為1001,因此第1個和第4SET值成員'a''d'被選擇,結果值為 'a,d'

對於包含多個SET元素的值,當插入值時元素所列的順序並不重要。在值中一個給定的元素列了多少次也不重要。當以後檢索該值時,值中的每個元素出現一次,根據資料表建立時指定的順序列出元素。例如,假定某個列指定為SET('a','b','c','d')

mysql> CREATE TABLE myset (col SET('a', 'b', 'c', 'd'));

插入值'a,d''d,a''a,d,d''a,d,a''d,a,d':

mysql> INSERT INTO myset (col) VALUES 
-> ('a,d'), ('d,a'), ('a,d,a'), ('a,d,d'), ('d,a,d');
Query OK, 5 rows affected (0.01 sec)
Records: 5  Duplicates: 0  Warnings: 0

當檢索時所有這些值顯示為 'a,d'

mysql> SELECT col FROM myset;
+------+
| col  |
+------+
| a,d  |
| a,d  |
| a,d  |
| a,d  |
| a,d  |
+------+
5 rows in set (0.04 sec)

如果將SET列設置為一個不支援的值,則該值被忽略並發出警告:

mysql> INSERT INTO myset (col) VALUES ('a,d,d,s');
Query OK, 1 row affected, 1 warning (0.03 sec)
 
mysql> SHOW WARNINGS;
+---------+------+------------------------------------------+
| Level   | Code | Message                                  |
+---------+------+------------------------------------------+
| Warning | 1265 | Data truncated for column 'col' at row 1 |
+---------+------+------------------------------------------+
1 row in set (0.04 sec)
 
mysql> SELECT col FROM myset;
+------+
| col  |
+------+
| a,d  |
| a,d  |
| a,d  |
| a,d  |
| a,d  |
| a,d  |
+------+
6 rows in set (0.01 sec)

SET值按數字順序排序。NULL值排在非NULL SET值的前面。

通常情況,可以使用FIND_IN_SET()函數或LIKE操作符搜索SET值:

mysql> SELECT * FROM tbl_name WHERE FIND_IN_SET('value',set_col)>0;
mysql> SELECT * FROM tbl_name WHERE set_col LIKE '%value%';

1個語句找出SET_col包含value set成員的行。第2個類似,但有所不同:它在其它地方找出set_col包含value的行,甚至是在另一個SET成員的子字串中。

下面的語句也是合法的:

mysql> SELECT * FROM tbl_name WHERE set_col & 1;
mysql> SELECT * FROM tbl_name WHERE set_col = 'val1,val2';

1個語句尋找包含第1set成員的值。第2個語句尋找一個確切匹配的值。應注意第2類的比較。將set值與'val1,val2'比較返回的結果與同'val2,val1'比較返回的結果不同。指定值時的順序應與在列定義中所列的順序相同。

如果想要為SET列確定所有可能的值,使用SHOW COLUMNS FROM tbl_name LIKE set_col並解析輸出中第2列的SET定義。

11.5. 列類型儲存需求

根據類別列出了MySQL支援的每個列類型的儲存需求。

MyISAM資料表中行的最大大小為65,534字節。每個BLOBTEXT列 帳號只佔其中的59個字節。

如果MyISAM資料表包括變長列類型,記錄格式也是可變長度。當建立資料表時,在某些條件下,MySQL可以將一個列從變長類型改為固定長度的類型或反之亦然。詳細訊息參見13.1.5.1節,「沉寂的列規格變更」

數值類型儲存需求

列類型

儲存需求

TINYINT

1個字節

SMALLINT

2個字節

MEDIUMINT

3個字節

INT, INTEGER

4個字節

BIGINT

8個字節

FLOAT(p)

如果0 <= p <= 244個字節, 如果25 <= p <= 538個字節

FLOAT

4個字節

DOUBLE [PRECISION], item REAL

8個字節

DECIMAL(M,D), NUMERIC(M,D)

變長;參見下面的討論

BIT(M)

大約(M+7)/8個字節

DECIMAL(NUMERIC)的儲存需求與具體版本有關:

使用二進制格式將9個十進制(基於10)數壓縮為4個字節來資料表示DECIMAL列值。每個值的整數和分數部分的儲存分別確定。每個9位數的倍數需要4個字節,並且「剩餘的」位需要4個字節的一部分。下資料表給出了超出位數的儲存需求:

剩餘的

字節

位數

數目

0

0

1

1

2

1

3

2

4

2

5

3

6

3

7

4

8

4

9

4

日期和時間類型的儲存需求

列類型

儲存需求

DATE

3個字節

DATETIME

8個字節

TIMESTAMP

4個字節

TIME

3個字節

YEAR

1個字節

字串類型的儲存需求

列類型

儲存需求

CHAR(M)

M個字節,0 <= M <= 255

VARCHAR(M)

L+1個字節,其中L <= M 0 <= M <= 65535(參見下面的註釋)

BINARY(M)

M個字節,0 <= M <= 255

VARBINARY(M)

L+1個字節,其中L <= M 0 <= M <= 255

TINYBLOB, TINYTEXT

L+1個字節,其中L < 28

BLOB, TEXT

L+2個字節,其中L < 216

MEDIUMBLOB, MEDIUMTEXT

L+3個字節,其中L < 224

LONGBLOB, LONGTEXT

L+4個字節,其中L < 232

ENUM('value1','value2',...)

12個字節,取決於枚舉值的個數(最多65,535個值)

SET('value1','value2',...)

1234或者8個字節,取決於set成員的數目(最多64個成員)

VARCHARBLOBTEXT類是變長類型。每個類型的儲存需求取決於列值的實際長度(用前面的資料表中的L資料表示),而不是該類型的最大可能的大小。例如,VARCHAR(10)列可以容納最大長度為10的字串。實際儲存需求是字串(L)的長度,加上一個記錄字串長度的字節。對於字串'abcd'L4,儲存需要5個字節。

對於CHARVARCHARTEXT類型,前面的資料表中的值LM應解釋為字元數目,並且列定義中的這些類型的長度資料表示字元數目。例如,要想保存一個TINYTEXT值需要L字元+ 1個字節。

要想計算用於保存具體CHARVARCHAR或者TEXT列值的字節數,需要考慮該列使用的字元編碼。在具體情況中,當使用Unicode時,必須記住所有Unicode字元使用相同的字節數。為了細分用於不同類Unicode字元使用的儲存,參見10.5節,「Unicode支援」

註釋:VARCHAR列的有效最大長度為65,532字元。

NDBCLUSTER引擎只支援固定寬度的列。這說明MySQL叢集中的資料表中的VARCHAR列的行為如同類型CHAR(不同的是每個記錄仍然有一個額外字節空間)。例如,在Cluster資料表中,聲明為VARCHAR(100)的列中的每個記錄儲存時將佔用101個字節,無論實際儲存的記錄中的字串的長度為多少。

BLOBTEXT類需要 123或者4個字節來記錄列值的長度,取決於該類的最大可能的長度。參見11.4.3節,「BLOB和TEXT類型

NDB Cluster儲存引擎中,TEXTBLOB列的實施是不同的,其中TEXT列中的每個記錄由兩個單獨部分組成。一個是固定大小(256字節),並且實際上保存在原資料表中。另一個包括超出256字節的任何數據,保存在隱含的資料表中。第2個資料表中的記錄總是2,000字節長。這說明如果size<= 256TEXT列的大小為256(其中size資料表示記錄的大小);否則,大小是256 +size+(2000(size256)%2000)

ENUM對象的大小由不同的枚舉值的數目確定。枚舉用一個字節,可以有255個可能的值。當枚舉的值位於25665,535之間時,用兩個字節。參見11.4.4節,「ENUM類型」

SET對象的大小由不同的set成員的數量確定。如果set大小是N,對像占(N+7)/8個字節,四捨五入到1234或者8個字節。SET最多可以有64個成員。參見11.4.5節,「SET類型」

11.6. 選擇正確的列類型

為了最佳化儲存,在任何情況下均應使用最精確的類型。例如,如果列的值的範圍為從199999,若使用整數,則MEDIUMINT UNSIGNED是好的類型。在所有可以資料表示該列值的類型中,該類型使用的儲存最少。

用精度為65位十進制數(基於10)DECIMAL 列進行所有基本計算(+-*/)。參見11.1.1節,「數值類型概述」

使用雙精度操作對DECIMAL值進行計算。如果準確度不是太重要或如果速度為最高優先級,DOUBLE類型即足夠了。為了達到高精度,可以轉換到保存在BIGINT中的定點類型。這樣可以用64位整數進行所有計算,根據需要將結果轉換回浮點值。

11.7. 使用來自其他資料庫引擎的列類型

為了使用由其它賣方編寫的SQL執行代碼,MySQL按照下資料表所示對列類型進行映射。通過這些映射,可以很容易地從其它資料庫引擎將資料表定義導入到MySQL中:

其它賣方類型

MySQL類型

BOOL,

TINYINT

BOOLEAN

TINYINT

CHAR VARYING(M)

VARCHAR(M)

DEC

DECIMAL

FIXED

DECIMAL

FLOAT4

FLOAT

FLOAT8

DOUBLE

INT1

TINYINT

INT2

SMALLINT

INT3

MEDIUMINT

INT4

INT

INT8

BIGINT

LONG VARBINARY

MEDIUMBLOB

LONG VARCHAR

MEDIUMTEXT

LONG

MEDIUMTEXT

MIDDLEINT

MEDIUMINT

NUMERIC

DECIMAL

在建立資料表時對列類型進行映射,然後原來的類型定義被丟棄。如果您使用其它賣方的類型建立一個資料表,然後執行DESCRIBE tbl_name語句,MySQL使用等效的MySQL類型來報告資料表的結構。例如:

mysql> CREATE TABLE t (a BOOL, b FLOAT8, c LONG, d NUMERIC);
Query OK, 0 rows affected (0.08 sec)
 
mysql> DESCRIBE t;
+-------+---------------+------+-----+---------+-------+
| Field | Type          | Null | Key | Default | Extra |
+-------+---------------+------+-----+---------+-------+
| a     | tinyint(1)    | YES  |     | NULL    |       |
| b     | double        | YES  |     | NULL    |       |
| c     | mediumtext    | YES  |     | NULL    |       |
| d     | decimal(10,0) | YES  |     | NULL    |       |
+-------+---------------+------+-----+---------+-------+
4 rows in set (0.00 sec)

這是MySQL參考手冊的翻譯版本,關於MySQL參考手冊,請訪問dev.mysql.com。 原始參考手冊為英文版,與英文版參考手冊相比,本翻譯版可能不是最新的。