首頁  >  文章  >  資料庫  >  MySQL學習系列3:資料類型

MySQL學習系列3:資料類型

黄舟
黄舟原創
2016-12-28 17:38:312677瀏覽

MYSQL裡的BLOB資料型別

BLOB是一個二元大對象,用來儲存可變數量的資料。 BLOB類型分為4種:TinyBlob、Blob、MediumBlob、LongBlob,

這幾種類型之間的唯一區別是在儲存檔案的最大大小上不同。

MySQL的四種BLOB類型類型(單位:位元組)

TinyBlob 最大255

Blob 最大65K

MediumBlob 最大16M

LongBlob 位元組的原始字元串);TEXT列儲存的是非二進位字串(字元字串)。

BLOB列沒有字元集,並且排序和比較基於列值位元組的數值;TEXT列有一個字元集,並且根據字元集對值進行排序和比較

BLOB是二進位字串,TEXT是非二進位字串,兩者均可存放大容量的資訊。 BLOB主要儲存圖片、音訊資訊等,

而TEXT只能儲存文字檔案。

SQLSERVER

SQLSERVER並沒有BLOB資料型,只有大型物件資料型態(BLOB):

text,ntext,image,nvarchar(max),varchar(max),varbinary(max)和xml資料型別

這些資料類型的資料都存放在LOB類型的資料頁



列類型


11.1.1. 數值類型概述

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

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

如果為一個數值欄位指定ZEROFILL,MySQL自動為該欄位新增UNSIGNED屬性。

SERIAL是BIGINT UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE的別名。

在整數列定義中,SERIAL DEFAULT VALUE是NOT NULL AUTO_INCREMENT UNIQUE的別名。

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

· BIT[(M)]

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

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

很小的整數。帶符號的範圍是-128到127。無符號的範圍是0到255。

· BOOL,BOOLEAN

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

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

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

小的整數。帶符號的範圍是-32768到32767。無符號的範圍是0到65535。

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

中等大小的整數。帶符號的範圍是-8388608到8388607。無符號的範圍是0到16777215。

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

普通大小的整數。帶符號的範圍是-2147483648到2147483647。無符號的範圍是0到4294967295。

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

這是INT的同義詞。

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

大整數。帶符號的範圍是-9223372036854775808到9223372036854775807。無符號的範圍是0到18446744073709551615。

應清楚BIGINT列的下述內容:

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

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

§ 當使用整數在一個BIGINT欄位中保存大的無符號的值。

§ 在MIN(col_name)或MAX(col_name)中,其中col_name指BIGINT欄位。

§ 使用運算子(+,-,*等等)且兩個運算元均為整數時。

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

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

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

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

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

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

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

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

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

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

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

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

為DOUBLE的同義字。除了:如果SQL伺服器模式包含REAL_AS_FLOAT選項,REAL是FLOAT的同義詞而不是DOUBLE的同義詞。

· FLOAT(p) [UNSIGNED] [ZEROFILL]

浮點數。 p表示精確度(以位數表示),但MySQL只使用該值來決定是否結果列的資料類型為FLOAT或DOUBLE。若p為從0到24,資料型別變成沒有M或D值的FLOAT。如果p為從25到53,資料型別變成沒有M或D值的DOUBLE。結果列範圍與本節前面所描述的單精度FLOAT或雙精度DOUBLE資料類型相同。

FLOAT(p)語法與ODBC相容。

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

壓縮的「嚴格」定點數。 M是小數位數(精度)的總數,D是小數點(標度)後面的位數。小數點和(負數)的‘-’符號不包括在M中。如果D是0,則數值沒有小數點或分數部分。 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])] [UNSIGNEDED] [ZEROFILL], FIXED[(M[,D])] [UNSIGNEDED] [ZEROFILL], FIXED[(M[,D])] [UNSIGNEDED] [ZEROFILL], FIXED[(M[,D])] [UNSIGNEDED] [ZEROFILL], FIXED[(M[,D])] [UNSIGNEDED] [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欄位用於INSERT或UPDATE操作時記錄日期和時間。如果你不分配一個值,表中的第一個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)]

兩位或四位數格式的年。預設是四位數格式。在四位格式中,允許的值是1901到2155和0000。在兩位格式中,允許的值是70到69,表示從1970年到2069年。 MySQL以YYYY 格式顯示YEAR值,但允許使用字串或數字為YEAR列指派值。


