MySQL學(xué)習(xí)系列3:數(shù)據(jù)類型

mysql里的blob數(shù)據(jù)類型

blob是一個(gè)二進(jìn)制大對(duì)象,用來存儲(chǔ)可變數(shù)量的數(shù)據(jù)。blob類型分為4種:tinyblob、blob、mediumblob、longblob,

這幾個(gè)類型之間的唯一區(qū)別是在存儲(chǔ)文件的最大大小上不同。

mysql的四種blob類型 類型 大小(單位:字節(jié))

tinyblob 最大 255

blob 最大 65k

mediumblob 最大 16m

longblob 最大 4g

blob列存儲(chǔ)的是二進(jìn)制字符串(字節(jié)字符串);text列存儲(chǔ)的是非二進(jìn)制字符串(字符字符串)。

blob列沒有字符集,并且排序和比較基于列值字節(jié)的數(shù)值;text列有一個(gè)字符集,并且根據(jù)字符集對(duì)值進(jìn)行排序和比較

blob是二進(jìn)制字符串,text是非二進(jìn)制字符串,兩者均可存放大容量的信息。blob主要存儲(chǔ)圖片、音頻信息等,

而text只能存儲(chǔ)文本文件。

sqlserver

sqlserver并沒有blob數(shù)據(jù)類型,只有大型對(duì)象數(shù)據(jù)類型(blob):

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

這些數(shù)據(jù)類型的數(shù)據(jù)都存放在lob類型的數(shù)據(jù)頁(yè)面里

列類型

11.1.1. 數(shù)值類型概述

下面為數(shù)值列類型的概述。詳細(xì)信息參見11.2節(jié),“數(shù)值類型”。列存儲(chǔ)需求參見11.5節(jié),“列類型存儲(chǔ)需求”。

M指示最大顯示寬度。最大有效顯示寬度是255。顯示寬度與存儲(chǔ)大小或類型包含的值的范圍無關(guān),相關(guān)描述見11.2節(jié),“數(shù)值類型”。

如果為一個(gè)數(shù)值列指定ZEROFILL,MySQL自動(dòng)為該列添加UNSIGNED屬性。

SERIAL是BIGINT UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE的一個(gè)別名。

在整數(shù)列定義中,SERIAL DEFAULT VALUE是NOT NULL AUTO_INCREMENT UNIQUE的一個(gè)別名。

警告:應(yīng)當(dāng)清楚,當(dāng)使用在整數(shù)值(其中一個(gè)是UNSIGNED類型)之間使用減號(hào)時(shí),結(jié)果是無符號(hào)。參見12.8節(jié),“Cast函數(shù)和操作符”。

· BIT[(M)]

位字段類型。M表示每個(gè)值的位數(shù),范圍為從1到64。如果M被省略, 默認(rèn)為1。

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

很小的整數(shù)。帶符號(hào)的范圍是-128到127。無符號(hào)的范圍是0到255。

· BOOL,BOOLEAN

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

在將來,將根據(jù)標(biāo)準(zhǔn)SQL引入完全布爾類型的處理。

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

小的整數(shù)。帶符號(hào)的范圍是-32768到32767。無符號(hào)的范圍是0到65535。

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

中等大小的整數(shù)。帶符號(hào)的范圍是-8388608到8388607。無符號(hào)的范圍是0到16777215。

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

普通大小的整數(shù)。帶符號(hào)的范圍是-2147483648到2147483647。無符號(hào)的范圍是0到4294967295。

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

這是INT的同義詞。

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

大整數(shù)。帶符號(hào)的范圍是-9223372036854775808到9223372036854775807。無符號(hào)的范圍是0到18446744073709551615。

應(yīng)清楚BIGINT列的下述內(nèi)容:

o 使用帶符號(hào)的BIGINT或DOUBLE值進(jìn)行所有算法,因此除了位函數(shù),不應(yīng)使用大于9223372036854775807(63位)的無符號(hào)的大整數(shù)! 如果這樣做,結(jié)果中的最后幾位可能出錯(cuò),這是由于將BIGINT值轉(zhuǎn)換為DOUBLE進(jìn)行四舍五入時(shí)造成的錯(cuò)誤。

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

§ 當(dāng)使用整數(shù)在一個(gè)BIGINT列保存大的無符號(hào)的值時(shí)。

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

§ 使用操作符(+,-,*等等)并且兩個(gè)操作數(shù)均為整數(shù)時(shí)。

o 總是可以使用一個(gè)字符串在BIGINT列中保存嚴(yán)格整數(shù)值。在這種情況下,MySQL執(zhí)行字符串-數(shù)字轉(zhuǎn)換,其間不存在雙精度表示。

o 當(dāng)兩個(gè)操作數(shù)均為整數(shù)值時(shí),-、+和* 操作符使用BIGINT算法。這說明如果乘兩個(gè)大整數(shù)(或來自返回整數(shù)的函數(shù)),當(dāng)結(jié)果大于9223372036854775807時(shí),會(huì)得到意想不到的結(jié)果。

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

小(單精度)浮點(diǎn)數(shù)。允許的值是-3.402823466E+38到-1.175494351E-38、0和1.175494351E-38到3.402823466E+38。這些是理論限制,基于IEEE標(biāo)準(zhǔn)。實(shí)際的范圍根據(jù)硬件或操作系統(tǒng)的不同可能稍微小些。

M是小數(shù)縱位數(shù),D是小數(shù)點(diǎn)后面的位數(shù)。如果M和D被省略,根據(jù)硬件允許的限制來保存值。單精度浮點(diǎn)數(shù)精確到大約7位小數(shù)位。

如果指定UNSIGNED,不允許負(fù)值。

使用浮點(diǎn)數(shù)可能會(huì)遇到意想不到的問題,因?yàn)樵贛ySQL中的所有計(jì)算用雙精度完成。參見A.5.7節(jié),“解決與不匹配行有關(guān)的問題”。

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

普通大小(雙精度)浮點(diǎn)數(shù)。允許的值是-1.7976931348623157E+308到-2.2250738585072014E-308、0和2.2250738585072014E-308到 1.7976931348623157E+308。這些是理論限制,基于IEEE標(biāo)準(zhǔn)。實(shí)際的范圍根據(jù)硬件或操作系統(tǒng)的不同可能稍微小些。

M是小數(shù)總位數(shù),D是小數(shù)點(diǎn)后面的位數(shù)。如果M和D被省略,根據(jù)硬件允許的限制來保存值。雙精度浮點(diǎn)數(shù)精確到大約15位小數(shù)位。

如果指定UNSIGNED,不允許負(fù)值。

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

為DOUBLE的同義詞。除了:如果SQL服務(wù)器模式包括REAL_AS_FLOAT選項(xiàng),REAL是FLOAT的同義詞而不是DOUBLE的同義詞。

· FLOAT(p) [UNSIGNED] [ZEROFILL]

浮點(diǎn)數(shù)。p表示精度(以位數(shù)表示),但MySQL只使用該值來確定是否結(jié)果列的數(shù)據(jù)類型為FLOAT或DOUBLE。如果p為從0到24,數(shù)據(jù)類型變?yōu)闆]有M或D值的FLOAT。如果p為從25到53,數(shù)據(jù)類型變?yōu)闆]有M或D值的DOUBLE。結(jié)果列范圍與本節(jié)前面描述的單精度FLOAT或雙精度DOUBLE數(shù)據(jù)類型相同。

FLOAT(p)語(yǔ)法與ODBC兼容。

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

壓縮的“嚴(yán)格”定點(diǎn)數(shù)。M是小數(shù)位數(shù)(精度)的總數(shù),D是小數(shù)點(diǎn)(標(biāo)度)后面的位數(shù)。小數(shù)點(diǎn)和(負(fù)數(shù))的‘-’符號(hào)不包括在M中。如果D是0,則值沒有小數(shù)點(diǎn)或分?jǐn)?shù)部分。DECIMAL整數(shù)最大位數(shù)(M)為65。支持的十進(jìn)制數(shù)的最大位數(shù)(D)是30。如果D被省略,
默認(rèn)是0。如果M被省略, 默認(rèn)是10。

如果指定UNSIGNED,不允許負(fù)值。

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

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

是DECIMAL的同義詞。FIXED同義詞適用于與其它服務(wù)器的兼容性。

11.1.2. 日期和時(shí)間類型概述

本節(jié)綜合討論了臨時(shí)列類型。詳細(xì)信息,參見11.3節(jié),“日期和時(shí)間類型”。列存儲(chǔ)需求參見11.5節(jié),“列類型存儲(chǔ)需求”。

· DATE

日期。支持的范圍為’1000-01-01′到’9999-12-31′。MySQL以’YYYY-MM-DD’格式顯示DATE值,但允許使用字符串或數(shù)字為DATE列分配值。

· DATETIME

日期和時(shí)間的組合。支持的范圍是’1000-01-01 00:00:00′到’9999-12-31 23:59:59′。MySQL以’YYYY-MM-DD HH:MM:SS’格式顯示DATETIME值,但允許使用字符串或數(shù)字為DATETIME列分配值。

· TIMESTAMP[(M)]

時(shí)間戳。范圍是’1970-01-01 00:00:00′到2037年。

TIMESTAMP列用于INSERT或UPDATE操作時(shí)記錄日期和時(shí)間。如果你不分配一個(gè)值,表中的第一個(gè)TIMESTAMP列自動(dòng)設(shè)置為最近操作的日期和時(shí)間。也可以通過分配一個(gè)NULL值,將TIMESTAMP列設(shè)置為當(dāng)前的日期和時(shí)間。

