個人MYSQL學習心得(四) 數據類型

MYSQL裏的BLOB數據類型html

BLOB是一個二進制大對象,用來存儲可變數量的數據。BLOB類型分爲4種:TinyBlob、Blob、MediumBlob、LongBlob,mysql

這幾個類型之間的惟一區別是在存儲文件的最大大小上不一樣。web

 

MySQL的四種BLOB類型     類型 大小(單位:字節)算法

TinyBlob                            最大 255
Blob                                  最大 65K
MediumBlob                       最大 16M
LongBlob                           最大 4Gsql

 

BLOB列存儲的是二進制字符串(字節字符串);TEXT列存儲的是非二進制字符串(字符字符串)。數據庫

BLOB列沒有字符集,而且排序和比較基於列值字節的數值;TEXT列有一個字符集,而且根據字符集對值進行排序和比較緩存

 

BLOB是二進制字符串,TEXT是非二進制字符串,二者都可存放大容量的信息。BLOB主要存儲圖片、音頻信息等安全

而TEXT只能存儲文本文件。服務器


SQLSERVER併發

SQLSERVER並無BLOB數據類型,只有大型對象數據類型(BLOB):

text,ntext,image,nvarchar(max),varchar(max),varbinary(max)和xml數據類型

這些數據類型的數據都存放在LOB類型的數據頁面裏

 

若有不對的地方,歡迎你們拍磚o(∩_∩)o 

 

其餘類型

第11章:列類型

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

MySQL支持處理空間數據的擴展名。關於空間類型的信息參見第19章:MySQL中的空間擴展

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

·         M

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

·         D

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

·         方括號(‘[’和‘]’)表示可選部分。

11.1. 列類型概述

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-3八、0和1.175494351E-38到3.402823466E+38。這些是理論限制,基於IEEE標準。實際的範圍根據硬件或操做系統的不一樣可能稍微小些。

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

若是指定UNSIGNED,不容許負值。

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

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

普通大小(雙精度)浮點數。容許的值是-1.7976931348623157E+308到-2.2250738585072014E-30八、0和2.2250738585072014E-308到 1.7976931348623157E+308。這些是理論限制,基於IEEE標準。實際的範圍根據硬件或操做系統的不一樣可能稍微小些。

M是小數總位數,D是小數點後面的位數。若是MD被省略,根據硬件容許的限制來保存值。雙精度浮點數精確到大約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,數據類型變爲沒有MD值的FLOAT。若是p爲從25到53,數據類型變爲沒有MD值的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])] [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。例如:

·                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版本以字節解釋長度)。

·         對於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語句將失敗並提示錯誤:

mysql>
ERROR 1074 (42000): Column length too big for column 'col' (max = 255); use BLOB or TEXT instead
mysql>
ERROR 1146 (42S02): Table 'test.c1' doesn't exist

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)的同義詞。

·         [NATIONAL] VARCHAR(M) [BINARY]

變長字符串。M 表示最大列長度。M的範圍是0到65,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(28–1)字節的BLOB列。

·         TINYTEXT

最大長度爲255(28–1)字符的TEXT列。

·         BLOB[(M)]

最大長度爲65,535(216–1)字節的BLOB列。

能夠給出該類型的可選長度M。若是給出,則MySQL將列建立爲最小的但足以容納M字節長的值的BLOB類型。

·         TEXT[(M)]

最大長度爲65,535(216–1)字符的TEXT列。

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

·         MEDIUMBLOB

最大長度爲16,777,215(224–1)字節的BLOB列。

·         MEDIUMTEXT

最大長度爲16,777,215(224–1)字符的TEXT列。

·         LONGBLOB

最大長度爲4,294,967,295或4GB(232–1)字節的BLOB列。LONGBLOB列的最大有效(容許的)長度取決於客戶端/服務器協議中配置最大包大小和可用的內存。

·         LONGTEXT

最大長度爲4,294,967,295或4GB(232–1)字符的TEXT列。LONGTEXT列的最大有效(容許的)長度取決於客戶端/服務器協議中配置最大包大小和可用的內存。

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

枚舉類型。只能有一個值的字符串,從值列'value1','value2',...,NULL中或特殊 ''錯誤值中選出。ENUM列最多能夠有65,535個大相徑庭的值。ENUM值在內部用整數表示。

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

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

11.2. 數值類型

MySQL支持全部標準SQL數值數據類型。這些類型包括嚴格數值數據類型(INTEGER、SMALLINT、DECIMAL和NUMERIC),以及近似數值數據類型(FLOAT、REAL和DOUBLE PRECISION)。關鍵字INT是INTEGER的同義詞,關鍵字DEC是DECIMAL的同義詞。

