MySQL支持所有的ANSI/ISO
SQL92的數字類型。這些類型包括準確數字的數據類型(NUMERIC,
DECIMAL,
INTEGER,和SMALLINT),也包括近似數字的數據類型(FLOAT,
REAL,和DOUBLE
PRECISION)。關鍵詞INT是INTEGER的一個同義詞,而關鍵詞DEC是DECIMAL一個同義詞。
NUMERIC和DECIMAL類型被MySQL實現為同樣的類型,這在SQL92標準允許。他們被用於保存值,該值的準確精度是極其重要的值,例如與金錢有關的數據。當聲明一個類是這些類型之一時,精度和規模的能被(並且通常是)指定﹔例如:
salary DECIMAL(9,2)
在這個例子中,9(precision)代表將被用於存儲值的總的小數位數,而2(scale)代表將被用於存儲小數點後的位數。因此,在這種情況下,能被存儲在salary列中的值的範圍是從-9999999.99到9999999.99。在ANSI/ISO
SQL92中,句法DECIMAL(p)等價於DECIMAL(p,0)。同樣,句法DECIMAL等價於DECIMAL(p,0),這裡實現被允許決定值p。MySQL當前不支持DECIMAL/NUMERIC數據類型的這些變種形式的任一種。這一般說來不是一個嚴重的問題,因為這些類型的主要益處得自於明顯地控制精度和規模的能力。
DECIMAL和NUMERIC值作為字符串存儲,而不是作為二進制浮點數,以便保存那些值的小數精度。一個字符用於值的每一位、小數點(如果scale>0)和“-”符號(對於負值)。如果scale是0,DECIMAL和NUMERIC值不包含小數點或小數部分。
DECIMAL和NUMERIC值得最大的範圍與DOUBLE一樣,但是對於一個給定的DECIMAL或NUMERIC列,實際的範圍可由制由給定列的precision或scale限制。當這樣的列賦給了小數點後面的位超過指定scale所允許的位的值,該值根據scale四舍五入。當一個DECIMAL或NUMERIC列被賦給了其大小超過指定(或缺省的)precision和scale隱含的範圍的值,MySQL存儲表示那個範圍的相應的端點值。
作為對ANSI/ISO
SQL92標準的擴展,MySQL也支持上表所列的整型類型TINYINT、MEDIUMINT和BIGINT。另一個擴展是MySQL支持可選地指定一個整型值顯示的寬度,用括號跟在基本關鍵詞之後(例如,INT(4))。這個可選的寬度指定被用於其寬度小於列指定寬度的值得左填補顯示,但是不限制能在列中被存儲的值的範圍,也不限制值將被顯示的位數,其寬度超過列指定的寬度。當與可選的擴展屬性ZEROFILL一起使用時,缺省的空格填補用零代替。例如,對於聲明為INT(5)
ZEROFILL的列,一個為4的值作為00004被檢索。注意,如果你在一個整型列存儲超過顯示寬度的更大值,當MySQL對於某些復雜的聯結(join)生成臨時表時,你可能會遇到問題,因為在這些情況下,MySQL相信數據確實適合原來的列寬度。
所有的整型類型可以有一個可選(非標準的)屬性UNSIGNED。當你想要在列中僅允許正數並且你需要一個稍大一點的列範圍,可以使用無符號值。
FLOAT類型被用來標示近似數字的數據類型。ANSI/ISO
SQL92標準允許一個可選的精度說明(但不是指數的範圍),跟在關鍵詞FLOAT後面的括號內位數。MySQL實現也支持這個可選的精度說明。當關鍵詞FLOAT被用於一個列類型而沒有精度說明時,MySQL使用4個字節存儲值。一個變種的句法也被支持,在FLOAT關鍵詞後面的括號給出2個數字。用這個選項,第一個數字繼續表示在字節計算的值存儲需求,而第二個數字指定要被存儲的和顯示跟隨小數點後的位數(就像DECIMAL和NUMERIC)。當MySQL要求為這樣一個列,一個小數點後的小數位超過列指定的值,存儲值時,該值被四舍五入,去掉額外的位。
REAL和DOUBLE
PRECISION類型不接受精度說明。作為對
ANSI/ISO SQL92 標準的擴展,MySQL識別出DOUBLE作為DOUBLE
PRECISION類型的一個同義詞。與REAL精度比用於DOUBLE
PRECISION的更小的標準要求相反,MySQL實現了兩種,作為8字節雙精度浮點值(當運行不是“Ansi模式”時)。為了最大的移植性,近似數字的數據值的存儲所需代碼應該使用沒有精度或小數位數說明的FLOAT或DOUBLE
PRECISION。
當要求在數字的列存儲超出該列類型允許的範圍的值時,MySQL剪切該值到範圍內的正確端點值並且存儲剪切後的結果值。
例如,一個INT列的範圍是-2147483648到2147483647。如果你試圖插入-9999999999到一個INT列中,值被剪切到範圍的低部端點,並存儲-2147483648。同樣,如果你試圖插入9999999999,2147483647被存儲。
如果INT列是UNSIGNED,列的範圍的大小是相同的,但是它的端點移到了0和4294967295。如果你試圖存儲-9999999999和9999999999,在列被存儲的值變為0和4294967296。
對於ALTER
TABLE、LOAD
DATA INFILE、UPDATE和多行INSERT語句,由於剪切所發生的變換作為“警告”被報告。
日期和時間類型是DATETIME、DATE、TIMESTAMP、TIME和YEAR。這些的每一個都有合法值的一個範圍,而“零”當你指定確實不合法的值時被使用。注意,MySQL允許你存儲某個“不嚴格地”合法的日期值,例如1999-11-31,原因我們認為它是應用程序的責任來處理日期檢查,而不是SQL服務器。為了使日期檢查更“快”,MySQL僅檢查月份在0-12的範圍,天在0-31的範圍。上述範圍這樣被定義是因為MySQL允許你在一個DATE或DATETIME列中存儲日期,這裡的天或月是零。這對存儲你不知道準確的日期的一個生日的應用程序來說是極其有用的,在這種情況下,你簡單地存儲日期像1999-00-00或1999-01-00。(當然你不能期望從函數如DATE_SUB()或DATE_ADD()得到類似以這些日期的正確值)。
當用日期和時間工作時,這裡是的一些要記住的一般考慮:
MySQL對一個給定的日期或時間類型以標準的格式檢索,但是它試圖為你提供的值解釋成許多格式(例如,當你指定一個值被賦給或與比較一個日期或時間類型時),但是只支持有在下列小節描述的格式。期望你提供合法的值,並且如果你以其他格式使用這些值,可能造成無法預料的結果。
盡管MySQL試圖以多種格式解釋值,但它總是期望日期值的年份部分在最左面,日期必須以年-月-日的順序給出(例如,'98-09-04'),而不是以其他地方常用的月-日-年或日-月-年的次序(例如,'09-04-98'、'04-09-98')。
如果一個值在數字的上下文環境中被使用,MySQL自動變換一個日期或時間類型值到一個數字,反過來也如此。
當MySQL遇到一個日期或時間類型的值超出範圍或對給類型不合法(見本節的開始)時,它將該類型的值變換到“零”值。(例外的是超出範圍的TIME值被剪切為適當的TIME範圍端點值。)下表顯示對每種類型的“零”值的格式:
|
列類型 |
“零”值 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
“零”值是特殊的,但是你能使用在表中顯示的值來明顯地存儲或引用他們。你也可以使用值'0'或0做到,
這更容易寫。
在MyODBC
2.50.12和以上版本中,由MyODBC使用的“零”日期或時間值被自動變換到NULL,因為ODBC不能處理這樣的值。
MySQL本身Y2K安全的(見1.6 2000年一致性),但是呈交給MySQL的輸入值可能不是。一個包含2位年份值的任何輸入是由二義性的,因為世紀是未知的。這樣的值必須被解釋成4位形式,因為MySQL內部使用4位存儲年份。
對於DATETIME,
DATE,
TIMESTAMP和YEAR類型,MySQL使用下列規則的解釋二義性的年份值:
在範圍00-69的年值被變換到2000-2069。
在範圍70-99的年值被變換到1970-1999。
記得這些規則僅僅提供對於你數據的含義的合理猜測。如果MySQL使用的啟發規則不產生正確的值,你應該提供無二義的包含4位年值的輸入。
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列類型提供一種類型,你可以使用它自動地用當前的日期和時間標記INSERT或UPDATE的操作。如果你有多個TIMESTAMP列,只有第一個自動更新。
自動更新第一個TIMESTAMP列在下列任何條件下發生:
列沒有明確地在一個INSERT或LOAD
DATA INFILE語句中指定。
列沒有明確地在一個UPDATE語句中指定且一些另外的列改變值。(注意一個UPDATE設置一個列為它已經有的值,這將不引起TIMESTAMP列被更新,因為如果你設置一個列為它當前的值,MySQL為了效率而忽略更改。)
你明確地設定TIMESTAMP列為NULL.
除第一個以外的TIMESTAMP列也可以設置到當前的日期和時間,只要將列設為NULL,或NOW()。
通過明確地設置希望的值,你可以設置任何TIMESTAMP列為不同於當前日期和時間的值,即使對第一個TIMESTAMP列也是這樣。例如,如果,當你創建一個行時,你想要一個TIMESTAMP被設置到當前的日期和時間,但在以後無論何時行被更新時都不改變,你可以使用這個屬性:
讓MySQL在行被創建時設置列,這將初始化它為當前的日期和時間。
當你執行隨後的對該行中其他列的更改時,明確設定TIMESTAMP列為它的當前值。
另一方面,你可能發現,當行被創建並且遠離隨後的更改時,很容易用一個你用NOW()初始化的DATETIME列。
TIMESTAMP值可以從1970的某時的開始一直到2037年,精度為一秒,其值作為數字顯示。
在MySQL檢索並且顯示TIMESTAMP值取決於顯示尺寸的格式如下表。“完整”TIMESTAMP格式是14位,但是TIMESTAMP列可以用更短的顯示尺寸創造:
|
列類型 |
顯示格式 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
所有的TIMESTAMP列都有同樣的存儲大小,不考慮顯示尺寸。最常見的顯示尺寸是6、8、12、和14。你可以在表創建時間指定一個任意的顯示尺寸,但是值0或比14大被強制到14。在從1∼13範圍的奇數值尺寸被強制為下一個更大的偶數。
使用一個常用的格式集的任何一個,你可以指定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',但是'971122459015'是不合法的(它有毫無意義的分鐘部分)且變成'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的月或天的值指定2位數字,'1979-6-9'與'1979-06-09'是一樣的。同樣,
對於包括的時間部分分隔符的指定為字符串的值,不必為小於10的小時、月或秒指定2位數字,'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,但是日期部分丟失(零),因此該值不是一個合法的日期。
TIMESTAMP列使用被指定的值的完整精度的存儲合法的值,不考慮顯示大小。這有幾個含意:
總是指定年,月,和日,即使你的列類型是TIMESTAMP(4)或TIMESTAMP(2)。否則,值將不是一個合法的日期並且0將被存儲。
如果你使用ALTER
TABLE拓寬一個狹窄的TIMESTAMP列,以前被“隱蔽”的信息將被顯示。
同樣,縮小一個TIMESTAMP列不會導致信息失去,除了感覺上值在顯示時,較少的信息被顯示出。
盡管TIMESTAMP值被存儲為完整精度,直接操作存儲值的唯一函數是UNIX_TIMESTAMP(),其他函數操作在格式化了的檢索的值上,這意味著你不能使用函數例如HOUR()或SECOND(),除非TIMESTAMP值的相關部分被包含在格式化的值中。例如,一個TIMESTAMP列的HH部分部被顯示,除非顯示大小至少是10,因此在更短的TIMESTAMP值上試試使用HOUR()產生一個無意義的結果。
在某種程度上,你可以把一種日期類型的值賦給一個不同的日期類型的對像。然而,這可能值有一些改變或信息的損失:
如果你將一個DATE值賦給一個DATETIME或TIMESTAMP對像,結果值的時間部分被設置為'00:00:00',因為DATE值不包含時間信息。
如果你將一個DATETIME或TIMESTAMP值賦給一個DATE對像,結果值的時間部分被刪除,因為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'不是一個合法的月份。
以2位數字指定的年值是模糊的,因為世紀是未知的。MySQL使用下列規則解釋2位年值:
在00-69範圍的年值被變換到2000-2069。
在范70-99圍的年值被變換到1970-1999。
TIME類型MySQL檢索並以'HH:MM:SS'格式顯示TIME值(或對大小時值,'HHH:MM:SS'格式)。TIME值的範圍可以從'-838:59:59'到'838:59:59'。小時部分可能很大的的原因是TIME類型不僅可以被使用在表示一天的時間(它必須是不到24個小時),而且用在表示在2個事件之間經過的時間或時間間隔(它可以是比24個小時大些,或甚至是負值)。
你能用多中格式指定TIME值:
作為'HH:MM:SS'格式的一個字符串。“寬松”的語法被允許--任何標點符號可用作時間部分的分隔符,例如,'10:11:12'和'10.11.12'是等價的。
作為沒有分隔符的'HHMMSS'格式的一個字符串,如果它作為一個時間解釋。例如,'101112'被理解為'10:11:12',但是'109712'是不合法的(它有無意義的分鐘部分)並變成'00:00:00'。
作為HHMMSS格式的一個數字,如果它能解釋為一個時間。例如,101112被理解為'10:11:12'。
返回值可在一個TIME上下文接受的函數,例如CURRENT_TIME。
對於作為包括一個時間分隔符的字符串被指定的TIME值,不必為小於10的小時、分鐘或秒值指定2位數字,'8:3:2'與'08:03:02'是一樣的。
將“短的”TIME值賦值給一個TIME行列是要格外小心。MySQL使用最右位代表秒的假設來解釋值。(MySQL將TIME值解釋為經過的時間,而非作為一天的時間
)例如,你可能想到'11:12'、'1112'和1112意味著'11:12:00'(11點12分),但是MySQL解釋他們為'00:11:12'(11分12秒)。同樣,'12'和12被解釋為'00:00: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'或它是否是不合法的。
YEAR類型YEAR類型是一個
1 字節類型用於表示年份。
MySQL檢索並且以YYYY格式顯示YEAR值,其範圍是1901到2155。
你能用多種格式指定YEAR值:
作為在'1901'到'2155'範圍的一個4位字符串。
作為在1901到2155範圍的一個4位數字。
作為在'00'到'99'範圍的一個2位字符串.在'00'到'69'和'70'到'99'範圍的值被變換到在2000到2069範圍和1970到1999的YEAR值。
作為在1到99範圍的一個2位數字。在範圍1到69和70到99的值被變換到在範圍2001到2069和1970到1999的YEAR的值。注意對於2位數字的範圍略微不同於2位數字字符串的範圍,因為你不能直接指定零作為一個數字並且把它解釋為2000。你必須作為一個字符串'0'或'00'指定它,它將被解釋為0000。
其返回值可在一個YEAR上下文環境中接受的函數,例如NOW()。
不合法YEAR值被變換到0000。
字符串類型是CHAR、VARCHAR、BLOB、TEXT、ENUM和SET。
CHAR和VARCHAR類型CHAR和VARCHAR類型是類似的,但是在他們被存儲和檢索的方式不同。
一個CHAR列的長度被修正為在你創造表時你所聲明的長度。長度可以是1和255之間的任何值。(在MySQL
3.23中,CHAR長度可以是0∼255。)
當CHAR值被存儲時,他們被用空格在右邊填補到指定的長度。當CHAR值被檢索時,拖後的空格被刪去。
在VARCHAR列中的值是變長字符串。你可以聲明一個VARCHAR列是在1和255之間的任何長度,就像對CHAR列。然而,與CHAR相反,VARCHAR值只存儲所需的字符,外加一個字節記錄長度,值不被填補﹔相反,當值被存儲時,拖後的空格被刪去。(這個空格刪除不同於ANSI
SQL規范。)
如果你把一個超過列最大長度的值賦給一個CHAR或VARCHAR列,值被截斷以適合它。
下表顯示了兩種類型的列的不同,通過演示存儲變長字符串值到CHAR(4)和VARCHAR(4)列:
|
值 |
|
存儲需求 |
|
存儲需求 |
|
|
|
4 個字節 |
|
1 字節 |
|
|
|
4 個字節 |
|
3 個字節 |
|
|
|
4 個字節 |
|
5 個字節 |
|
|
|
4 個字節 |
|
5 個字節 |
從CHAR(4)和VARCHAR(4)列檢索的值在每種情況下都是一樣的,因為拖後的空格從檢索的CHAR列上被刪除。
在CHAR和VARCHAR列中存儲和比較值是以大小寫不區分的方式進行的,除非當桌子被創建時,BINARY屬性被指定。BINARY屬性意味著該列的值根據MySQL服務器正在運行的機器的ASCII順序以大小寫區分的方式存儲和比較。
BINARY屬性是“粘性”的。這意味著,如果標記了BINARY的列用於一個表達式中,整個的表達式作為一個BINARY值被比較。
MySQL在表創建時可以隱含地改變一個CHAR或VARCHAR列的類型。見7.7.1
隱含的的列說明改變。
BLOB和TEXT類型一個BLOB是一個能保存可變數量的數據的二進制的大對像。4個BLOB類型TINYBLOB、BLOB、MEDIUMBLOB和LONGBLOB僅僅在他們能保存值的最大長度方面有所不同。見7.3.1
列類型存儲需求。
4個TEXT類型TINYTEXT、TEXT、MEDIUMTEXT和LONGTEXT對應於4個BLOB類型,並且有同樣的最大長度和存儲需求。在BLOB和TEXT類型之間的唯一差別是對BLOB值的排序和比較以大小寫敏感方式執行,而對TEXT值是大小寫不敏感的。換句話說,一個TEXT是一個大小寫不敏感的BLOB。
如果你把一個超過列類型最大長度的值賦給一個BLOB或TEXT列,值被截斷以適合它。
在大多數方面,你可以認為一個TEXT行列是你所希望大的一個VARCHAR列。同樣,你可以認為一個BLOB列是一個VARCHAR
BINARY列。差別是:
用MySQL版本3.23.2和更新,你能在BLOB和TEXT列上索引。更舊的MySQL版本不支持這個。
當值被存儲時,對BLOB和TEXT列沒有拖後空格的刪除,因為對VARCHAR列有刪除。
MyODBC定義BLOB為LONGVARBINARY,TEXT值為LONGVARCHAR。
因為BLOB和TEXT值可以是非常長的,當使用他們時,你可能遇到一些限制:
如果你想要在一個BLOB或TEXT列上使用GROUP
BY或ORDER
BY,你必須將列值變換成一個定長對像。這樣做的標準方法是用SUBSTRING函數。例如:
mysql> select comment from tbl_name,substring(comment,20) as substr ORDER BY substr;
如果你不這樣做,在排序時,只有列的首max_sort_length個字節被使用,缺省的max_sort_length是1024﹔這個值能在啟動mysqld服務器時使用-O選擇改變。你可以在包含BLOB或TEXT值得一個表達式上分組(group),通過指定列的位置或使用一個別名:
mysql> select id,substring(blob_col,1,100) from tbl_name GROUP BY 2; mysql> select id,substring(blob_col,1,100) as b from tbl_name GROUP BY b;
一個BLOB或TEXT對像的最大尺寸由其類型決定,但是你能在客戶與服務器之間是實際傳輸的最大值由可用的內存數量和通訊緩沖區的大小來決定。你能改變消息緩沖區大小,但是你必須在服務器和客戶兩端做。見10.2.3
調節服務器參數。
注意,每個BLOB或TEXT值內部由一個獨立分配的對像表示。這與所有的其他列類型相反,它們是在打開表時,按列被分配一次存儲。
ENUM類型一個ENUM是一個字符對像,其值通常從一個在表創建時明確被列舉的允許值的一張表中選擇。
在下列的某個情形下,值也可以空字符串("")或NULL:
如果你把一個無效值插入到一個ENUM(即,一個不在允許的值列表中的字符串),空字符串作為一個特殊錯誤的值被插入。
如果一個ENUM被聲明為NULL,NULL也是列的合法值,並且缺省值是NULL。如果一個ENUM被聲明為NOT
NULL,缺省值是允許值的列表的第一成員。
每枚舉值有一個編號:
在列說明中來自允許成員值列表值用從1開始編號。
空字符串錯誤值的編號值是0。這意味著,你能使用下列SELECT語句找出被賦給無效ENUM值的行:
mysql> SELECT * FROM tbl_name WHERE enum_col=0;
NULL值的編號是NULL。
例如,指定為ENUM("one",
"two", "three")的列可以有顯示在下面的值的任何一個。每個值的編號也被顯示:
|
值 |
編號 |
|
|
|
|
|
0 |
|
|
1 |
|
|
2 |
|
|
3 |
枚舉可以有最大65535個成員。
當你把值賦給一個ENUM列時,字母的大小寫是無關緊要的。然而,以後從列中檢索的值大小寫匹配在表創建時用來指定允許值的值的大小寫。
如果你在一個數字的上下文環境中檢索一個ENUM,列值的編號被返回。如果你存儲一個數字到一個ENUM中,數字被當作一個標號,並且存儲的值是該編號的枚舉成員。
ENUM值根據列說明列舉的枚舉成員的次序被排序。(換句話說,ENUM值根據他們的編號數字被排序)
例如,對ENUM("a",
"b"),"a"排在"b"前面,但是對ENUM("b",
"a"),"b"排在"a"前面。空字符串排序非空字符串之前,並且NULL排在所有其他枚舉值之前。
如果你想要得到一個ENUM列的所有可能的值,你應該使用:SHOW
COLUMNS FROM table_name LIKE enum_column_name並且分析在第二列的ENUM定義。
SET類型一個SET是可以有零或多個值的一個字符串對像,其每一個必須從表創建造被指定了的允許值的一張列表中被選擇。由多個集合成員組成的SET列通過由由逗號分隔(“,”)的成員被指定,其推論是該SET成員值不能包含逗號本身。
例如,
一個指定為SET("one",
"two") NOT NULL的列可以有這些值的任何一個:
"" "one" "two" "one,two" 一個SET能有最多64個不同的成員。
MySQL用數字值存儲SET值,存儲值的低階位對應於第一個集合成員。如果你在數字上下文中檢索一個SET值,檢索的值把位設置位對應組成列值的集合成員。如果一個數字被存儲進一個SET列,在數字的二進制表示中設置的位決定了在列中的集合成員。假定一個列被指定為SET("a","b","c","d"),那麼成員有下列位值:
|
|
十進制的值 |
二進制的值 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
如果你給該列賦值9,即二進制的1001,這樣第一個和第四個SET值成員"a"和"d"被選擇並且結果值是"a,d"。
對於包含超過一個SET成員的值,當你插入值時,無所謂以什麼順序列舉值,也無所謂給定的值列舉了多少次。當以後檢索值時,在值中的每個成員將出現一次,根據他們在表創建時被指定的順序列出成員。例如,如果列指定為SET("a","b","c","d"),那麼"a,d"、"d,a"和"d,a,a,d,d"在檢索時將均作為"a,d"出現。
SET值以數字次序被排序。NULL指排在非NULL
SET值之前。
通常,你使用LIKE操作符或FIND_IN_SET()函數執行在一個SET上的一個SELECT:
mysql> SELECT * FROM tbl_name WHERE set_col LIKE '%value%'; mysql> SELECT * FROM tbl_name WHERE FIND_IN_SET('value',set_col)>0;
但是下列也會工作:
mysql> SELECT * FROM tbl_name WHERE set_col = 'val1,val2'; mysql> SELECT * FROM tbl_name WHERE set_col & 1;
這些語句的第一個語句尋找一個精確的匹配。第二個尋找包含第一個集合成員的值。
如果你想要得到一個SET列的所有可能的值,你應該使用:SHOW
COLUMNS FROM table_name LIKE set_column_name並且分析在第二列的SET定義。
為了最有效地使用存儲空間,試著在所有的情況下使用最精確的類型。例如,如果一個整數列被用於在之間1和99999的值,
MEDIUMINT UNSIGNED是最好的類型。
貨幣值的精確表示是一個常見的問題。在MySQL,你應該使用DECIMAL類型,它作為一個字符串被存儲,不會發生精確性的損失。如果精確性不是太重要,DOUBLE類型也是足夠好的。
對高精度,你總是能變換到以一個BIGINT存儲的定點類型。這允許你用整數做所有的計算,並且僅在必要時將結果轉換回浮點值。見10.6
選擇一個表類型。