11.1.3. 字串類型概述

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

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

MySQL 5.1字串資料類型包含部分在MySQL 4.1之前的版本中沒有的特性:

· 許多字串資料類型的列定義可以包括指定字元集的CHARACTER SET屬性,也可能包含校對規則。 (CHARSET是CHARACTER SET的同義字)。這些屬性適用於CHAR、VARCHAR、TEXT型別、ENUM和SET。例如:

該表定義創建了一個名為c1的列,具有一個utf8字符集和該字符集的默認校對規則,和一個名為c2的列以及latin1字符集和該字符集的二元校對規則。二元校對規則對大小寫不敏感。

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

· 對於CHAR、VARCHAR和TEXT類型,BINARY屬性可以為列指派該列字元集的 校對規則。

· 字元列的排序和比較是基於分配給列的字元集。在先前的版本中,排序和比較基於伺服器字元集的校對規則。對於CHAR和VARCHAR 資料列,你可以用BINARY屬性宣告欄位讓排序和 校對規則使用目前的字元代碼值而不是詞彙順序。

關於MySQL 5.1中字符集的支持,請參閱第10章:字符集支持。

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

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

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

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

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

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

欄位類型CHAR BYTE是CHAR BINARY的一個別名。這是為了保證相容性。

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

可以為CHAR指定UNICODE屬性。它分配ucs2字符集。

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

· CHAR

這是CHAR(1)的同義詞。由最長的行的大小和使用的字元集決定。簡寫。列宣告的長度大於255,長度前綴是兩個位元組。 M)

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

最大長度為255(28–1)字元的TEXT欄位。

· BLOB[(M)]

最大長度為65,535(216–1)位元組的BLOB欄位。可選長度M。字元的TEXT欄位。位元組的BLOB欄位。列的最大有效(允許的)長度取決於客戶端/伺服器協定中配置最大包大小和可用的記憶體。的最大有效(允許的)長度取決於客戶端/伺服器協定中配置最大包大小和可用的記憶體。

· ENUM(‘value1‘,’value2‘,…)

枚舉型別。只能有一個值的字串,從值列'value1','value2',…,NULL中或特殊”錯誤值中選出。ENUM列最多可以有65,535個截然不同的值。ENUM值在內部用整數表示。 …SET欄位最多可以有64個成員。和NUMERIC),以及近似數值資料類型(FLOAT、REAL和DOUBLE PRECISION)。 InnoDB和BDB表。

(帶符號的/無符號的)    (帶符號的/無符號的)    

TINYINT    1    -128    2    -32768    32767    

0    65535    

MEDIUMINT    3    -838608  
0    16777215    

INT    4    -2147483648    2147483647    
5099   8    -9223372036854775808    9223372036854775807    

0    184467440737

0    184467440737

0    184467441375

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

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

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

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

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

如果為一個數值欄位指定ZEROFILL,MySQL自動為該欄位新增UNSIGNED屬性。

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

FLOAT類型用來表示近似數值資料型態。 SQL標準允許在關鍵字FLOAT後面的括號內選擇用位元指定精確度(但不能為指數範圍)。 MySQL也支援可選的只用於決定儲存大小的精度規定。 0到23的精度對應FLOAT列的4位元組單精度。 24到53的精度對應DOUBLE列的8位元組雙精度。

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

MySQL將DOUBLE視為DOUBLE PRECISION(非標準擴充)的同義詞。 MySQL也將REAL視為DOUBLE PRECISION(非標準擴充)的同義詞,除非SQL伺服器模式包含REAL_AS_FLOAT選項。

為了確保最大可能的可攜性,需要使用近似數值資料值儲存的程式碼應使用FLOAT或DOUBLE PRECISION,不規定精確度或位數。

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

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

在MySQL 5.1中以二進位格式儲存DECIMAL和NUMERIC值。

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

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

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

BIT資料型別可用於保存位元欄位值。 BIT(M)類型允許儲存M位元值。 M範圍為1到64。

要指定位值,可以使用b’value‘符。 value是一個用0和1寫的二進位值。例如,b’111′和b’100000000′分別表示7和128。參見9.1.5節,「位元字段值」。

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

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

如果INT欄位是UNSIGNED,則列範圍的大小相同,但其端點會變成0和4294967295。如果你試圖保存-9999999999和9999999999,以非嚴格模式保存到列中的值是0和4294967296。

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

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