BIT數據類型保存位字段值,而且支持MyISAM、MEMORY、InnoDB和BDB表。

做爲SQL標準的擴展,MySQL也支持整數類型TINYINT、MEDIUMINT和BIGINT。下面的表顯示了須要的每一個整數類型的存儲和範圍。

類型

字節

最小值

最大值

 

 

(帶符號的/無符號的)

(帶符號的/無符號的)

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。同數類型,該屬性防止負值保存到列中。然而,與整數類型不一樣的是,列值的上範圍保持不變。

若是爲一個數值列指定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中視爲相同的類型。它們用於保存必須爲確切精度的值,例如貨幣數據。當聲明該類型的列時,能夠(而且一般要)指定精度和標度;例如:

salary DECIMAL(5,2)

在該例子中,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. 日期和時間類型

表示時間值的DATE和時間類型爲DATETIME、DATE、TIMESTAMP、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'

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類型

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'是不合法的(它有一個沒有意義的分鐘部分),將變爲'0000-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'或者00000000000000)。

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

數字值應爲六、八、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到999九、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:

mysql>

客戶端能夠按照下面方法讓服務器爲它的鏈接以MAXDB模式運行:

mysql>

 

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,任何一個能夠在另外一個的前面。

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

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列指定自動默認或更新,必須經過將第1個TIMESTAMP列顯式分配一個常量DEFAULT值來禁用自動初始化和更新。(例如,DEFAULT 0或DEFAULT'2003-01-01 00:00:00')。而後,對於其它TIMESTAMP列,規則與第1個TIMESTAMP列相同,例外狀況是不能忽略DEFAULT和ON 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被插入到該列內。換句話說,只有使用以下定義建立,定義爲 NULL的TIMESTAMP列纔會自動更新:

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表示日,能夠取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類型

字符串類型指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)

存儲需求

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>
Query OK, 0 rows affected (0.02 sec)
 
mysql>
Query OK, 1 row affected (0.00 sec)
 
mysql>
+----------------+----------------+
| CONCAT(v, '+') | CONCAT(c, '+') |
+----------------+----------------+
| ab  +          | ab+            |
+----------------+----------------+
1 row in set (0.00 sec)

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

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

mysql>
Query OK, 0 rows affected (0.09 sec)
 
mysql>
Query OK, 1 row affected (0.00 sec)
 
mysql>
+--------------------+----------------------+
| myname = 'Monty  ' | yourname = 'Monty  ' |
+--------------------+----------------------+
|                  1 |                    1 |
+--------------------+----------------------+
1 row in set (0.00 sec)

請注意全部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值時,在它們右邊填充值以達到指定長度。填充值是0x00(零字節)。插入值時在右側添加0x00 on,而且選擇時不刪除尾部的字節。比較時全部字節很重要,包括ORDER BY和DISTINCT操做。比較時0x00字節和空格是不一樣的,0x00<空格。

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

對於VARBINARY,插入時不填充字符,選擇時不裁剪字節。比較時全部字節很重要,包括ORDER BY和DISTINCT操做。比較時0x00字節和空格是不一樣的,0x00<空格。

對於尾部填充字符被裁剪掉或比較時將它們忽視掉的情形,若是列的索引須要惟一的值,在列內插入一個只是填充字符數不一樣的值將會形成複製鍵值錯誤。

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

mysql>
Query OK, 0 rows affected (0.01 sec)
 
mysql>
Query OK, 1 row affected (0.01 sec)
 
mysql>
+--------+---------+-------------+
| HEX(c) | c = 'a' | c = 'a\0\0' |
+--------+---------+-------------+
| 610000 |       0 |           1 |
+--------+---------+-------------+
1 row in set (0.09 sec)

若是檢索的值必須與指定進行存儲而沒有填充的值相同,最好使用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變量的值:

mysql>
mysql>
    ->

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

mysql>
    ->

·         BLOB或TEXT對象的最大大小由其類型肯定,但在客戶端和服務器之間實際能夠傳遞的最大值由可用內存數量和通訊緩存區大小肯定。你能夠經過更改max_allowed_packet變量的值更改消息緩存區的大小,但必須同時修改服務器和客戶端程序。例如,可使用 mysqlmysqldump來更改客戶端的max_allowed_packet值。參見7.5.2節,「調節服務器參數」8.3節,「mysql:MySQL命令行工具」8.8節,「mysqldump:數據庫備份程序」