TIMESTAMP值返回后顯示為’YYYY-MM-DD HH:MM:SS’格式的字符串,顯示寬度固定為19個(gè)字符。如果想要獲得數(shù)字值,應(yīng)在TIMESTAMP 列添加+0。

注釋:MySQL 4.1以前使用的TIMESTAMP格式在MySQL 5.1中不支持;關(guān)于舊格式的信息參見MySQL 4.1 參考手冊(cè)。

· TIME

時(shí)間。范圍是’-838:59:59′到’838:59:59′。MySQL以’HH:MM:SS’格式顯示TIME值,但允許使用字符串或數(shù)字為TIME列分配值。

· YEAR[(2|4)]

兩位或四位格式的年。默認(rèn)是四位格式。在四位格式中,允許的值是1901到2155和0000。在兩位格式中,允許的值是70到69,表示從1970年到2069年。MySQL以YYYY 格式顯示YEAR值,但允許使用字符串或數(shù)字為YEAR列分配值。

11.1.3. 字符串類型概述

本節(jié)綜合討論了字符串列類型。詳細(xì)信息參見11.4節(jié),“String類型”。列存儲(chǔ)需求參見11.5節(jié),“列類型存儲(chǔ)需求”。

在某些情況中,MySQL可以將一個(gè)字符串列更改為不同于CREATE TABLE或ALTER TABLE語(yǔ)句中所給出的類型。參見13.1.5.1節(jié),“沉寂的列規(guī)格變更”。

MySQL 5.1字符串?dāng)?shù)據(jù)類型包括部分在MySQL 4.1之前的版本中沒有的特性:

· 許多字符串?dāng)?shù)據(jù)類型的列定義可以包括指定字符集的CHARACTER SET屬性,也可能包括校對(duì)規(guī)則。(CHARSET是CHARACTER SET的一個(gè)同義詞)。這些屬性適用于CHAR、VARCHAR、TEXT類型、ENUM和SET。例如:

該表定義創(chuàng)建了一個(gè)名為c1的列,具有一個(gè)utf8字符集和該字符集的默認(rèn) 校對(duì)規(guī)則,和一個(gè)名為c2的列以及l(fā)atin1字符集和該字符集的二元 校對(duì)規(guī)則。二元校對(duì)規(guī)則對(duì)大小寫不敏感。

· MySQL 5.1用字符單位解釋在字符列定義中的長(zhǎng)度規(guī)范。(以前的一些MySQL版本以字節(jié)解釋長(zhǎng)度)。

· 對(duì)于CHAR、VARCHAR和TEXT類型,BINARY屬性可以為列分配該列字符集的 校對(duì)規(guī)則。

· 字符列的排序和比較基于分配給列的字符集。在以前的版本中,排序和比較基于服務(wù)器字符集的校對(duì)規(guī)則。對(duì)于CHAR和VARCHAR 列,你可以用BINARY屬性聲明列讓排序和 校對(duì)規(guī)則使用當(dāng)前的字符代碼值而不是詞匯順序。

關(guān)于MySQL 5.1中字符集的支持,參見第10章:字符集支持。

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

固定長(zhǎng)度字符串,當(dāng)保存時(shí)在右側(cè)填充空格以達(dá)到指定的長(zhǎng)度。M表示列長(zhǎng)度。M的范圍是0到255個(gè)字符。

注釋:當(dāng)檢索CHAR值時(shí)尾部空格被刪除。

如果想要將某個(gè)CHAR的長(zhǎng)度設(shè)為大于255,執(zhí)行的CREATE TABLE或ALTER TABLE語(yǔ)句將失敗并提示錯(cuò)誤:

CHAR是CHARACTER的簡(jiǎn)寫。NATIONAL CHAR(或其等效短形式NCHAR)是標(biāo)準(zhǔn)的定義CHAR列應(yīng)使用 默認(rèn)字符集的SQL方法。這在MySQL中為默認(rèn)值。

BINARY屬性是指定列字符集的二元 校對(duì)規(guī)則的簡(jiǎn)寫。排序和比較基于數(shù)值字符值。

列類型CHAR BYTE是CHAR BINARY的一個(gè)別名。這是為了保證兼容性。

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

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

MySQL允許創(chuàng)建類型CHAR(0)的列。這主要用于必須有一個(gè)列但實(shí)際上不使用值的舊版本的應(yīng)用程序相兼容。當(dāng)你需要只能取兩個(gè)值的列時(shí)也很好:沒有定義為NOT NULL的一個(gè)CHAR(0)列只占用一位,只可以取值NULL和”(空字符串)。

· CHAR

這是CHAR(1)的同義詞。

· [NATIONAL] VARCHAR(M) [BINARY]

變長(zhǎng)字符串。M 表示最大列長(zhǎng)度。M的范圍是0到65,535。(VARCHAR的最大實(shí)際長(zhǎng)度由最長(zhǎng)的行的大小和使用的字符集確定。最大有效長(zhǎng)度是65,532字節(jié))。

注釋:MySQL 5.1遵從標(biāo)準(zhǔn)SQL規(guī)范,并且不刪除VARCHAR值的尾部空格。

VARCHAR是字符VARYING的簡(jiǎn)寫。

BINARY屬性是指定列的字符集的二元 校對(duì)規(guī)則的簡(jiǎn)寫。排序和比較基于數(shù)值字符值。

VARCHAR保存時(shí)用一個(gè)字節(jié)或兩個(gè)字節(jié)長(zhǎng)的前綴+數(shù)據(jù)。如果VARCHAR列聲明的長(zhǎng)度大于255,長(zhǎng)度前綴是兩個(gè)字節(jié)。

· BINARY(M)

BINARY類型類似于CHAR類型,但保存二進(jìn)制字節(jié)字符串而不是非二進(jìn)制字符串。

· VARBINARY(M)

VARBINARY類型類似于VARCHAR類型,但保存二進(jìn)制字節(jié)字符串而不是非二進(jìn)制字符串。

· TINYBLOB

最大長(zhǎng)度為255(28–1)字節(jié)的BLOB列。

· TINYTEXT

最大長(zhǎng)度為255(28–1)字符的TEXT列。

· BLOB[(M)]

最大長(zhǎng)度為65,535(216–1)字節(jié)的BLOB列。

可以給出該類型的可選長(zhǎng)度M。如果給出,則MySQL將列創(chuàng)建為最小的但足以容納M字節(jié)長(zhǎng)的值的BLOB類型。

· TEXT[(M)]

最大長(zhǎng)度為65,535(216–1)字符的TEXT列。

可以給出可選長(zhǎng)度M。則MySQL將列創(chuàng)建為最小的但足以容納M字符長(zhǎng)的值的TEXT類型。

· MEDIUMBLOB

最大長(zhǎng)度為16,777,215(224–1)字節(jié)的BLOB列。

· MEDIUMTEXT

最大長(zhǎng)度為16,777,215(224–1)字符的TEXT列。

· LONGBLOB

最大長(zhǎng)度為4,294,967,295或4GB(232–1)字節(jié)的BLOB列。LONGBLOB列的最大有效(允許的)長(zhǎng)度取決于客戶端/服務(wù)器協(xié)議中配置最大包大小和可用的內(nèi)存。

· LONGTEXT

最大長(zhǎng)度為4,294,967,295或4GB(232–1)字符的TEXT列。LONGTEXT列的最大有效(允許的)長(zhǎng)度取決于客戶端/服務(wù)器協(xié)議中配置最大包大小和可用的內(nèi)存。

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

枚舉類型。只能有一個(gè)值的字符串,從值列’value1‘,’value2‘,…,NULL中或特殊 ”錯(cuò)誤值中選出。ENUM列最多可以有65,535個(gè)截然不同的值。ENUM值在內(nèi)部用整數(shù)表示。

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

一個(gè)設(shè)置。字符串對(duì)象可以有零個(gè)或多個(gè)值,每個(gè)值必須來自列值’value1‘,’value2‘,…SET列最多可以有64個(gè)成員。SET值在內(nèi)部用整數(shù)表示。

11.2. 數(shù)值類型

MySQL支持所有標(biāo)準(zhǔn)SQL數(shù)值數(shù)據(jù)類型。這些類型包括嚴(yán)格數(shù)值數(shù)據(jù)類型(INTEGER、SMALLINT、DECIMAL和NUMERIC),以及近似數(shù)值數(shù)據(jù)類型(FLOAT、REAL和DOUBLE PRECISION)。關(guān)鍵字INT是INTEGER的同義詞,關(guān)鍵字DEC是DECIMAL的同義詞。

BIT數(shù)據(jù)類型保存位字段值,并且支持MyISAM、MEMORY、InnoDB和BDB表。

作為SQL標(biāo)準(zhǔn)的擴(kuò)展,MySQL也支持整數(shù)類型TINYINT、MEDIUMINT和BIGINT。下面的表顯示了需要的每個(gè)整數(shù)類型的存儲(chǔ)和范圍。

類型 ? ?字節(jié) ? ?最小值 ? ?最大值 ? ?

(帶符號(hào)的/無符號(hào)的) ? ?(帶符號(hào)的/無符號(hào)的) ? ?

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還支持選擇在該類型關(guān)鍵字后面的括號(hào)內(nèi)指定整數(shù)值的顯示寬度(例如,INT(4))。該可選顯示寬度規(guī)定用于顯示寬度小于指定的列寬度的值時(shí)從左側(cè)填滿寬度。

顯示寬度并不限制可以在列內(nèi)保存的值的范圍,也不限制超過列的指定寬度的值的顯示。