11.3. 日期和時間類型

11.3.1. DATETIME、DATE和TIMESTAMP類型11.3.2. TIME類型11.3.3. YEAR類型11.3.4. Y2K事宜和日期類型

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

如果試圖插入一個不合法的日期,MySQL將給予警告或錯誤。可以使用ALLOW_INVALID_DATES SQL模式讓MySQL接受某些日期,例如’1999-11-31′。當你想要保存一個「可能錯誤的」使用者已經在資料庫中指定(例如,以web形式)用於將來處理的值時很有用。在這種模式下,MySQL只驗證月範圍為從0到12,日範圍為從0到31。這些範圍可以包括零,因為MySQL允許在DATE或DATETIME列保存日/月和日是零的日期。這在應用程式需要保存一個你不知道確切日期的生日時非常有用。在這種情況下,只需要將日期保存為’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′    EST

 00000000000000    

TIME    '00:00:00′    

YEAR    0000    

· 「零」值是特殊值,但你可以使用表內顯示的值明確保存或引用它們。你也可以使用值’0′或0來保存或引用,寫起來更容易。

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




11.3.1. DATETIME、DATE和TIMESTAMP型

11.3.1.1.
自MySQL 4.1以來的TIMESTAMP屬性

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

當你需要同時包含日期和時間資訊的值時則使用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模式。這些屬性將在本節後面描述。

可以使用任何常見格式指定DATETIME、DATE和TIMESTAMP值:

· ’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′是不合法的(它有一個沒有意義的分鐘部分),將變為' 00-00 00:00:00′。

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

· YYYYMMDDHHMMSS或YYMMDDHHMMSS格式的數字,假設數字對於日期類型是有意義的。例如,19830905132800和830905132800被解釋為 ’1983-09-05 13:28:00′。

· YYYYMMDD或YYMMDD格式的數字,假設數字對於日期類型是有意義的。例如,19830905和830905被解釋為’1983-09-05′。

· 函數傳回的結果,其值適合DATETIME、DATE或TIMESTAMP上下文,例如NOW()或CURRENT_DATE。

無效DATETIME、DATE或TIMESTAMP值轉換為對應類型的「零」值(’0000-00-00 00:00:00′、’0000-00-00′或000000000000000)。

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

數字值應為6、8、12或14位長。若一個數值是8或14位長,則假定為YYYYMMDD或YYYYMMDDHHMMSS格式,前4位數表示年。若數字 是6或12位長,則假定為YYMMDD或YYMMDDHHMMSS格式,前2位數表示年。其它數字被解釋為彷彿用零填充到了最近的長度。

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

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

· 如果你為一個DATETIME或TIMESTAMP物件分配一個DATE值,結果值的時間部分被設定為'00:00:00′,因為DATE值未包含時間信息。

· 如果你為一個DATE物件分配一個DATETIME或TIMESTAMP值,結果值的時間部分被刪除,因為DATE值未包含時間資訊。

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

當指定日期值時請注意某些缺陷:

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

· 在非嚴格模式,MySQL伺服器只對日期的合法性進行基本檢查:年、月和日的範圍分別是1000到9999、00到12和00到31。任何包含超出這些範圍的部分的日期被轉換成’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模式運作。當伺服器以該模式運作時,TIMESTAMP與DATETIME相等。也就是說,如果建立表時伺服器以MAXDB模式運行,TIMESTAMP列會建立為DATETIME列。結果是,該欄位使用DATETIME顯示格式,具有相同的值範圍,並且沒有自動初始化或更新目前的日期和時間。

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

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

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

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

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

· 你可以指定哪個TIMESTAMP欄位會自動初始化或更新為目前的日期和時間。不再需要為第1個TIMESTAMP欄位。

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

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

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

· 表內的任何一個TIMESTAMP欄位可以設定為自動初始化為目前時間戳記和/或更新。

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

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

o 不使用DEFAULT或ON 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來啟用自動更新而不讓列自動初始化)。

· 在DEFAULT和ON UPDATE子句中可以使用CURRENT_TIMESTAMP、CURRENT_TIMESTAMP()或NOW()。它們均具有相同的效果。

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

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

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

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

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

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

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