每一個BLOB或TEXT值分別由內部分配的對象表示。這與其它列類型造成對比,後者是當打開表時爲每1列分配存儲引擎。

11.4.4. ENUM類型

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

在某些狀況下,ENUM值也能夠爲空字符串('')或NULL:

·         若是你將一個非法值插入ENUM(也就是說,容許的值列以外的字符串),將插入空字符串以做爲特殊錯誤值。該字符串與「普通」空字符串不一樣,該字符串有數值值0。後面有詳細討論。

·         若是將ENUM列聲明爲容許NULL,NULL值則爲該列的一個有效值,而且 默認值爲NULL。若是ENUM列被聲明爲NOT NULL,其默認值爲容許的值列的第1個元素。

每一個枚舉值有一個索引:

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

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

·                mysql>

·         NULL值的索引是NULL。

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

索引

NULL

NULL

''

0

'one'

1

'two'

2

'three'

3

枚舉最多能夠有65,535個元素。

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

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

若是在數值上下文中檢索一個ENUM值,將返回列值的索引。例如,你能夠這樣從ENUM列搜索數值值:

mysql>

若是將一個數字保存到ENUM列,數字被視爲索引,而且保存的值是該索引對應的枚舉成員。(可是,這不適合LOAD DATA,它將全部輸入視爲字符串)。不建議使用相似數字的枚舉值來定義一個ENUM列,由於這很容易引發混淆。例如,下面的列含有字符串值'0'、'1'和'2'的枚舉成員,但數值索引值爲一、2和3:

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值,所保存值的低階位對應第1個SET成員。若是在數值上下文中檢索一個SET值,檢索的值的位設置對應組成列值的SET成員。例如,你能夠這樣從一個SET列檢索數值值:

mysql>

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

SET成員

十進制值

二進制值

'a'

1

0001

'b'

2

0010

'c'

4

0100

'd'

8

1000

 

若是你爲該列分配一個值9,其二進制形式爲1001,所以第1個和第4個SET值成員'a'和'd'被選擇,結果值爲 'a,d'。

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

mysql>

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

mysql>
-> ('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>
+------+
| col  |
+------+
| a,d  |
| a,d  |
| a,d  |
| a,d  |
| a,d  |
+------+
5 rows in set (0.04 sec)

若是將SET列設置爲一個不支持的值,則該值被忽略併發出警告:

mysql>
Query OK, 1 row affected, 1 warning (0.03 sec)
 
mysql>
+---------+------+------------------------------------------+
| Level   | Code | Message                                  |
+---------+------+------------------------------------------+
| Warning | 1265 | Data truncated for column 'col' at row 1 |
+---------+------+------------------------------------------+
1 row in set (0.04 sec)
 
mysql>
+------+
| 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>
mysql>

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

下面的語句也是合法的:

mysql>
mysql>

第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個字節

SMALLINT

2個字節

MEDIUMINT

3個字節

INT, INTEGER

4個字節

BIGINT

8個字節

FLOAT(p)

若是0 <= p <= 24爲4個字節, 若是25 <= p <= 53爲8個字節

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 <= 且0 <= M <= 65535(參見下面的註釋)

BINARY(M)

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

VARBINARY(M)

L+1個字節,其中L <= 且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',...)

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

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

一、二、三、4或者8個字節,取決於set成員的數目(最多64個成員)

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

對於CHAR、VARCHAR和TEXT類型,前面的表中的值LM應解釋爲字符數目,而且列定義中的這些類型的長度表示字符數目。例如,要想保存一個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類須要 一、二、3或者4個字節來記錄列值的長度,取決於該類的最大可能的長度。參見11.4.3節,「BLOB和TEXT類型

在NDB Cluster存儲引擎中,TEXT和BLOB列的實施是不一樣的,其中TEXT列中的每一個記錄由兩個單獨部分組成。一個是固定大小(256字節),而且實際上保存在原表中。另外一個包括超出256字節的任何數據,保存在隱含的表中。第2個表中的記錄老是2,000字節長。這說明若是size<= 256,TEXT列的大小爲256(其中size表示記錄的大小);不然,大小是256 +size+(2000–(size–256)%2000)。

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

SET對象的大小由不一樣的set成員的數量肯定。若是set大小是N,對象佔(N+7)/8個字節,四捨五入到一、二、三、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

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>
Query OK, 0 rows affected (0.08 sec)
 
mysql>
+-------+---------------+------+-----+---------+-------+
| 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    |       |
+-------+---------------+------+-----+---------+-------+
相關文章
相關標籤/搜索