當(dāng)結(jié)合可選擴(kuò)展屬性ZEROFILL使用時(shí), 默認(rèn)補(bǔ)充的空格用零代替。例如,對(duì)于聲明為INT(5) ZEROFILL的列,值4檢索為00004。請(qǐng)注意如果在整數(shù)列保存超過顯示寬度的一個(gè)值,當(dāng)MySQL為復(fù)雜聯(lián)接生成臨時(shí)表時(shí)會(huì)遇到問題,因?yàn)樵谶@些情況下MySQL相信數(shù)據(jù)適合原列寬度。

所有整數(shù)類型可以有一個(gè)可選(非標(biāo)準(zhǔn))屬性UNSIGNED。當(dāng)你想要在列內(nèi)只允許非負(fù)數(shù)和該列需要較大的上限數(shù)值范圍時(shí)可以使用無符號(hào)值。

浮點(diǎn)和定點(diǎn)類型也可以為UNSIGNED。同數(shù)類型,該屬性防止負(fù)值保存到列中。然而,與整數(shù)類型不同的是,列值的上范圍保持不變。

如果為一個(gè)數(shù)值列指定ZEROFILL,MySQL自動(dòng)為該列添加UNSIGNED屬性。

對(duì)于浮點(diǎn)列類型,在MySQL中單精度值使用4個(gè)字節(jié),雙精度值使用8個(gè)字節(jié)。

FLOAT類型用于表示近似數(shù)值數(shù)據(jù)類型。SQL標(biāo)準(zhǔn)允許在關(guān)鍵字FLOAT后面的括號(hào)內(nèi)選擇用位指定精度(但不能為指數(shù)范圍)。MySQL還支持可選的只用于確定存儲(chǔ)大小的精度規(guī)定。0到23的精度對(duì)應(yīng)FLOAT列的4字節(jié)單精度。24到53的精度對(duì)應(yīng)DOUBLE列的8字節(jié)雙精度。

MySQL允許使用非標(biāo)準(zhǔn)語(yǔ)法:FLOAT(M,D)或REAL(M,D)或DOUBLE
PRECISION(M,D)。這里,“(M,D)”表示該值一共顯示M位整數(shù),其中D位位于小數(shù)點(diǎn)后面。例如,定義為FLOAT(7,4)的一個(gè)列可以顯示為-999.9999。MySQL保存值時(shí)進(jìn)行四舍五入,因此如果在FLOAT(7,4)列內(nèi)插入999.00009,近似結(jié)果是999.0001。

MySQL將DOUBLE視為DOUBLE PRECISION(非標(biāo)準(zhǔn)擴(kuò)展)的同義詞。MySQL還將REAL視為DOUBLE PRECISION(非標(biāo)準(zhǔn)擴(kuò)展)的同義詞,除非SQL服務(wù)器模式包括REAL_AS_FLOAT選項(xiàng)。

為了保證最大可能的可移植性,需要使用近似數(shù)值數(shù)據(jù)值存儲(chǔ)的代碼應(yīng)使用FLOAT或DOUBLE PRECISION,不規(guī)定精度或位數(shù)。

DECIMAL和NUMERIC類型在MySQL中視為相同的類型。它們用于保存必須為確切精度的值,例如貨幣數(shù)據(jù)。當(dāng)聲明該類型的列時(shí),可以(并且通常要)指定精度和標(biāo)度;例如:

在該例子中,5是精度,2是標(biāo)度。精度表示保存值的主要位數(shù),標(biāo)度表示小數(shù)點(diǎn)后面可以保存的位數(shù)。

在MySQL 5.1中以二進(jìn)制格式保存DECIMAL和NUMERIC值。

標(biāo)準(zhǔn)SQL要求salary列能夠用5位整數(shù)位和兩位小數(shù)保存任何值。因此,在這種情況下可以保存在salary列的值的范圍是從-999.99到999.99。

在標(biāo)準(zhǔn)SQL中,語(yǔ)法DECIMAL(M)等價(jià)于DECIMAL(M,0)。同樣,語(yǔ)法DECIMAL等價(jià)于DECIMAL(M,0),可以通過計(jì)算確定M的值。在MySQL
5.1中支持DECIMAL和NUMERIC數(shù)據(jù)類型的變量形式。M默認(rèn)值是10。

DECIMAL或NUMERIC的最大位數(shù)是65,但具體的DECIMAL或NUMERIC列的實(shí)際范圍受具體列的精度或標(biāo)度約束。如果此類列分配的值小數(shù)點(diǎn)后面的位數(shù)超過指定的標(biāo)度允許的范圍,值被轉(zhuǎn)換為該標(biāo)度。(具體操作與操作系統(tǒng)有關(guān),但一般結(jié)果均被截取到允許的位數(shù))。

BIT數(shù)據(jù)類型可用來保存位字段值。BIT(M)類型允許存儲(chǔ)M位值。M范圍為1到64。

要指定位值,可以使用b’value‘符。value是一個(gè)用0和1編寫的二進(jìn)制值。例如,b’111′和b’100000000′分別表示7和128。參見9.1.5節(jié),“位字段值”。

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

當(dāng)要在一個(gè)數(shù)值列內(nèi)保存一個(gè)超出該列允許范圍的值時(shí),MySQL的操作取決于此時(shí)有效的SQL模式。如果模式未設(shè)置,MySQL將值裁剪到范圍的相應(yīng)端點(diǎn),并保存裁減好的值。但是,如果模式設(shè)置為traditional(“嚴(yán)格模式”),超出范圍的值將被拒絕并提示錯(cuò)誤,并且根據(jù)SQL標(biāo)準(zhǔn)插入會(huì)失敗。參見5.3.2節(jié),“SQL服務(wù)器模式”。

如果INT列是UNSIGNED,列范圍的大小相同,但其端點(diǎn)會(huì)變?yōu)榈?和4294967295。如果你試圖保存-9999999999和9999999999,以非嚴(yán)格模式保存到列中的值是0和4294967296。

如果在浮點(diǎn)或定點(diǎn)列中分配的值超過指定(或默認(rèn))精度和標(biāo)度規(guī)定的范圍,MySQL以非嚴(yán)格模式保存表示范圍相應(yīng)端點(diǎn)的值。

當(dāng)MySQL沒有工作在嚴(yán)格模式時(shí),對(duì)于ALTER TABLE、LOAD DATA INFILE、UPDATE和多行INSERT語(yǔ)句,由于裁剪發(fā)生的轉(zhuǎn)換將報(bào)告為警告。當(dāng)MySQL工作在嚴(yán)格模式時(shí),這些語(yǔ)句將失敗,并且部分或全部值不會(huì)插入或更改,取決于是否表為事務(wù)表和其它因素。詳情參見5.3.2節(jié),“SQL服務(wù)器模式”。

11.3. 日期和時(shí)間類型

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

表示時(shí)間值的DATE和時(shí)間類型為DATETIME、DATE、TIMESTAMP、TIME和YEAR。每個(gè)時(shí)間類型有一個(gè)有效值范圍和一個(gè)“零”值,當(dāng)指定不合法的MySQL不能表示的值時(shí)使用“零”值。TIMESTAMP類型有專有的自動(dòng)更新特性,將在后面描述。

如果試圖插入一個(gè)不合法的日期,MySQL將給出警告或錯(cuò)誤。可以使用ALLOW_INVALID_DATES SQL模式讓MySQL接受某些日期,例如’1999-11-31′。當(dāng)你想要保存一個(gè)“可能錯(cuò)誤的”用戶已經(jīng)在數(shù)據(jù)庫(kù)中指定(例如,以web形式)用于將來處理的值時(shí)很有用。在這種模式下,MySQL只驗(yàn)證月范圍為從0到12,日范圍為從0到31。這些范圍可以包括零,因?yàn)镸ySQL允許在DATE或DATETIME列保存日/月和日是零的日期。這在應(yīng)用程序需要保存一個(gè)你不知道確切日期的生日時(shí)非常有用。在這種情況下,只需要將日期保存為’1999-00-00′或’1999-01-00′。如果保存此類日期,DATE_SUB()或DATE_ADD等需要完整日期的函數(shù)不會(huì)得到正確的結(jié)果。(如果你不想在日期中出現(xiàn)零,可以使用NO_ZERO_IN_DATE SQL模式)。

MySQL還允許將’0000-00-00′保存為“偽日期”(如果不使用NO_ZERO_DATE SQL模式)。這在某些情況下比使用NULL值更方便(并且數(shù)據(jù)和索引占用的空間更小)。

將sql_mode系統(tǒng)變量設(shè)置為相應(yīng)模式值,可以更確切你想讓MySQL支持哪種日期。參見5.3.2節(jié),“SQL服務(wù)器模式”。

當(dāng)使用日期和時(shí)間類型時(shí)應(yīng)記住以下幾點(diǎn):

· MySQL以標(biāo)準(zhǔn)輸出格式檢索給定日期或時(shí)間類型的值,但它盡力解釋你指定的各種輸入值格式(例如,當(dāng)你指定一個(gè)分配給或與日期或時(shí)間類型進(jìn)行比較的值時(shí))。只支持下面章節(jié)中描述的格式。期望你能提供有效值。如果你使用其它格式的值會(huì)發(fā)生意想不到的結(jié)果。

· 包含兩位年值的日期會(huì)令人模糊,因?yàn)槭兰o(jì)不知道。MySQL使用以下規(guī)則解釋兩位年值:

o 70-99范圍的年值轉(zhuǎn)換為1970-1999。

o 00-69范圍的年值轉(zhuǎn)換為2000-2069。

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

· 如果值用于數(shù)值上下文中,MySQL自動(dòng)將日期或時(shí)間類型的值轉(zhuǎn)換為數(shù)字,反之亦然。

· 當(dāng) MySQL遇到一個(gè)日期或時(shí)間類型的超出范圍或?qū)τ谠擃愋筒缓戏ǖ闹禃r(shí)(如本節(jié)開始所描述),它將該值轉(zhuǎn)換為該類的“零”值。一個(gè)例外是超出范圍的TIME值被裁剪到TIME范圍的相應(yīng)端點(diǎn)。

下面的表顯示了各類“零”值的格式。請(qǐng)注意如果啟用NO_ZERO_DATE SQL模式,使用這些值會(huì)產(chǎn)生警告。

列類型 ? ?“零”值 ? ?

DATETIME ? ?’0000-00-00 00:00:00′ ? ?

DATE ? ?’0000-00-00′ ? ?

TIMESTAMP ? ?00000000000000 ? ?

TIME ? ?’00:00:00′ ? ?

YEAR ? ?0000 ? ?

· “零”值是特殊值,但你可以使用表內(nèi)顯示的值顯式保存或引用它們。你也可以使用值’0′或0來保存或引用,寫起來更容易。

· MyODBC中使用的“零”日期或時(shí)間值在MyODBC 2.50.12和以上版本中被自動(dòng)轉(zhuǎn)換為NULL,因?yàn)镺DBC不能處理此類值。

11.3.1. DATETIME、DATE和TIMESTAMP類型

11.3.1.1.
自MySQL 4.1以來的TIMESTAMP屬性

DATETIME、DATE和TIMESTAMP類型是相關(guān)的。該節(jié)描述了它們的特征,它們的相似點(diǎn)和不同點(diǎn)。

當(dāng)你需要同時(shí)包含日期和時(shí)間信息的值時(shí)則使用DATETIME類型。MySQL以’YYYY-MM-DD HH:MM:SS’格式檢索和顯示DATETIME值。支持的范圍為’1000-01-01 00:00:00′到’9999-12-31 23:59:59′。(“支持”表示盡管先前的值可能工作,但沒有保證)。

當(dāng)你只需要日期值而不需要時(shí)間部分時(shí)應(yīng)使用DATE類型。MySQL用’YYYY-MM-DD’格式檢索和顯示DATE值。支持的范圍是’1000-01-01′到 ’9999-12-31′。

TIMESTAMP列類型的屬性不固定,取決于MySQL版本和服務(wù)器運(yùn)行的SQL模式。這些屬性將在本節(jié)后面描述。

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

· ’YYYY-MM-DD HH:MM:SS’或’YY-MM-DD HH:MM:SS’格式的字符串。允許“不嚴(yán)格”語(yǔ)法:任何標(biāo)點(diǎn)符都可以用做日期部分或時(shí)間部分之間的間割符。例如,’98-12-31 11:30:45′、’98.12.31 11+30+45′、’98/12/31 11*30*45′和’98@12@31 11^30^45′是等價(jià)的。

· ’YYYY-MM-DD’或’YY-MM-DD’格式的字符串。這里也允許使用“不嚴(yán)格的”語(yǔ)法。例如,’98-12-31′、’98.12.31′、’98/12/31′和’98@12@31′是等價(jià)的。

· ’YYYYMMDDHHMMSS’或’YYMMDDHHMMSS’格式的沒有間割符的字符串,假定字符串對(duì)于日期類型是有意義的。例如,’19970523091528′和’970523091528′被解釋為’1997-05-23 09:15:28′,但’971122129015′是不合法的(它有一個(gè)沒有意義的分鐘部分),將變?yōu)椤?000-00-00 00:00:00′。

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

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

· YYYYMMDD或YYMMDD格式的數(shù)字,假定數(shù)字對(duì)于日期類型是有意義的。例如,19830905和830905被解釋為’1983-09-05′。

· 函數(shù)返回的結(jié)果,其值適合DATETIME、DATE或者TIMESTAMP上下文,例如NOW()或CURRENT_DATE。

無效DATETIME、DATE或者TIMESTAMP值被轉(zhuǎn)換為相應(yīng)類型的“零”值(’0000-00-00 00:00:00′、’0000-00-00′或者00000000000000)。

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

數(shù)字值應(yīng)為6、8、12或者14位長(zhǎng)。如果一個(gè)數(shù)值是8或14位長(zhǎng),則假定為YYYYMMDD或YYYYMMDDHHMMSS格式,前4位數(shù)表示年。如果數(shù)字 是6或12位長(zhǎng),則假定為YYMMDD或YYMMDDHHMMSS格式,前2位數(shù)表示年。其它數(shù)字被解釋為仿佛用零填充到了最近的長(zhǎng)度。

指定為非限定符字符串的值使用給定的長(zhǎng)度進(jìn)行解釋。如果字符串為8或14字符長(zhǎng),前4位數(shù)表示年。否則,前2位數(shù)表示年。從左向右解釋字符串內(nèi)出現(xiàn)的各部分,以發(fā)現(xiàn)年、月、日、小時(shí)、分和秒值。這說明不應(yīng)使用少于6字符的字符串。例如,如果你指定’9903′,認(rèn)為它表示1999年3月,MySQL將在你的表內(nèi)插入一個(gè)“零”日期值。這是因?yàn)槟旰驮轮凳?9和03,但日部分完全丟失,因此該值不是一個(gè)合法的日期。但是,可以明顯指定一個(gè)零值來代表缺少的月或日部分。例如,可以使用’990300′來插入值’1999-03-00′。

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

· 如果你為一個(gè)DATETIME或TIMESTAMP對(duì)象分配一個(gè)DATE值,結(jié)果值的時(shí)間部分被設(shè)置為’00:00:00′,因?yàn)镈ATE值未包含時(shí)間信息。

· 如果你為一個(gè)DATE對(duì)象分配一個(gè)DATETIME或TIMESTAMP值,結(jié)果值的時(shí)間部分被刪除,因?yàn)镈ATE值未包含時(shí)間信息。

· 記住盡管可以使用相同的格式指定DATETIME、DATE和TIMESTAMP值,不同類型的值的范圍卻不同。例如,TIMESTAMP值不能早于1970或晚于2037。這說明一個(gè)日期,例如’1968-01-01′,雖然對(duì)于DATETIME或DATE值是有效的,但對(duì)于TIMESTAMP值卻無效,如果分配給這樣一個(gè)對(duì)象將被轉(zhuǎn)換為0。

當(dāng)指定日期值時(shí)請(qǐng)注意某些缺陷:

· 指定為字符串的值允許的非嚴(yán)格格式可能會(huì)欺騙。例如,值’10:11:12′由于‘:’間割符看上去可能象時(shí)間值,但如果用于日期上下文值則被解釋為年’2010-11-12′。值’10:45:15′被轉(zhuǎn)換為’0000-00-00′因?yàn)椤?5′不是合法月。

· 在非嚴(yán)格模式,MySQL服務(wù)器只對(duì)日期的合法性進(jìn)行基本檢查:年、月和日的范圍分別是1000到9999、00到12和00到31。任何包含超出這些范圍的部分的日期被轉(zhuǎn)換成’0000-00-00′。請(qǐng)注意仍然允許你保存非法日期,例如’2002-04-31′。要想確保不使用嚴(yán)格模式時(shí)日期有效,應(yīng)檢查應(yīng)用程序。

在嚴(yán)格模式,非法日期不被接受,并且不轉(zhuǎn)換。

詳細(xì)信息參見5.3.2節(jié),“SQL服務(wù)器模式”。

· 包含兩位年值的日期會(huì)令人模糊,因?yàn)槭兰o(jì)不知道。MySQL使用以下規(guī)則解釋兩位年值:

o 00-69范圍的年值轉(zhuǎn)換為2000-2069。

o 70-99范圍的年值轉(zhuǎn)換為1970-1999。

11.3.1.1. 自MySQL 4.1以來的TIMESTAMP屬性

注釋:在舊版本的MySQL中(4.1之前),TIMESTAMP列類型的屬性在許多方面于本節(jié)所描述的大大不同。如果你需要對(duì)舊的TIMESTAMP數(shù)據(jù)進(jìn)行轉(zhuǎn)化以便在MySQL 5.1中工作,詳情請(qǐng)參見MySQL 4.1 參考手冊(cè)。

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

MySQL服務(wù)器也可以以MAXDB模式運(yùn)行。當(dāng)服務(wù)器以該模式運(yùn)行時(shí),TIMESTAMP與DATETIME相等。也就是說,如果創(chuàng)建表時(shí)服務(wù)器以MAXDB模式運(yùn)行,TIMESTAMP列創(chuàng)建為DATETIME列。結(jié)果是,該列使用DATETIME顯示格式,有相同的值范圍,并且沒有自動(dòng)對(duì)當(dāng)前的日期和時(shí)間進(jìn)行初始化或更新。

要想啟用MAXDB模式,在啟動(dòng)服務(wù)器時(shí)使用–sql-mode=MAXDB服務(wù)器選項(xiàng)或在運(yùn)行時(shí)通過設(shè)置全局sql_mode變量將SQL服務(wù)器模式設(shè)置為MAXDB:

客戶端可以按照下面方法讓服務(wù)器為它的連接以MAXDB模式運(yùn)行:

MySQL不接受在日或月列包括一個(gè)零或包含非法日期值的時(shí)間戳值。該規(guī)則的唯一例外是特殊值’0000-00-00 00:00:00′。

你可以非常靈便地確定什么時(shí)候初始化和更新TIMESTAMP和對(duì)哪些列進(jìn)行初始化和更新:

· 你可以將當(dāng)前的時(shí)間戳指定為默認(rèn)值和自動(dòng)更新的值。但只能選擇一個(gè),或者兩者都不選。(不可能一個(gè)列選擇一個(gè)行為而另一個(gè)列選擇另一個(gè)行為)。