否則-也就是說,如果使用NULL而不是DEFAULT TIMESTAMP來定義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表示日,可以取0到34之間的數值。請注意MySQL還不儲存分數。

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

· HHMMSS格式的數值,假設是有意義的時間。例如,101112被理解為’10:11:12′。以下格式也可以理解:SS、MMSS、HHMMSS、HHMMSS.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類型是一個單字元類型用來表示年。

MySQL以YYYY格式擷取並顯示YEAR值。範圍是1901到2155。

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

· 四位字串,範圍為’1901′到’2155′。

· 四位數字,範圍為1901到2155。

· 兩位字串,範圍為’00′到’99′。 ’00′到’69′和’70′到’99′範圍的值被轉換為2000到2069和1970到1999範圍的YEAR值。

· 兩位整數,範圍為1到99。1到69和70到99範圍的值被轉換為2001到2069和1970到1999範圍的YEAR值。請注意兩位整數範圍與兩位字串範圍稍有不同,因為你不能直接將零指定為數字並將它解釋為2000。你必須將它指定為一個字串’0′或’00′或它被解釋為0000。

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

非法YEAR值被轉換為0000。


11.3.4. Y2K事宜和日期類型

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

對於DATETIME、DATE、TIMESTAMP和YEAR類型,MySQL使用以下規則解釋含模糊年值的日期:

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

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

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

ORDER BY可以正確排序有兩位數年的TIMESTAMP或YEAR值。

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


11.4. String類型

11.4.1. CHAR和VARCHAR類型11.4.2.
BINARY和VARBINARY類型11.4.3. BLOB和TEXT類型
11.4.3.字串類型指CHAR、VARCHAR、BINARY、VARBINARY、BLOB、TEXT、ENUM和SET。該節描述了這些類型如何運作以及如何在查詢中使用這些類型。


11.4.1. CHAR和VARCHAR類型


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

CHAR和VARCHAR類型聲明的長度表示你想要儲存的最大字元數。例如,CHAR(30)可以佔用30個字元。

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

VARCHAR欄位中的值為可變長字串。長度可以指定為0到65,535之間的值。 (VARCHAR的最大有效長度由最大行大小和使用的字元集決定。整體最大長度是65,532位元組)。

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

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

如果指派給CHAR或VARCHAR資料列的值超過欄位的最大長度,則會將數值裁切以使其適合。如果被裁掉的字元不是空格,則會產生一則警告。如果裁剪非空格字符,則會造成錯誤(而不是警告)並透過使用嚴格SQL模式來停用值的插入。參見5.3.2節,「SQL伺服器模式」。

下面的表格顯示了儲存各種字串值到CHAR(4)和VARCHAR(4)欄位後的結果,說明了CHAR和VARCHAR之間的差異:


值   CHAR(4)    儲存需求(4)    儲存需求   

」    ' '    4個位元組   ”    1個位元組   

'

'abcd'    'abcd'    4個位元組'abcd'    5個位元組   

'abcdefgh'    'abcd'    4個字節   'abcd'    5個字節  

請注意上表中最後一行嚴格使用時執行不嚴格執行時所使用的固定模式;模式,超過列長度不的值不保存,並且會出現錯誤。

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



根據分配給列的字元集校對規則對CHAR和VARCHAR欄位中的值進行排序和比較。

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

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

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

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

ASCII屬性為CHAR列指派latin1字元集。 UNICODE屬性分配ucs2字元集。


11.4.2. BINARY和VARBINARY類型

BINARY和VARBINARY類別類似於CHAR和VARCHAR,不同的是它們包含二進位字串而不要非二進位字串。也就是說,它們包含位元組字串而不是字元字串。這說明它們沒有字元集,並且排序和比較基於列值位元組的數值值。

BINARY和VARBINARY允許的最大長度一樣,如同CHAR和VARCHAR,不同的是BINARY和VARBINARY的長度是位元組長度而不是字元長度。

BINARY和VARBINARY資料型別不同於CHAR BINARY和VARCHAR BINARY資料型態。對於後一種類型,BINARY屬性不會將列視為二進位字串列。相反,它致使使用列字元集的二元 校對規則,並且列本身包含非二進位字元字串而不是二進位位元組字串。例如CHAR(5) BINARY被視為CHAR(5) CHARACTER SET latin1 COLLATE latin1_bin,假定預設字元集是latin1。這不同於BINARY(5),它保存5位元組二進位字串,沒有字元集或 校對規則。

當保存BINARY值時,在它們右邊填充值以達到指定長度。填充值是0×00(零位元組)。插入值時在右側新增0×00 on,並且選擇時不刪除尾部的位元組。比較時所有位元組很重要,包括ORDER BY和DISTINCT運算。比較時0×00位元組和空格是不同的,0×00
例如:對於一個BINARY(3)列,當插入時 ’a' 變為 ’a ’。 ’a'插入時變為’a'。選擇時兩個插入的值均不更改。

對於VARBINARY,插入時不填充字符,選擇時不裁剪位元組。比較時所有位元組很重要,包括ORDER BY和DISTINCT運算。比較時0×00位元組和空格是不同的,0×00
對於尾部填充字元被裁剪掉或比較時將它們忽略掉的情形,如果列的索引需要唯一的值,在列內插入一個只是填充字元數不同的值將會造成複製鍵值錯誤。

如果你打算使用這些資料類型來保存二進位資料並且需要檢索的值與保存的值完全相同,應考慮前面所述的填充和裁剪特徵。下面的例子說明了0×00填滿的BINARY值如何影響列值比較:

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

建立表格時,MySQL可以默默更改BINARY或VARBINARY欄位的類型。參見13.1.5.1節,「沉寂的列規格變更」。


11.4.3. BLOB和TEXT型

BLOB是一個二進位大對象,可以容納可變數量的資料。有4種BLOB類型:TINYBLOB、BLOB、MEDIUMBLOB和LONGBLOB。它們只是可容納值的最大長度不同。

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

請參閱11.5節,「列類型儲存需求」。

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

在TEXT或BLOB欄位的儲存或擷取過程中,不存在大小寫轉換。

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

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

· 當儲存或擷取BLOB和TEXT列的值時不刪除尾部空格。 (這與VARBINARY和VARCHAR列相同)。

請注意比較時將以空格擴充TEXT以適合比較的對象,如CHAR和VARCHAR。

· 對於BLOB和TEXT列的索引,必須指定索引前綴的長度。對於CHAR和VARCHAR,前綴長度是可選的。參見7.4.3節,「列索引」。

· BLOB和TEXT欄位不能有 預設值。

LONG和LONG VARCHAR對應MEDIUMTEXT資料類型。這是為了保證相容性。如果TEXT列類型使用BINARY屬性,將為列指派列字元集的二元 校對規則。

MySQL連線程式/ODBC將BLOB值定義為LONGVARBINARY,將TEXT值定義為LONGVARCHAR。

由於BLOB和TEXT值可能會非常長,使用它們時可能會遇到一些限制:

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

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

當你想要讓超過max_sort_length的位元組有意義,對含長值的BLOB或TEXT一種方式是將列值轉換為固定長度的物件。標準方法是使用SUBSTRING函數。例如,下面的語句對comment列的2000個位元組進行排序:

· BLOB或TEXT物件的最大大小由其類型決定,但在客戶端和伺服器之間實際可以傳遞的最大值由可用記憶體數量和通訊快取區大小決定。你可以透過更改max_allowed_pa​​cket變數的值來更改訊息快取區的大小,但必須同時修改伺服器和客戶端程式。例如,可以使用 mysql和mysqldump來變更客戶端的max_allowed_pa​​cket值。請參閱7.5.2節,「調節伺服器參數」、8.3節,「mysql:MySQL命令列工具」和8.8節,「mysqldump:資料庫備份程式」。

每個BLOB或TEXT值分別由內部分配的物件表示。這與其它列類型形成對比,後者是當開啟表時為每1列分配儲存引擎。


11.4.4. ENUM類型

ENUM是一個字串對象,其值來自表格建立時在列規定中明確列舉的一列值。

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

· 如果你將一個非法值插入ENUM(也就是說,允許的值列之外的字串),將插入空字串以作為特殊錯誤值。為該列的一個有效值,並且預設值為NULL。 · 來自列規定的允許的值列中的值從1開始編號。 :





· NULL值的索引是NULL。數值的指標:


值   索引   

NULL    NULL    

」    0    


”    0    🠎

'three'    3    

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

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

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

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

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

根據枚舉成員在列定義中列出的順序對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的欄位可以有下面的任何值:

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

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

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

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

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

SET成員   十進位值   二進位值  