· 你可以指定哪個(gè)TIMESTAMP列自動(dòng)初始化或更新為當(dāng)前的日期和時(shí)間。不再需要為第1個(gè)TIMESTAMP列。

請(qǐng)注意下面討論所信息只適用于創(chuàng)建時(shí)未啟用MAXDB模式的表的TIMESTAMP列。(如上所述,MAXDB模式使列創(chuàng)建為DATETIME列)。控制TIMESTAMP列的初始化和更新的規(guī)則如下所示:

· 如果一個(gè)表內(nèi)的第1個(gè)TIMESTAMP列指定為一個(gè)DEFAULT值,則不能忽略。 默認(rèn)值可以為CURRENT_TIMESTAMP或常量日期和時(shí)間值。

· DEFAULT NULL與第1個(gè)TIMESTAMP 列的DEFAULT CURRENT_TIMESTAMP相同。對(duì)于其它TIMESTAMP列,DEFAULT NULL被視為DEFAULT 0。

· 表內(nèi)的任何一個(gè)TIMESTAMP列可以設(shè)置為自動(dòng)初始化為當(dāng)前時(shí)間戳和/或更新。

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

o 用DEFAULT CURRENT_TIMESTAMP和ON UPDATE CURRENT_TIMESTAMP子句,列為默認(rèn)值使用當(dāng)前的時(shí)間戳,并且自動(dòng)更新。

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

o 用DEFAULT CURRENT_TIMESTAMP子句不用ON UPDATE子句,列為默認(rèn)值使用當(dāng)前的時(shí)間戳但是不自動(dòng)更新。

o 不用DEFAULT子句但用ON UPDATE CURRENT_TIMESTAMP子句,列有默認(rèn)值0并自動(dòng)更新。

o 用常量DEFAULT值,列有給出的 默認(rèn)值。如果列有一個(gè)ON UPDATE CURRENT_TIMESTAMP子句,它自動(dòng)更新,否則不。

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

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

兩個(gè)屬性的順序并不重要。如果一個(gè)TIMESTAMP列同時(shí)指定了DEFAULT和ON UPDATE,任何一個(gè)可以在另一個(gè)的前面。

例子,下面這些語(yǔ)句是等效的:

· 要為TIMESTAMP列而不是第1列指定自動(dòng)默認(rèn)或更新,必須通過將第1個(gè)TIMESTAMP列顯式分配一個(gè)常量DEFAULT值來禁用自動(dòng)初始化和更新。(例如,DEFAULT 0或DEFAULT’2003-01-01 00:00:00′)。然后,對(duì)于其它TIMESTAMP列,規(guī)則與第1個(gè)TIMESTAMP列相同,例外情況是不能忽略DEFAULT和ON UPDATE子句。如果這樣做,則不會(huì)自動(dòng)進(jìn)行初始化或更新。

例如:下面這些語(yǔ)句是等效的:

可以對(duì)每個(gè)連接設(shè)置當(dāng)前的時(shí)區(qū),相關(guān)描述參見5.10.8節(jié),“MySQL服務(wù)器時(shí)區(qū)支持”。TIMESTAMP值以UTC格式保存,存儲(chǔ)時(shí)對(duì)當(dāng)前的時(shí)區(qū)進(jìn)行轉(zhuǎn)換,檢索時(shí)再轉(zhuǎn)換回當(dāng)前的時(shí)區(qū)。只要時(shí)區(qū)設(shè)定值為常量,便可以得到保存時(shí)的值。如果保存一個(gè)TIMESTAMP值,應(yīng)更改時(shí)區(qū)然后檢索該值,它與你保存的值不同。這是因?yàn)樵趦蓚€(gè)方向的轉(zhuǎn)換中沒有使用相同的時(shí)區(qū)。當(dāng)前的時(shí)區(qū)可以用作time_zone系統(tǒng)變量的值。

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

如果未指定NULL屬性,將列設(shè)置為NULL設(shè)置則會(huì)將它設(shè)置為當(dāng)前的時(shí)間戳。請(qǐng)注意允許NULL值的TIMESTAMP列不會(huì)采用當(dāng)前的時(shí)間戳,除非要么其 默認(rèn)值定義為CURRENT_TIMESTAMP,或者NOW()或CURRENT_TIMESTAMP被插入到該列內(nèi)。換句話說,只有使用如下定義創(chuàng)建,定義為 NULL的TIMESTAMP列才會(huì)自動(dòng)更新:

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

…則必須顯式插入一個(gè)對(duì)應(yīng)當(dāng)前日期和時(shí)間的值。例如:

11.3.2. TIME類型

MySQL以’HH:MM:SS’格式檢索和顯示TIME值(或?qū)τ诖蟮男r(shí)值采用’HHH:MM:SS’格式)。TIME值的范圍可以從’-838:59:59′到’838:59:59′。小時(shí)部分會(huì)因此大的原因是TIME類型不僅可以用于表示一天的時(shí)間(必須小于24小時(shí)),還可能為某個(gè)事件過去的時(shí)間或兩個(gè)事件之間的時(shí)間間隔(可以大于24小時(shí),或者甚至為負(fù))。

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

· ’D HH:MM:SS.fraction’格式的字符串。還可以使用下面任何一種“非嚴(yán)格”語(yǔ)法:’HH:MM:SS.fraction’、’HH:MM:SS’、’HH:MM’、’D HH:MM:SS’、’D HH:MM’、’D HH’或’SS’。這里D表示日,可以取0到34之間的值。請(qǐng)注意MySQL還不保存分?jǐn)?shù)。

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

· HHMMSS格式的數(shù)值,假定是有意義的時(shí)間。例如,101112被理解為’10:11:12′。下面格式也可以理解:SS、MMSS、HHMMSS、HHMMSS.fraction。請(qǐng)注意MySQL還不保存分?jǐn)?shù)。

· 函數(shù)返回的結(jié)果,其值適合TIME上下文,例如CURRENT_TIME。

對(duì)于指定為包括時(shí)間部分間割符的字符串的TIME值,如果時(shí)、分或者秒值小于10,則不需要指定兩位數(shù)。’8:3:2′與’08:03:02′相同。

為TIME列分配簡(jiǎn)寫值時(shí)應(yīng)注意。沒有冒號(hào),MySQL解釋值時(shí)假定最右邊的兩位表示秒。(MySQL解釋TIME值為過去的時(shí)間而不是當(dāng)天的時(shí)間)。例如,你可能認(rèn)為’1112′和1112表示’11:12:00′(11點(diǎn)過12分),但MySQL將它們解釋為’00:11:12′(11分,12 秒)。同樣,’12′和12 被解釋為 ’00:00:12′。相反,TIME值中使用冒號(hào)則肯定被看作當(dāng)天的時(shí)間。也就是說,’11:12′表示’11:12:00′,而不是’00:11:12′。

超出TIME范圍但合法的值被裁為范圍最接近的端點(diǎn)。例如,’-850:00:00′和’850:00:00′被轉(zhuǎn)換為’-838:59:59′和’838:59:59′。

無效TIME值被轉(zhuǎn)換為’00:00:00′。請(qǐng)注意由于’00:00:00′本身是一個(gè)合法TIME值,只從表內(nèi)保存的一個(gè)’00:00:00′值還不能說出原來的值是 ’00:00:00′還是不合法的值。

11.3.3. YEAR類型

YEAR類型是一個(gè)單字節(jié)類型用于表示年。

MySQL以YYYY格式檢索和顯示YEAR值。范圍是1901到2155。

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

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

· 四位數(shù)字,范圍為1901到2155。

· 兩位字符串,范圍為’00′到’99′。’00′到’69′和’70′到’99′范圍的值被轉(zhuǎn)換為2000到2069和1970到1999范圍的YEAR值。

· 兩位整數(shù),范圍為1到99。1到69和70到99范圍的值被轉(zhuǎn)換為2001到2069和1970到1999范圍的YEAR值。請(qǐng)注意兩位整數(shù)范圍與兩位字符串范圍稍有不同,因?yàn)槟悴荒苤苯訉⒘阒付閿?shù)字并將它解釋為2000。你必須將它指定為一個(gè)字符串’0′或’00′或它被解釋為0000。

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

非法YEAR值被轉(zhuǎn)換為0000。

11.3.4. Y2K事宜和日期類型

MySQL本身對(duì)于2000年(Y2K)是安全的(參見1.4.5節(jié),“2000年兼容性”),但輸入給MySQL的值可能不安全。任何包含兩位年值的輸入都會(huì)令人模糊,因?yàn)槭兰o(jì)不知道。這些值必須解釋為四位形式,因?yàn)镸ySQL內(nèi)部使用四位來保存年。

對(duì)于DATETIME、DATE、TIMESTAMP和YEAR類型,MySQL使用以下規(guī)則解釋含模糊年值的日期:

· 00-69范圍的年值轉(zhuǎn)換為2000-2069。

· 70-99范圍的年值轉(zhuǎn)換為1970-1999。

請(qǐng)記住這些規(guī)則只是合理猜測(cè)數(shù)據(jù)值表示什么。如果MySQL使用的啟發(fā)不能產(chǎn)生正確的值,你應(yīng)提供包含四位年值的確切輸入。

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

部分函數(shù)如MIN()和MAX()將TIMESTAMP或YEAR轉(zhuǎn)換為一個(gè)數(shù)字。這說明使用有兩位年值的值,這些函數(shù)不能工作正確。在這種情況下的修復(fù)方法是將TIMESTAMP或YEAR轉(zhuǎn)換為四位年格式或使用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.4. ENUM類型11.4.5. SET類型

字符串類型指CHAR、VARCHAR、BINARY、VARBINARY、BLOB、TEXT、ENUM和SET。該節(jié)描述了這些類型如何工作以及如何在查詢中使用這些類型。

11.4.1. CHAR和VARCHAR類型

CHAR和VARCHAR類型類似,但它們保存和檢索的方式不同。它們的最大長(zhǎng)度和是否尾部空格被保留等方面也不同。在存儲(chǔ)或檢索過程中不進(jìn)行大小寫轉(zhuǎn)換。

CHAR和VARCHAR類型聲明的長(zhǎng)度表示你想要保存的最大字符數(shù)。例如,CHAR(30)可以占用30個(gè)字符。

CHAR列的長(zhǎng)度固定為創(chuàng)建表時(shí)聲明的長(zhǎng)度。長(zhǎng)度可以為從0到255的任何值。當(dāng)保存CHAR值時(shí),在它們的右邊填充空格以達(dá)到指定的長(zhǎng)度。當(dāng)檢索到CHAR值時(shí),尾部的空格被刪除掉。在存儲(chǔ)或檢索過程中不進(jìn)行大小寫轉(zhuǎn)換。

VARCHAR列中的值為可變長(zhǎng)字符串。長(zhǎng)度可以指定為0到65,535之間的值。(VARCHAR的最大有效長(zhǎng)度由最大行大小和使用的字符集確定。整體最大長(zhǎng)度是65,532字節(jié))。

同CHAR對(duì)比,VARCHAR值保存時(shí)只保存需要的字符數(shù),另加一個(gè)字節(jié)來記錄長(zhǎng)度(如果列聲明的長(zhǎng)度超過255,則使用兩個(gè)字節(jié))。

VARCHAR值保存時(shí)不進(jìn)行填充。當(dāng)值保存和檢索時(shí)尾部的空格仍保留,符合標(biāo)準(zhǔn)SQL。

如果分配給CHAR或VARCHAR列的值超過列的最大長(zhǎng)度,則對(duì)值進(jìn)行裁剪以使其適合。如果被裁掉的字符不是空格,則會(huì)產(chǎn)生一條警告。如果裁剪非空格字符,則會(huì)造成錯(cuò)誤(而不是警告)并通過使用嚴(yán)格SQL模式禁用值的插入。參見5.3.2節(jié),“SQL服務(wù)器模式”。

下面的表顯示了將各種字符串值保存到CHAR(4)和VARCHAR(4)列后的結(jié)果,說明了CHAR和VARCHAR之間的差別:

值 ? ?CHAR(4) ? ?存儲(chǔ)需求 ? ?VARCHAR(4) ? ?存儲(chǔ)需求 ? ?

” ? ?‘ ’ ? ?4個(gè)字節(jié) ? ?” ? ?1個(gè)字節(jié) ? ?

‘a(chǎn)b’ ? ?‘a(chǎn)b ’ ? ?4個(gè)字節(jié) ? ?‘a(chǎn)b ‘ ? ?3個(gè)字節(jié) ? ?

‘a(chǎn)bcd’ ? ?‘a(chǎn)bcd’ ? ?4個(gè)字節(jié) ? ?‘a(chǎn)bcd’ ? ?5個(gè)字節(jié) ? ?

‘a(chǎn)bcdefgh’ ? ?‘a(chǎn)bcd’ ? ?4個(gè)字節(jié) ? ?‘a(chǎn)bcd’ ? ?5個(gè)字節(jié) ? ?

請(qǐng)注意上表中最后一行的值只適用不使用嚴(yán)格模式時(shí);如果MySQL運(yùn)行在嚴(yán)格模式,超過列長(zhǎng)度不的值不保存,并且會(huì)出現(xiàn)錯(cuò)誤。

從CHAR(4)和VARCHAR(4)列檢索的值并不總是相同,因?yàn)闄z索時(shí)從CHAR列刪除了尾部的空格。通過下面的例子說明該差別:

根據(jù)分配給列的字符集校對(duì)規(guī)則對(duì)CHAR和VARCHAR列中的值進(jìn)行排序和比較。

請(qǐng)注意所有MySQL校對(duì)規(guī)則屬于PADSPACE類。這說明在MySQL中的所有CHAR和VARCHAR值比較時(shí)不需要考慮任何尾部空格。例如:

請(qǐng)注意所有MySQL版本均如此,并且它不受SQL服務(wù)器模式的影響。

對(duì)于尾部填充字符被裁剪掉或比較時(shí)將它們忽視掉的情形,如果列的索引需要唯一的值,在列內(nèi)插入一個(gè)只是填充字符數(shù)不同的值將會(huì)造成復(fù)制鍵值錯(cuò)誤。

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

ASCII屬性為CHAR列分配latin1字符集。UNICODE屬性分配ucs2字符集。

11.4.2. BINARY和VARBINARY類型

BINARY和VARBINARY類類似于CHAR和VARCHAR,不同的是它們包含二進(jìn)制字符串而不要非二進(jìn)制字符串。也就是說,它們包含字節(jié)字符串而不是字符字符串。這說明它們沒有字符集,并且排序和比較基于列值字節(jié)的數(shù)值值。

BINARY和VARBINARY允許的最大長(zhǎng)度一樣,如同CHAR和VARCHAR,不同的是BINARY和VARBINARY的長(zhǎng)度是字節(jié)長(zhǎng)度而不是字符長(zhǎng)度。

BINARY和VARBINARY數(shù)據(jù)類型不同于CHAR BINARY和VARCHAR BINARY數(shù)據(jù)類型。對(duì)于后一種類型,BINARY屬性不會(huì)將列視為二進(jìn)制字符串列。相反,它致使使用列字符集的二元 校對(duì)規(guī)則,并且列自身包含非二進(jìn)制字符字符串而不是二進(jìn)制字節(jié)字符串。例如CHAR(5) BINARY被視為CHAR(5) CHARACTER SET latin1 COLLATE latin1_bin,假定默認(rèn)字符集是latin1。這不同于BINARY(5),它保存5字節(jié)二進(jìn)制字符串,沒有字符集或 校對(duì)規(guī)則。

當(dāng)保存BINARY值時(shí),在它們右邊填充值以達(dá)到指定長(zhǎng)度。填充值是0×00(零字節(jié))。插入值時(shí)在右側(cè)添加0×00 on,并且選擇時(shí)不刪除尾部的字節(jié)。比較時(shí)所有字節(jié)很重要,包括ORDER BY和DISTINCT操作。比較時(shí)0×00字節(jié)和空格是不同的,0×00
例如:對(duì)于一個(gè)BINARY(3)列,當(dāng)插入時(shí) ’a’ 變?yōu)?’a ’。’a’插入時(shí)變?yōu)椤痑’。當(dāng)選擇時(shí)兩個(gè)插入的值均不更改。

對(duì)于VARBINARY,插入時(shí)不填充字符,選擇時(shí)不裁剪字節(jié)。比較時(shí)所有字節(jié)很重要,包括ORDER BY和DISTINCT操作。比較時(shí)0×00字節(jié)和空格是不同的,0×00
對(duì)于尾部填充字符被裁剪掉或比較時(shí)將它們忽視掉的情形,如果列的索引需要唯一的值,在列內(nèi)插入一個(gè)只是填充字符數(shù)不同的值將會(huì)造成復(fù)制鍵值錯(cuò)誤。

如果你計(jì)劃使用這些數(shù)據(jù)類型來保存二進(jìn)制數(shù)據(jù)并且需要檢索的值與保存的值完全相同,應(yīng)考慮前面所述的填充和裁剪特征。下面的例子說明了用0×00填充的BINARY值如何影響列值比較:

如果檢索的值必須與指定進(jìn)行存儲(chǔ)而沒有填充的值相同,最好使用BLOB數(shù)據(jù)類型。

創(chuàng)建表時(shí),MySQL可以默默更改BINARY或VARBINARY列的類型。參見13.1.5.1節(jié),“沉寂的列規(guī)格變更”。

11.4.3. BLOB和TEXT類型

BLOB是一個(gè)二進(jìn)制大對(duì)象,可以容納可變數(shù)量的數(shù)據(jù)。有4種BLOB類型:TINYBLOB、BLOB、MEDIUMBLOB和LONGBLOB。它們只是可容納值的最大長(zhǎng)度不同。

有4種TEXT類型:TINYTEXT、TEXT、MEDIUMTEXT和LONGTEXT。這些對(duì)應(yīng)4種BLOB類型,有相同的最大長(zhǎng)度和存儲(chǔ)需求。

參見11.5節(jié),“列類型存儲(chǔ)需求”。

BLOB 列被視為二進(jìn)制字符串(字節(jié)字符串)。TEXT列被視為非二進(jìn)制字符串(字符字符串)。BLOB列沒有字符集,并且排序和比較基于列值字節(jié)的數(shù)值值。TEXT列有一個(gè)字符集,并且根據(jù)字符集的 校對(duì)規(guī)則對(duì)值進(jìn)行排序和比較。

在TEXT或BLOB列的存儲(chǔ)或檢索過程中,不存在大小寫轉(zhuǎn)換。

當(dāng)未運(yùn)行在嚴(yán)格模式時(shí),如果你為BLOB或TEXT列分配一個(gè)超過該列類型的最大長(zhǎng)度的值值,值被截取以保證適合。如果截掉的字符不是空格,將會(huì)產(chǎn)生一條警告。使用嚴(yán)格SQL模式,會(huì)產(chǎn)生錯(cuò)誤,并且值將被拒絕而不是截取并給出警告。參見5.3.2節(jié),“SQL服務(wù)器模式”。

在大多數(shù)方面,可以將BLOB列視為能夠足夠大的VARBINARY列。同樣,可以將TEXT列視為VARCHAR列。BLOB和TEXT在以下幾個(gè)方面不同于VARBINARY和VARCHAR:

· 當(dāng)保存或檢索BLOB和TEXT列的值時(shí)不刪除尾部空格。(這與VARBINARY和VARCHAR列相同)。

請(qǐng)注意比較時(shí)將用空格對(duì)TEXT進(jìn)行擴(kuò)充以適合比較的對(duì)象,正如CHAR和VARCHAR。

· 對(duì)于BLOB和TEXT列的索引,必須指定索引前綴的長(zhǎng)度。對(duì)于CHAR和VARCHAR,前綴長(zhǎng)度是可選的。參見7.4.3節(jié),“列索引”。

· BLOB和TEXT列不能有 默認(rèn)值。

LONG和LONG VARCHAR對(duì)應(yīng)MEDIUMTEXT數(shù)據(jù)類型。這是為了保證兼容性。如果TEXT列類型使用BINARY屬性,將為列分配列字符集的二元 校對(duì)規(guī)則。

MySQL連接程序/ODBC將BLOB值定義為L(zhǎng)ONGVARBINARY,將TEXT值定義為L(zhǎng)ONGVARCHAR。

由于BLOB和TEXT值可能會(huì)非常長(zhǎng),使用它們時(shí)可能遇到一些約束:

· 當(dāng)排序時(shí)只使用該列的前max_sort_length個(gè)字節(jié)。max_sort_length的 默認(rèn)值是1024;該值可以在啟動(dòng)mysqld服務(wù)器時(shí)使用–max_sort_length選項(xiàng)進(jìn)行更改。參見5.3.3節(jié),“服務(wù)器系統(tǒng)變量”。

運(yùn)行時(shí)增加max_sort_length的值可以在排序或組合時(shí)使更多的字節(jié)有意義。任何客戶端可以更改其會(huì)話max_sort_length變量的值:

當(dāng)你想要使超過max_sort_length的字節(jié)有意義,對(duì)含長(zhǎng)值的BLOB或TEXT列使用GROUP BY或ORDER BY的另一種方式是將列值轉(zhuǎn)換為固定長(zhǎng)度的對(duì)象。標(biāo)準(zhǔn)方法是使用SUBSTRING函數(shù)。例如,下面的語(yǔ)句對(duì)comment列的2000個(gè)字節(jié)進(jìn)行排序:

· BLOB或TEXT對(duì)象的最大大小由其類型確定,但在客戶端和服務(wù)器之間實(shí)際可以傳遞的最大值由可用內(nèi)存數(shù)量和通信緩存區(qū)大小確定。你可以通過更改max_allowed_packet變量的值更改消息緩存區(qū)的大小,但必須同時(shí)修改服務(wù)器和客戶端程序。例如,可以使用 mysql和mysqldump來更改客戶端的max_allowed_packet值。參見7.5.2節(jié),“調(diào)節(jié)服務(wù)器參數(shù)”、8.3節(jié),“mysql:MySQL命令行工具”和8.8節(jié),“mysqldump:數(shù)據(jù)庫(kù)備份程序”。

每個(gè)BLOB或TEXT值分別由內(nèi)部分配的對(duì)象表示。這與其它列類型形成對(duì)比,后者是當(dāng)打開表時(shí)為每1列分配存儲(chǔ)引擎。

11.4.4. ENUM類型

ENUM是一個(gè)字符串對(duì)象,其值來自表創(chuàng)建時(shí)在列規(guī)定中顯式枚舉的一列值。

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

· 如果你將一個(gè)非法值插入ENUM(也就是說,允許的值列之外的字符串),將插入空字符串以作為特殊錯(cuò)誤值。該字符串與“普通”空字符串不同,該字符串有數(shù)值值0。后面有詳細(xì)討論。

· 如果將ENUM列聲明為允許NULL,NULL值則為該列的一個(gè)有效值,并且 默認(rèn)值為NULL。如果ENUM列被聲明為NOT NULL,其默認(rèn)值為允許的值列的第1個(gè)元素。

每個(gè)枚舉值有一個(gè)索引:

· 來自列規(guī)定的允許的值列中的值從1開始編號(hào)。

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

· NULL值的索引是NULL。

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

值 ? ?索引 ? ?

NULL ? ?NULL ? ?

” ? ?0 ? ?

‘one’ ? ?1 ? ?

‘two’ ? ?2 ? ?

‘three’ ? ?3 ? ?

枚舉最多可以有65,535個(gè)元素。

當(dāng)創(chuàng)建表時(shí),ENUM成員值的尾部空格將自動(dòng)被刪除。

當(dāng)檢索時(shí),保存在ENUM列的值使用列定義中所使用的大小寫來顯示。請(qǐng)注意可以為ENUM列分配字符集和 校對(duì)規(guī)則。對(duì)于二進(jìn)制或大小寫敏感的校對(duì)規(guī)則,當(dāng)為列分配值時(shí)應(yīng)考慮大小寫。

如果在數(shù)值上下文中檢索一個(gè)ENUM值,將返回列值的索引。例如,你可以這樣從ENUM列搜索數(shù)值值:

如果將一個(gè)數(shù)字保存到ENUM列,數(shù)字被視為索引,并且保存的值是該索引對(duì)應(yīng)的枚舉成員。(但是,這不適合LOAD DATA,它將所有輸入視為字符串)。不建議使用類似數(shù)字的枚舉值來定義一個(gè)ENUM列,因?yàn)檫@很容易引起混淆。例如,下面的列含有字符串值’0′、’1′和’2′的枚舉成員,但數(shù)值索引值為1、2和3:

根據(jù)枚舉成員在列定義中列出的順序?qū)NUM值進(jìn)行排序。(換句話說,ENUM值根據(jù)索引編號(hào)進(jìn)行排序)。例如,對(duì)于ENUM(‘a(chǎn)’,’b’),’a’排在’b’前面,但對(duì)于ENUM(‘b’,’a’),’b’排在’a’前面。空字符串排在非空字符串前面,并且NULL值排在所有其它枚舉值前面。要想防止意想不到的結(jié)果,按字母順序規(guī)定ENUM列。還可以使用GROUP BY CAST(col AS CHAR)或GROUP BY CONCAT(col)來確保按照詞匯對(duì)列進(jìn)行排序而不是用索引數(shù)字。

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

11.4.5. SET類型

SET是一個(gè)字符串對(duì)象,可以有零或多個(gè)值,其值來自表創(chuàng)建時(shí)規(guī)定的允許的一列值。指定包括多個(gè)SET成員的SET列值時(shí)各成員之間用逗號(hào)(‘,’)間隔開。這樣SET成員值本身不能包含逗號(hào)。

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

SET最多可以有64個(gè)不同的成員。

當(dāng)創(chuàng)建表時(shí),SET成員值的尾部空格將自動(dòng)被刪除。

當(dāng)檢索時(shí),保存在SET列的值使用列定義中所使用的大小寫來顯示。請(qǐng)注意可以為SET列分配字符集和 校對(duì)規(guī)則。對(duì)于二進(jìn)制或大小寫敏感的校對(duì)規(guī)則,當(dāng)為列分配值時(shí)應(yīng)考慮大小寫。

MySQL用數(shù)字保存SET值,所保存值的低階位對(duì)應(yīng)第1個(gè)SET成員。如果在數(shù)值上下文中檢索一個(gè)SET值,檢索的值的位設(shè)置對(duì)應(yīng)組成列值的SET成員。例如,你可以這樣從一個(gè)SET列檢索數(shù)值值:

如果將一個(gè)數(shù)字保存到SET列中,數(shù)字中二進(jìn)制表示中的位確定了列值中的SET成員。對(duì)于指定為SET(‘a(chǎn)’,’b’,’c’,’d’)的列,成員有下面的十進(jìn)制和二進(jìn)制值:

SET成員 ? ?十進(jìn)制值 ? ?二進(jìn)制值 ? ?

‘a(chǎn)’ ? ?1 ? ?0001 ? ?

‘b’ ? ?2 ? ?0010 ? ?

‘c’ ? ?4 ? ?0100 ? ?

‘d’ ? ?8 ? ?1000 ? ?

如果你為該列分配一個(gè)值9,其二進(jìn)制形式為1001,因此第1個(gè)和第4個(gè)SET值成員’a’和’d’被選擇,結(jié)果值為 ’a,d’。

對(duì)于包含多個(gè)SET元素的值,當(dāng)插入值時(shí)元素所列的順序并不重要。在值中一個(gè)給定的元素列了多少次也不重要。當(dāng)以后檢索該值時(shí),值中的每個(gè)元素出現(xiàn)一次,根據(jù)表創(chuàng)建時(shí)指定的順序列出元素。例如,假定某個(gè)列指定為SET(‘a(chǎn)’,’b’,’c’,’d’):

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

當(dāng)檢索時(shí)所有這些值顯示為 ’a,d’:

如果將SET列設(shè)置為一個(gè)不支持的值,則該值被忽略并發(fā)出警告:

SET值按數(shù)字順序排序。NULL值排在非NULL SET值的前面。

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

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

下面的語(yǔ)句也是合法的:

第1個(gè)語(yǔ)句尋找包含第1個(gè)set成員的值。第2個(gè)語(yǔ)句尋找一個(gè)確切匹配的值。應(yīng)注意第2類的比較。將set值與’val1,val2‘比較返回的結(jié)果與同’val2,val1‘比較返回的結(jié)果不同。指定值時(shí)的順序應(yīng)與在列定義中所列的順序相同。

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

11.5. 列類型存儲(chǔ)需求

根據(jù)類別列出了MySQL支持的每個(gè)列類型的存儲(chǔ)需求。

MyISAM表中行的最大大小為65,534字節(jié)。每個(gè)BLOB和TEXT列 賬戶只占其中的5至9個(gè)字節(jié)。

如果MyISAM表包括變長(zhǎng)列類型,記錄格式也是可變長(zhǎng)度。當(dāng)創(chuàng)建表時(shí),在某些條件下,MySQL可以將一個(gè)列從變長(zhǎng)類型改為固定長(zhǎng)度的類型或反之亦然。詳細(xì)信息參見13.1.5.1節(jié),“沉寂的列規(guī)格變更”。

數(shù)值類型存儲(chǔ)需求

列類型 ? ?存儲(chǔ)需求 ? ?

TINYINT ? ?1個(gè)字節(jié) ? ?

SMALLINT ? ?2個(gè)字節(jié) ? ?

MEDIUMINT ? ?3個(gè)字節(jié) ? ?

INT, INTEGER ? ?4個(gè)字節(jié) ? ?

BIGINT ? ?8個(gè)字節(jié) ? ?

FLOAT(p) ? ?如果0

FLOAT ? ?4個(gè)字節(jié) ? ?

DOUBLE [PRECISION], item REAL ? ?8個(gè)字節(jié) ? ?

DECIMAL(M,D), NUMERIC(M,D) ? ?變長(zhǎng);參見下面的討論 ? ?

BIT(M) ? ?大約(M+7)/8個(gè)字節(jié) ? ?

DECIMAL(和NUMERIC)的存儲(chǔ)需求與具體版本有關(guān):

使用二進(jìn)制格式將9個(gè)十進(jìn)制(基于10)數(shù)壓縮為4個(gè)字節(jié)來表示DECIMAL列值。每個(gè)值的整數(shù)和分?jǐn)?shù)部分的存儲(chǔ)分別確定。每個(gè)9位數(shù)的倍數(shù)需要4個(gè)字節(jié),并且“剩余的”位需要4個(gè)字節(jié)的一部分。下表給出了超出位數(shù)的存儲(chǔ)需求:

剩余的 ? ?字節(jié) ? ?

位數(shù) ? ?數(shù)目 ? ?

0 ? ?0 ? ?

1 ? ?1 ? ?

2 ? ?1 ? ?

3 ? ?2 ? ?

4 ? ?2 ? ?

5 ? ?3 ? ?

6 ? ?3 ? ?

7 ? ?4 ? ?

8 ? ?4 ? ?

9 ? ?4 ? ?

日期和時(shí)間類型的存儲(chǔ)需求

列類型 ? ?存儲(chǔ)需求 ? ?

DATE ? ?3個(gè)字節(jié) ? ?

DATETIME ? ?8個(gè)字節(jié) ? ?

TIMESTAMP ? ?4個(gè)字節(jié) ? ?

TIME ? ?3個(gè)字節(jié) ? ?

YEAR ? ?1個(gè)字節(jié) ? ?

字符串類型的存儲(chǔ)需求

列類型 ? ?存儲(chǔ)需求 ? ?

CHAR(M) ? ?M個(gè)字節(jié),0

VARCHAR(M) ? ?L+1個(gè)字節(jié),其中L

BINARY(M) ? ?M個(gè)字節(jié),0

VARBINARY(M) ? ?L+1個(gè)字節(jié),其中L

TINYBLOB, TINYTEXT ? ?L+1個(gè)字節(jié),其中L

BLOB, TEXT ? ?L+2個(gè)字節(jié),其中L

MEDIUMBLOB, MEDIUMTEXT ? ?L+3個(gè)字節(jié),其中L

LONGBLOB, LONGTEXT ? ?L+4個(gè)字節(jié),其中L

ENUM(‘value1‘,’value2‘,…) ? ?1或2個(gè)字節(jié),取決于枚舉值的個(gè)數(shù)(最多65,535個(gè)值) ? ?

SET(‘value1‘,’value2‘,…) ? ?1、2、3、4或者8個(gè)字節(jié),取決于set成員的數(shù)目(最多64個(gè)成員) ? ?

VARCHAR、BLOB和TEXT類是變長(zhǎng)類型。每個(gè)類型的存儲(chǔ)需求取決于列值的實(shí)際長(zhǎng)度(用前面的表中的L表示),而不是該類型的最大可能的大小。例如,VARCHAR(10)列可以容納最大長(zhǎng)度為10的字符串。實(shí)際存儲(chǔ)需求是字符串(L)的長(zhǎng)度,加上一個(gè)記錄字符串長(zhǎng)度的字節(jié)。對(duì)于字符串’abcd’,L是4,存儲(chǔ)需要5個(gè)字節(jié)。

對(duì)于CHAR、VARCHAR和TEXT類型,前面的表中的值L和M應(yīng)解釋為字符數(shù)目,并且列定義中的這些類型的長(zhǎng)度表示字符數(shù)目。例如,要想保存一個(gè)TINYTEXT值需要L字符+
1個(gè)字節(jié)。

要想計(jì)算用于保存具體CHAR、VARCHAR或者TEXT列值的字節(jié)數(shù),需要考慮該列使用的字符集。在具體情況中,當(dāng)使用Unicode時(shí),必須記住所有Unicode字符使用相同的字節(jié)數(shù)。為了細(xì)分用于不同類Unicode字符使用的存儲(chǔ),參見10.5節(jié),“Unicode支持”。

注釋:VARCHAR列的有效最大長(zhǎng)度為65,532字符。

NDBCLUSTER引擎只支持固定寬度的列。這說明MySQL簇中的表中的VARCHAR列的行為如同類型CHAR(不同的是每個(gè)記錄仍然有一個(gè)額外字節(jié)空間)。例如,在Cluster表中,聲明為VARCHAR(100)的列中的每個(gè)記錄存儲(chǔ)時(shí)將占用101個(gè)字節(jié),無論實(shí)際存儲(chǔ)的記錄中的字符串的長(zhǎng)度為多少。

BLOB和TEXT類需要 1、2、3或者4個(gè)字節(jié)來記錄列值的長(zhǎng)度,取決于該類的最大可能的長(zhǎng)度。參見11.4.3節(jié),“BLOB和TEXT類型
”。

在NDB Cluster存儲(chǔ)引擎中,TEXT和BLOB列的實(shí)施是不同的,其中TEXT列中的每個(gè)記錄由兩個(gè)單獨(dú)部分組成。一個(gè)是固定大小(256字節(jié)),并且實(shí)際上保存在原表中。另一個(gè)包括超出256字節(jié)的任何數(shù)據(jù),保存在隱含的表中。第2個(gè)表中的記錄總是2,000字節(jié)長(zhǎng)。這說明如果size+size+(2000–(size–256)%2000)。

ENUM對(duì)象的大小由不同的枚舉值的數(shù)目確定。枚舉用一個(gè)字節(jié),可以有255個(gè)可能的值。當(dāng)枚舉的值位于256和65,535之間時(shí),用兩個(gè)字節(jié)。參見11.4.4節(jié),“ENUM類型”。

SET對(duì)象的大小由不同的set成員的數(shù)量確定。如果set大小是N,對(duì)象占(N+7)/8個(gè)字節(jié),四舍五入到1、2、3、4或者8個(gè)字節(jié)。SET最多可以有64個(gè)成員。參見11.4.5節(jié),“SET類型”。

11.6. 選擇正確的列類型

為了優(yōu)化存儲(chǔ),在任何情況下均應(yīng)使用最精確的類型。例如,如果列的值的范圍為從1到99999,若使用整數(shù),則MEDIUMINT
UNSIGNED是好的類型。在所有可以表示該列值的類型中,該類型使用的存儲(chǔ)最少。

用精度為65位十進(jìn)制數(shù)(基于10)對(duì)DECIMAL 列進(jìn)行所有基本計(jì)算(+、-、*、/)。參見11.1.1節(jié),“數(shù)值類型概述”。

使用雙精度操作對(duì)DECIMAL值進(jìn)行計(jì)算。如果準(zhǔn)確度不是太重要或如果速度為最高優(yōu)先級(jí),DOUBLE類型即足夠了。為了達(dá)到高精度,可以轉(zhuǎn)換到保存在BIGINT中的定點(diǎn)類型。這樣可以用64位整數(shù)進(jìn)行所有計(jì)算,根據(jù)需要將結(jié)果轉(zhuǎn)換回浮點(diǎn)值。

11.7. 使用來自其他數(shù)據(jù)庫(kù)引擎的列類型

為了使用由其它賣方編寫的SQL執(zhí)行代碼,MySQL按照下表所示對(duì)列類型進(jìn)行映射。通過這些映射,可以很容易地從其它數(shù)據(jù)庫(kù)引擎將表定義導(dǎo)入到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 ? ?

在創(chuàng)建表時(shí)對(duì)列類型進(jìn)行映射,然后原來的類型定義被丟棄。如果你使用其它賣方的類型創(chuàng)建一個(gè)表,然后執(zhí)行DESCRIBE tbl_name語(yǔ)句,MySQL使用等效的MySQL類型來報(bào)告表的結(jié)構(gòu)。

?以上就是MySQL學(xué)習(xí)系列3:數(shù)據(jù)類型的內(nèi)容,更多相關(guān)內(nèi)容請(qǐng)關(guān)注PHP中文網(wǎng)(www.php.cn)!

? 版權(quán)聲明
THE END
喜歡就支持一下吧
點(diǎn)贊13 分享