'b'    2    0010    

'c'    4    0100    

'd'    0100    

 001,因此第1個和第4個SET值成員' a'和'd'被選擇,結果值為'a,d'。

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





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



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



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



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

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





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

下面的語句也是合法的:





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

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


11.5. 列類型儲存需求

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

MyISAM表中行的最大大小為65,534位元組。每個BLOB和TEXT列 帳戶只佔其中的5至9個位元組。

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

數值類型儲存需求

欄位類型   儲存需求   

TINYINT    1個位元組   

 

INT, INTEGER    4個位元組   

BIGINT    8個位元組

FLOAT(p)    如果0

FLOAT    4個位元組   

FLOAT    4個位元組   

FLOAT    4個位元組位元組   

DECIMAL(M,D), NUMERIC(M,D)    變長;請參閱下方的討論   

BIT(M)    儲存需求與特定版本有關:

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


剩餘的   位元組   

位數   數目   

0      

3    2    

4    2    

5    3    

6    3    

7    4    

8    4    

9    

DATE    3個位元組   

DATETIME    8個位元組   

TIMESTAMP    4個位元組   

TIMESTAMP    4個位元組節   

TIME    3個位元組   

YEAR    1個位元組   

字串類型的儲存需求

= 255    

VARCHAR(M)    L+1個位元組,其中L

BINARY(M)    M個位元組,0

TINYBLOB, TINYTEXT    L+1個位元組,其中L

MEDIUMBLOB, MEDIUMTEXT    L+3個字節,其中L

LONGBLOB, LONGTEXT      

LONGBLOB, LONGTEXT      

LONGBLOB, LONGTEXT    ue2', …)    1或2個位元組,取決於枚舉值的個數(最多65,535個值)    

SET('value1','value2',…)    1、2、3、4或8個位元組,取決於set成員的數目(最多64個成員)    

VARCHAR、BLOB和TEXT類別是變長型。每個類型的儲存需求取決於列值的實際長度(用前面的表中的L表示),而不是該類型的最大可能的大小。例如,VARCHAR(10)欄位可以容納最大長度為10的字串。實際儲存需求是字串(L)的長度,加上一個記錄字串長度的位元組。對於字串’abcd’,L是4,儲存需要5個位元組。

對於CHAR、VARCHAR和TEXT類型,前面的表格中的值L和M應解釋為字元數目,並且列定義中的這些類型的長度表示字元數目。例如,要想保存一個TINYTEXT值需要L字元+
1個位元組。

要想計算用來保存具體CHAR、VARCHAR或TEXT列值的位元組數,需要考慮該列所使用的字元集。在具體情況中,當使用Unicode時,必須記住所有Unicode字元使用相同的位元組數。為了細分用於不同類別Unicode字元使用的存儲,請參閱10.5節,「Unicode支援」。

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

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

BLOB和TEXT類別需要 1、2、3或4個位元組來記錄列值的長度,取決於該類別的最大可能的長度。請參閱11.4.3節,「BLOB和TEXT類型
」。

在NDB Cluster儲存引擎中,TEXT和BLOB列的實作是不同的,其中TEXT列中的每個記錄由兩個單獨部分組成。一個是固定大小(256位元組),並且實際上保存在原始表中。另一個包括超出256位元組的任何數據,保存在隱含的表中。第2個表中的記錄總是2,000位元組長。這說明如果size+size+(2000–(size–256)%2000)。

ENUM物件的大小由不同的枚舉值的數目決定。枚舉用一個字節,可以有255個可能的值。當枚舉的值位於256和65,535之間時,用兩個位元組。參見11.4.4節,「ENUM類型」。

SET物件的大小由不同的set成員的數量決定。如果set大小是N,物件佔(N+7)/8個位元組,四捨五入到1、2、3、4或8個位元組。 SET最多可以有64個成員。參見11.4.5節,「SET類型」。


11.6. 選擇正確的列類型

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

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

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


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

為了使用由其它賣方編寫的SQL執行程式碼,MySQL按照下表所示對欄位類型進行對應。透過這些映射,可以輕鬆地從其它資料庫引擎將表格定義匯入MySQL:

其它賣方類型   MySQL類型   

BOOL,    TINYINT   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學習系列3:資料類型的內容,更多相關內容請關注PHP中文網(www.php.cn)!


陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn