MySQL中文參考手冊

譯者:晏子 (clyan@sohu.com) 主頁:http://linuxdb.yeah.net



譯者:晏子 (clyan@sohu.com)

GB 碼主頁:http://linuxdb.yeah.net



Big5 轉碼者:statue (statue@bbs.yzu.edu.tw)

詞彙轉換:彭武興 (wilson@mailbox.com.tw)

Big5 碼主頁: http://cnpa.yzu.edu.tw/~cfc/docs/mysqldoc_big5/manual_toc.html

Big5 碼分站: http://php.wilson.gs/mysqldoc/big5/manual_toc.html





--------------------------------------------------------------------------------



第一章, 前一章, 下一章, 最後一章,目錄.





--------------------------------------------------------------------------------



7 MySQL語言參考



7.1 文字:怎麼寫字符串和數字

7.1.1 字符串

一個字符串是一個字符序列,由單引號(“'”)或雙引號(“"”)字符(後者只有你不在ANSI模式運行)包圍。例如:



'a string'

"another string"



在字符串內,某個順序有特殊的意義。這些順序的每一個以一條反斜線(“\”)開始,稱為轉義字符。MySQL識別下列轉義字符:



\0

一個ASCII 0 (NUL)字符。

\n

一個新行符。

\t

一個定位符。

\r

一個回車符。

\b

一個退格符。

\'

一個單引號(“'”)符。

\"

一個雙引號(“"”)符。

\\

一個反斜線(“\”)符。

\%

一個“%”符。它用於在正文中搜索“%”的文字實例,否則這裡“%”將解釋為一個通配符。

\_

一個“_”符。它用於在正文中搜索“_”的文字實例,否則這裡“_”將解釋為一個通配符。

注意,如果你在某些正文環境中使用“\%”或“\%_”,這些將返回字符串“\%”和“\_”而不是“%”和“_”。



有幾種方法在一個字符串內包括引號:



一個字符串內用“'”加引號的“'”可以被寫作為“''”。

一個字符串內用“"”加引號的“"”可以被寫作為“""”。

你可以把一個轉義字符(“\”)放在引號前面。

一個字符串內用“"”加引號的“'”不需要特殊對待而且不必被重複或轉義。同理,一個字符串內用“'”加引號的與“"”也不需要特殊對待。

下面顯示的SELECT演示引號和轉義如何工作:



mysql> SELECT 'hello', '"hello"', '""hello""', 'hel''lo', '\'hello';

+-------+---------+-----------+--------+--------+

| hello | "hello" | ""hello"" | hel'lo | 'hello |

+-------+---------+-----------+--------+--------+



mysql> SELECT "hello", "'hello'", "''hello''", "hel""lo", "\"hello";

+-------+---------+-----------+--------+--------+

| hello | 'hello' | ''hello'' | hel"lo | "hello |

+-------+---------+-----------+--------+--------+



mysql> SELECT "This\nIs\nFour\nlines";

+--------------------+

| This

Is

Four

lines |

+--------------------+



如果你想要把二進制數據插入到一個BLOB列,下列字符必須由轉義序列表示:



NUL

ASCII 0。你應該用'\0'(一個反斜線和一個ASCII '0')表示它。

\

ASCII 92,反斜線。用'\\'表示。

'

ASCII 39,單引號。用“\'”表示。

"

ASCII 34,雙引號。用“\"”表示。

如果你寫C代碼,你可以使用C API函數mysql_escape_string()來為INSERT語句轉義字符。見20.3 C API 函數概述。在 Perl中,你可以使用DBI包中的quote方法變換特殊的字符到正確的轉義序列。見20.5.2 DBI介面。



你應該在任何可能包含上述任何特殊字符的字符串上使用轉義函數!



7.1.2 數字

整數表示為一個數字順序。浮點數使用“.”作為一個十進制分隔符。這兩種類型的數字可以前置“-”表明一個負值。



有效整數的例子:



1221

0

-32



有效浮點數的例子:



294.42

-32032.6809e+10

148.00



一個整數可以在浮點上下文使用﹔它解釋為等值的浮點數。



7.1.3 十六進制值

MySQL支援十六進制值。在數字上下文,它們表現類似於一個整數(64位精度)。在字符串上下文,它們表現類似於一個二進制字符串,這裡每一對十六進制數字被變換為一個字符。



mysql> SELECT 0xa+0

-> 10

mysql> select 0x5061756c;

-> Paul



十六進制字符串經常被ODBC使用,給出BLOB列的值。



7.1.4 NULL值

NULL值意味著“無數據”並且不同於例如數字類型的0為或字符串類型的空字符串。見18.15 NULL值問題。



當使用文本文件導入或導出格式(LOAD DATA INFILE, SELECT ... INTO OUTFILE)時,NULL可以用\N表示。見7.16 LOAD DATA INFILE句法。



7.1.5 資料庫、表、索引、列和別名的命名

資料庫、表、索引、列和別名的名字都遵守MySQL同樣的規則:



注意,從MySQL3.23.6開始規則改變了,此時我們引入了用'引用的標識符(資料庫、表和列命名)(如果你以ANSI模式運行,"也將用於引用標識符)。



標識符 最大長度 允許的字符

資料庫 64 在一個目錄名允許的任何字符,除了/.

表 64 在文件名中允許的任何字符,除了/或.

列 64 所有字符

別名 255 所有字符



注意,除了以上,你在一個標識符中不能有ASCII(0)或ASCII(255)。



注意,如果標識符是一個限制詞或包含特殊字符,當你使用它時,你必須總是用`引用它:



SELECT * from `select` where `select`.id > 100;



在 MySQL的先前版本,命名規則如下:



一個名字可以包含來自當前字符集的數字字母的字符和“_”和“$”。預設字符集是ISO-8859-1 Latin1﹔這可以通過重新編譯MySQL來改變。見9.1.1 用於數據和排序的字符集。

一個名字可以以在一個名字中合法的任何字符開始。特別地,一個名字可以以一個數字開始(這不同於許多其他的資料庫系統!)。然而,一個名字不能僅僅由數字組成。

你不能在名字中使用“.”,因為它被用來擴充格式,你能用它引用列(見下面)。

建議你不使用像1e這樣的名字,因為一個表達式如1e+1是二義性的。它可以解釋為表達式1e + 1或數字1e+1。



在MySQL中,你能使用下列表格的任何一種引用列:



列引用 含義

col_name 來自於任意表的列col_name,用於包含該表的一個列的查詢中

tbl_name.col_name 來自當前的資料庫的表tbl_name的列col_name

db_name.tbl_name.col_name 行列col_name從表格tbl_name資料庫db_name。這個形式在MySQL3.22或以後版本可用。

`column_name` 是一個關鍵詞或包含特殊字符的列。



在一條語句的列引用中,你不必指定一個tbl_name或db_name.tbl_name前綴,除非引用會有二義性。例如,假定表t1和t2,每個均包含列c,並且你用一個使用t1和t2的SELECT語句檢索c。在這種情況下,c有二義性,因為它在使用表的語句中不是唯一的,因此你必須通過寫出t1.c或t2.c來指明你想要哪個表。同樣,如果你從資料庫db1中一個表t和在資料庫db2的一個表t檢索,你必須用db1.t.col_name和db2.t.col_name引用這些數據表的列。



句法.tbl_name意味著在當前的資料庫中的表tbl_name,該句法為了ODBC的兼容性被接受,因為一些ODBC程式用一個“.”字符作為資料庫表名的前綴。



7.1.5.1 名字的大小寫敏感性

在MySQL中,資料庫和表對應於在那些目錄下的目錄和文件,因而,內在的作業系統的敏感性決定資料庫和表命名的大小寫敏感性。這意味著資料庫和表名在Unix上是區分大小寫的,而在Win32上忽略大小寫。



注意:在Win32上,盡管資料庫和表名是忽略大小寫的,你不應該在同一個查詢中使用不同的大小寫來引用一個給定的資料庫和表。下列查詢將不工作,因為它作為my_table和作為MY_TABLE引用一個表:



mysql> SELECT * FROM my_table WHERE MY_TABLE.col=1;



列名在所有情況下都是忽略大小寫的。



表的別名是區分大小寫的。下列查詢將不工作,: 因為它用a和A引用別名:



mysql> SELECT col_name FROM tbl_name AS a

WHERE a.col_name = 1 OR A.col_name = 2;



列的別名是忽略大小寫的。



7.2 用戶變數

MySQL支援執行緒特定的變數,用@variablename句法。一個變數名可以由當前字符集的數字字母字符和“_”、“$”和“.”組成。預設字符集是ISO-8859-1 Latin1﹔這可以通過重新編譯MySQL改變。見9.1.1 用於數據和排序的字符集。



變數不必被初始化。預設地,他們包含NULL並能儲存整數、實數或一個字符串值。當執行緒退出時,對於一個執行緒的所有變數自動地被釋放。



你可以用SET句法設置一個變數:



SET @variable= { integer expression | real expression | string expression }

[,@variable= ...].



你也可以用@variable:=expr句法在一個表達式中設置一個變數:



select @t1:=(@t2:=1)+@t3:=4,@t1,@t2,@t3;

+----------------------+------+------+------+

| @t1:=(@t2:=1)+@t3:=4 | @t1 | @t2 | @t3 |

+----------------------+------+------+------+

| 5 | 5 | 1 | 4 |

+----------------------+------+------+------+



(這裡,我們不得不使用:=句法,因為=是為比較保留的)



7.3 列類型

MySQL支援大量的列類型,它可以被分為3類:數字類型、日期和時間類型以及字符串(字符)類型。本節首先給出可用類型的一個概述,並且總結每個列類型的儲存需求,然後提供每個類中的類型性質的更詳細的描述。概述有意簡化,更詳細的說明應該考慮到有關特定列類型的附加資訊,例如你能為其指定值的允許格式。



由MySQL支援的列類型列在下面。下列代碼字母用於描述中:



M

指出最大的顯示尺寸。最大的合法的顯示尺寸是 255 。

D

適用於浮點類型並且指出跟隨在十進制小數點後的數碼的數量。最大可能的值是30,但是應該不大於M-2。

方括號(“[”和“]”)指出可選的類型修飾符的部分。



注意,如果你指定一個了為ZEROFILL,MySQL將為該列自動地增加UNSIGNED屬性。



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

一個很小的整數。有符號的範圍是-128到127,無符號的範圍是0到255。

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或DOUBLE值完成,因此你不應該使用大於9223372036854775807(63位)的有符號大整數,除了位函數!注意,當兩個參數是INTEGER值時,-、+和*將使用BIGINT運算!這意味著如果你乘2個大整數(或來自於返回整數的函數),如果結果大於9223372036854775807,你可以得到意外的結果。一個浮點數字,不能是無符號的,對一個單精度浮點數,其精度可以是
FLOAT[(M,D)] [ZEROFILL]

一個小(單精密)浮點數字。不能無符號。允許的值是-3.402823466E+38到-1.175494351E-38,0 和1.175494351E-38到3.402823466E+38。M是顯示寬度而D是小數的位數。沒有參數的FLOAT或有
DOUBLE[(M,D)] [ZEROFILL]

一個正常大小(雙精密)浮點數字。不能無符號。允許的值是-1.7976931348623157E+308到-2.2250738585072014E-308、 0和2.2250738585072014E-308到1.7976931348623157E+308。M是顯示寬度而D是小數位數。沒有一個參數的DOUBLE或FLOAT(X)(25
DOUBLE PRECISION[(M,D)] [ZEROFILL]

 

REAL[(M,D)] [ZEROFILL]

這些是DOUBLE同義詞。

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

一個未壓縮(unpack)的浮點數字。不能無符號。行為如同一個CHAR列:“未壓縮”意味著數字作為一個字符串被儲存,值的每一位使用一個字符。小數點,並且對於負數,“-”符號不在M中計算。如果D是0,值將沒有小數點或小數部分。DECIMAL值的最大範圍與DOUBLE相同,但是對一個給定的DECIMAL列,實際的範圍可以通過M和D的選擇被限制。如果D被省略,它被設置為0。如果M被省掉,它被設置為10。注意,在MySQL3.22裡,M參數包括符號和小數點。

NUMERIC(M,D) [ZEROFILL]

這是DECIMAL的一個同義詞。

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年的某時。MySQL以YYYYMMDDHHMMSS、YYMMDDHHMMSS、YYYYMMDD或YYMMDD格式來顯示TIMESTAMP值,取決於是否M是14(或省略)、12、8或6,但是允許你使用字符串或數字把值賦給TIMESTAMP列。一個TIMESTAMP列對於記錄一個INSERT或UPDATE操作的日期和時間是有用的,因為如果你不自己給它賦值,它自動地被設置為最近操作的日期和時間。你以可以通過賦給它一個NULL值設置它為當前的日期和時間。見7.3.6 日期和時間類型。

TIME

一個時間。範圍是'-838:59:59'到'838:59:59'。MySQL以'HH:MM:SS'格式來顯示TIME值,但是允許你使用字符串或數字把值賦給TIME列。

YEAR[(2|4)]

一個2或4位數字格式的年(預設是4位)。允許的值是1901到2155,和0000(4位年格式),如果你使用2位,1970-2069( 70-69)。MySQL以YYYY格式來顯示YEAR值,但是允許你把使用字符串或數字值賦給YEAR列。(YEAR類型在MySQL3.22中是新類型。)

CHAR(M) [BINARY]

一個定長字符串,當儲存時,總是是用空格填滿右邊到指定的長度。M的範圍是1 ~ 255個字符。當值被檢索時,空格尾部被刪除。CHAR值根據預設字符集以大小寫不區分的方式排序和比較,除非給出BINARY關鍵詞。NATIONAL CHAR(短形式NCHAR)是ANSI SQL的方式來定義CHAR列應該使用預設字符集。這是MySQL的預設。CHAR是CHARACTER的一個縮寫。

[NATIONAL] VARCHAR(M) [BINARY]

一個變長字符串。注意:當值被儲存時,尾部的空格被刪除(這不同於ANSI SQL規範)。M的範圍是1 ~ 255個字符。 VARCHAR值根據預設字符集以大小寫不區分的方式排序和比較,除非給出BINARY關鍵詞值。見7.7.1 隱式列指定變化。 VARCHAR是CHARACTER VARYING一個縮寫。

TINYBLOB

 

TINYTEXT

一個BLOB或TEXT列,最大長度為255(2^8-1)個字符。見7.7.1 隱式列指定變化。

BLOB

 

TEXT

一個BLOB或TEXT列,最大長度為65535(2^16-1)個字符。見7.7.1 隱式列指定變化。

MEDIUMBLOB

 

MEDIUMTEXT

一個BLOB或TEXT列,最大長度為16777215(2^24-1)個字符。見7.7.1 隱式列指定變化。

LONGBLOB

 

LONGTEXT

一個BLOB或TEXT列,最大長度為4294967295(2^32-1)個字符。見7.7.1 隱式列指定變化

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

枚舉。一個僅有一個值的字符串對像,這個值式選自與值列表'value1'、'value2', ...,或NULL。一個ENUM最多能有65535不同的值。

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

一個集合。能有零個或多個值的一個字符串對像,其中每一個必須從值列表'value1', 'value2', ...選出。一個SET最多能有64個成員。

7.3.1 列類型儲存需求

對於每個由MySQL支援的列類型的儲存需求在下面按類列出。



7.3.2 數字類型

列類型 需要的儲存量

TINYINT 1 字節

SMALLINT 2 個字節

MEDIUMINT 3 個字節

INT 4 個字節

INTEGER 4 個字節

BIGINT 8 個字節

FLOAT(X) 4 如果 X
FLOAT 4 個字節

DOUBLE 8 個字節

DOUBLE PRECISION 8 個字節

REAL 8 個字節

DECIMAL(M,D) M字節(D+2 , 如果M
NUMERIC(M,D) M字節(D+2 , 如果M


7.3.3 日期和時間類型

列類型 需要的儲存量

DATE 3 個字節

DATETIME 8 個字節

TIMESTAMP 4 個字節

TIME 3 個字節

YEAR 1 字節



7.3.4 串類型

列類型 需要的儲存量

CHAR(M) M字節,1
VARCHAR(M) L+1 字節, 在此L
TINYBLOB, TINYTEXT L+1 字節, 在此L
BLOB, TEXT L+2 字節, 在此L
MEDIUMBLOB, MEDIUMTEXT L+3 字節, 在此L
LONGBLOB, LONGTEXT L+4 字節, 在此L
ENUM('value1','value2',...) 1 或 2 個字節, 取決於枚舉值的數目(最大值65535)

SET('value1','value2',...) 1,2,3,4或8個字節, 取決於集合成員的數量(最多64個成員)



VARCHAR和BLOB和TEXT類型是變長類型,對於其儲存需求取決於列值的實際長度(在前面的表格以 L表示),而不是取決於類型的最大可能尺寸。例如,一個VARCHAR(10)列能保存最大長度為10個字符的一個字符串,實際的儲存需要是字符串的長度(L),加上1個字節以記錄字符串的長度。對於字符串'abcd',L是4而儲存要求是5個字節。



BLOB和TEXT類型需要1,2,3或4個字節來記錄列值的長度,這取決於類型的最大可能長度。



如果一個表包括任何變長的列類型,記錄格式將也是變長的。注意,當一個表被創建時,MySQL可能在某些條件下將一個列從一個變長類型改變為一個定長類型或相反。見7.7.1 隱式列指定變化。



一個ENUM對像的大小由不同枚舉值的數量決定。1字節被用於枚舉,最大到255個可能的值﹔2個字節用於枚舉,最大到65535 值。



一個SET對像的大小由不同的集合成員的數量決定。如果集合大小是N,對像占據(N+7)/8個字節,四捨五入為1,2,3,4或8 個字節。一個SET最多能有64個成員。



7.3.5 數字類型

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語句,由於剪切所發生的變換作為“警告”被報告。



7.3.6 日期和時間類型

日期和時間類型是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範圍端點值。)下表顯示對每種類型的“零”值的格式: 列類型 “零”值

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

DATE '0000-00-00'

TIMESTAMP 00000000000000(長度取決於顯示尺寸)

TIME '00:00:00'

YEAR 0000



“零”值是特殊的,但是你能使用在表中顯示的值來明顯地儲存或引用他們。你也可以使用值'0'或0做到, 這更容易寫。

在MyODBC 2.50.12和以上版本中,由MyODBC使用的“零”日期或時間值被自動變換到NULL,因為ODBC不能處理這樣的值。

7.3.6.1 Y2K問題和日期類型

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位年值的輸入。



7.3.6.2 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(14) YYYYMMDDHHMMSS

TIMESTAMP(12) YYMMDDHHMMSS

TIMESTAMP(10) YYMMDDHHMM

TIMESTAMP(8) YYYYMMDD

TIMESTAMP(6) YYMMDD

TIMESTAMP(4) YYMM

TIMESTAMP(2) YY



所有的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。

7.3.6.3 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'或它是否是不合法的。



7.3.6.4 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。



7.3.7 字符串類型

字符串類型是CHAR、VARCHAR、BLOB、TEXT、ENUM和SET。



7.3.7.1 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)列:



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

'' ' ' 4 個字節 '' 1 字節

'ab' 'ab ' 4 個字節 'ab' 3 個字節

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

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



從CHAR(4)和VARCHAR(4)列檢索的值在每種情況下都是一樣的,因為拖後的空格從檢索的CHAR列上被刪除。



在CHAR和VARCHAR列中儲存和比較值是以大小寫不區分的方式進行的,除非當桌子被創建時,BINARY屬性被指定。BINARY屬性意味著該列的值根據MySQL伺服器正在運行的機器的ASCII順序以大小寫區分的方式儲存和比較。



BINARY屬性是“粘性”的。這意味著,如果標記了BINARY的列用於一個表達式中,整個的表達式作為一個BINARY值被比較。



MySQL在表創建時可以隱含地改變一個CHAR或VARCHAR列的類型。見7.7.1 隱含的的列說明改變。



7.3.7.2 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列有刪除。

BLOB和TEXT列不能有DEFAULT值。

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值內部由一個獨立分配的對像表示。這與所有的其他列類型相反,它們是在打開表時,按列被分配一次儲存。



7.3.7.3 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")的列可以有顯示在下面的值的任何一個。每個值的編號也被顯示:



值 編號

NULL NULL

"" 0

"one" 1

"two" 2

"three" 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定義。



7.3.7.4 SET類型

一個SET是可以有零或多個值的一個字符串對像,其每一個必須從表創建造被指定了的允許值的一張列表中被選擇。由多個集合成員組成的SET列通過由由逗號分隔(“,”)的成員被指定,其推論是該SET成員值不能包含逗號本身。



例如, 一個指定為SET("one", "two") NOT NULL的列可以有這些值的任何一個:



""

"one"

"two"

"one,two"



一個SET能有最多64個不同的成員。

MySQL用數字值儲存SET值,儲存值的低階位對應於第一個集合成員。如果你在數字上下文中檢索一個SET值,檢索的值把位設置位對應組成列值的集合成員。如果一個數字被儲存進一個SET列,在數字的二進制表示中設置的位決定了在列中的集合成員。假定一個列被指定為SET("a","b","c","d"),那麼成員有下列位值:



SET 成員 十進制的值 二進制的值

a 1 0001

b 2 0010

c 4 0100

d 8 1000



如果你給該列賦值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定義。



7.3.8 為列選擇正確的類型

為了最有效地使用儲存空間,試著在所有的情況下使用最精確的類型。例如,如果一個整數列被用於在之間1和99999的值, MEDIUMINT UNSIGNED是最好的類型。



貨幣值的精確表示是一個常見的問題。在MySQL,你應該使用DECIMAL類型,它作為一個字符串被儲存,不會發生精確性的損失。如果精確性不是太重要,DOUBLE類型也是足夠好的。



對高精度,你總是能變換到以一個BIGINT儲存的定點類型。這允許你用整數做所有的計算,並且僅在必要時將結果轉換回浮點值。見10.6 選擇一個表類型。



7.3.9 列索引

所有的MySQL列類型能被索引。在相關的列上的使用索引是改進SELECT操作性能的最好方法。



一個表最多可有16個索引。最大索引長度是256個字節,盡管這可以在編譯MySQL時被改變。



對於CHAR和VARCHAR列,你可以索引列的前綴。這更快並且比索引整個列需要較少的磁碟空間。在CREATE TABLE語句中索引列前綴的語法看起來像這樣:



KEY index_name (col_name(length))

下面的例子為name列的頭10個字符創建一個索引:



mysql> CREATE TABLE test (

name CHAR(200) NOT NULL,

KEY index_name (name(10)));



對於BLOB和TEXT列,你必須索引列的前綴,你不能索引列的全部。



7.3.10 多列索引

MySQL能在多個列上創建索引。一個索引可以由最多15個列組成。(在CHAR和VARCHAR列上,你也可以使用列的前綴作為一個索引的部分)。



一個多重列索引可以認為是包含通過合並(concatenate)索引列值創建的值的一個排序數組。



當你為在一個WHERE子句索引的第一列指定已知的數量時,MySQL以這種方式使用多重列索引使得查詢非常快速,即使你不為其他列指定值。



假定一張表使用下列說明創建:



mysql> CREATE TABLE test (

id INT NOT NULL,

last_name CHAR(30) NOT NULL,

first_name CHAR(30) NOT NULL,

PRIMARY KEY (id),

INDEX name (last_name,first_name));



那麼索引name是一個在last_name和first_name上的索引,這個索引將被用於在last_name或last_name和first_name的一個已知範圍內指定值的查詢,因此,name索引將使用在下列查詢中:



mysql> SELECT * FROM test WHERE last_name="Widenius";



mysql> SELECT * FROM test WHERE last_name="Widenius"

AND first_name="Michael";



mysql> SELECT * FROM test WHERE last_name="Widenius"

AND (first_name="Michael" OR first_name="Monty");



mysql> SELECT * FROM test WHERE last_name="Widenius"

AND first_name >="M" AND first_name


然而,name索引將不用在下列詢問中:



mysql> SELECT * FROM test WHERE first_name="Michael";



mysql> SELECT * FROM test WHERE last_name="Widenius"

OR first_name="Michael";



關於MySQL使用索引改進性能的方式的更多的資訊,見10.4 使用MySQL索引。



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

為了跟容易地使用為其他供應商的SQL實現編寫的代碼,下表顯示了MySQL映射的列類型。這些映射使得從其他資料庫引擎移動表定義到MySQL更容易:



其他供應商類型 MySQL類型

BINARY(NUM) CHAR(NUM) BINARY

CHAR VARYING(NUM) VARCHAR(NUM)

FLOAT4 FLOAT

FLOAT8 DOUBLE

INT1 TINYINT

INT2 SMALLINT

INT3 MEDIUMINT

INT4 INT

INT8 BIGINT

LONG VARBINARY MEDIUMBLOB

LONG VARCHAR MEDIUMTEXT

MIDDLEINT MEDIUMINT

VARBINARY(NUM) VARCHAR(NUM) BINARY



列類型映射發生在表創建時。如果你用其他供應商使用的類型創建表,那麼發出一個DESCRIBE tbl_name語句,MySQL使用等價的MySQL類型報告表結構。



7.4 用在SELECT和WHERE子句中的函數

在一個SQL語句中的select_expression或where_definition可由使用下面描述的函數的任何表達式組成。



包含NULL的一個表達式總是產生一個NULL值,否則除非表達式所包含的操作符和函數在文檔中說明。



注意:在一個函數名和跟隨它的括號之間不許沒有空格。這幫助MySQL分析器區分函數調用和具有相同名字的對表或列的引用,盡管允許在參數周圍有空格。



為了簡潔,例子以縮寫形式顯示從mysql程式輸出。因此:



mysql> select MOD(29,9);

1 rows in set (0.00 sec)



+-----------+

| mod(29,9) |

+-----------+

| 2 |

+-----------+



被顯示為這樣:



mysql> select MOD(29,9);

-> 2



7.4.1 分組函數

( ... )

括號。使用它們來強制在一個表達式的計算順序。

mysql> select 1+2*3;

-> 7

mysql> select (1+2)*3;

-> 9



7.4.2 常用的算術操作

一般的算術操作符是可用的。注意在-、+和*情況下,如果兩個參數是整數,結果用BIGINT(64位)精度計算!



+

加法

mysql> select 3+5;

-> 8



-

減法

mysql> select 3-5;

-> -2

*

乘法

mysql> select 3*5;

-> 15

mysql> select 18014398509481984*18014398509481984.0;

-> 324518553658426726783156020576256.0

mysql> select 18014398509481984*18014398509481984;

-> 0





最後一個表達式的結果是不正確的,因為整數乘積的結果超過用BIGINT計算的64位範圍。



/

除法

mysql> select 3/5;

-> 0.60



被零除產生一個NULL結果:



mysql> select 102/(1-1);

-> NULL



一個除法用BIGINT算術計算,只要在它的結果被轉換到一個整數的上下文中執行!



7.4.3 位函數

MySQL為位操作使用BIGINT(64位)算法,因此這些操作符有最大64位的一個範圍。



|

位或

mysql> select 29 | 15;

-> 31



&

位與

mysql> select 29 & 15;

-> 13




左移位一個長(BIGINT)數字。

mysql> select 1
-> 4



>>

右移位一個長(BIGINT)數字。

mysql> select 4 >> 2

-> 1

~

顛倒所有的位。

mysql> select 5 & ~1

-> 4



BIT_COUNT(N)

返回在參數N設定的位的數量。

mysql> select BIT_COUNT(29);

-> 4



7.4.4 邏輯運算

所有的邏輯函數返回1(TRUE)或0(FALSE)。



NOT

!

邏輯非。如果參數是0,返回1,否則返回0。例外: NOT NULL返回NULL。

mysql> select NOT 1;

-> 0

mysql> select NOT NULL;

-> NULL

mysql> select ! (1+1);

-> 0

mysql> select ! 1+1;

-> 1



最後的例子返回1,因為表達式作為(!1)+1計算。

OR

 

||

邏輯或。如果任何一個參數不是0並且不NULL,返回1。

mysql> select 1 || 0;

-> 1

mysql> select 0 || 0;

-> 0

mysql> select 1 || NULL;

-> 1



AND

 

&&

邏輯與。如果任何一個參數是0或NULL,返回0,否則返回1。

mysql> select 1 && NULL;

-> 0

mysql> select 1 && 0;

-> 0



7.4.5 比較運算符

比較操作得出值1(TRUE)、0(FALSE)或NULL等結果。這些函數工作運用在數字和字符串上。當需要時,字符串自動地被變換到數字且數字到字符串(如在Perl)。



MySQL使用下列規則執行比較:



如果一個或兩個參數是NULL,比較的結果是NULL,除了操作符。

如果在比較中操作的兩個參數是字符串,他們作為字符串被比較。

如果兩個參數是整數,他們作為整數被比較。

十六進制的值如果不與一個數字比較,則被當作二進制字符串。

如果參數之一是一個TIMESTAMP或DATETIME列而其他參數是一個常數,在比較執行前,常數被轉換為一個時間標記。這樣做是為了對ODBC更友好。

在所有其他的情況下,參數作為浮點(實數)數字被比較。

預設地,字符串使用當前的字符集以大小寫敏感的方式進行(預設為ISO-8859-1 Latin1,它對英語運用得很出色)。



下面的例子演示了對於比較操作字符串到數字的轉換:



mysql> SELECT 1 > '6x';

-> 0

mysql> SELECT 7 > '6x';

-> 1

mysql> SELECT 0 > 'x6';

-> 0

mysql> SELECT 0 = 'x6';

-> 1



=

等於

mysql> select 1 = 0;

-> 0

mysql> select '0' = 0;

-> 1

mysql> select '0.0' = 0;

-> 1

mysql> select '0.01' = 0;

-> 0

mysql> select '.01' = 0.01;

-> 1





 

!=

不等於

mysql> select '.01' '0.01';

-> 1

mysql> select .01 '0.01';

-> 0

mysql> select 'zapp' 'zappp';

-> 1




小於或等於



mysql> select 0.1
-> 1




小於

mysql> select 2
-> 1



>=

大於或等於

mysql> select 2 >= 2;

-> 1

>

大於

mysql> select 2 > 2;

-> 0





安全等於Null

mysql> select 1 1, NULL NULL, 1 NULL;

-> 1 1 0



IS NULL

 

IS NOT NULL

測試值是否是或不是NULL

mysql> select 1 IS NULL, 0 IS NULL, NULL IS NULL:

-> 0 0 1

mysql> select 1 IS NOT NULL, 0 IS NOT NULL, NULL IS NOT NULL;



expr BETWEEN min AND max

如果expr對大於或等於min且expr是小於或等於max,BETWEEN返回1,否則它返回0。如果所有的參數類型是一樣得,這等價於表達式(min
mysql> select 1 BETWEEN 2 AND 3;

-> 0

mysql> select 'b' BETWEEN 'a' AND 'c';

-> 1

mysql> select 2 BETWEEN 2 AND '3';

-> 1

mysql> select 2 BETWEEN 2 AND 'x-3';

-> 0



expr IN (value,...)

如果expr是在IN表中的任何值,返回1,否則返回0。如果所有的值是常數,那麼所有的值根據expr類型被計算和排序,然後項目的搜索是用二進制的搜索完成。這意味著如果IN值表全部由常數組成,IN是很快的。如果expr是一個大小寫敏感的字符串表達式,字符串比較以大小寫敏感方式執行。

mysql> select 2 IN (0,3,5,'wefwf');

-> 0

mysql> select 'wefwf' IN (0,3,5,'wefwf');

-> 1

expr NOT IN (value,...)

與NOT (expr IN (value,...))相同。

ISNULL(expr)

如果expr是NULL,ISNULL()返回1,否則它返回0。

mysql> select ISNULL(1+1);

-> 0

mysql> select ISNULL(1/0);

-> 1



注意,使用=的NULL的值比較總為假!



COALESCE(list)

回來list中第一個非NULL的單元。

mysql> select COALESCE(NULL,1);

-> 1

mysql> select COALESCE(NULL,NULL,NULL);

-> NULL



INTERVAL(N,N1,N2,N3,...)

如果N
mysql> select INTERVAL(23, 1, 15, 17, 30, 44, 200);

-> 3

mysql> select INTERVAL(10, 1, 10, 100, 1000);

-> 2

mysql> select INTERVAL(22, 23, 30, 44, 200);

-> 0

7.4.6 字符串比較函數

通常,如果在字符串比較中的任何表達式是區分大小寫的,比較以大小寫敏感的方式執行。



expr LIKE pat [ESCAPE 'escape-char']

使用SQL的簡單的正規表達式比較的模式匹配。返回1(TRUE)或0(FALSE)。用LIKE,你可以在模式中使用下列2個通配符字符: % 匹配任何數目的字符,甚至零個字符

_ 精確匹配一個字符



mysql> select 'David!' LIKE 'David_';

-> 1

mysql> select 'David!' LIKE '%D%v%';

-> 1



為了測試一個通配符的文字實例,用轉義字符的加在字符前面。如果你不指定ESCAPE字符,假定為“\”:



\% 匹配一%字符

\_ 匹配一_字符



mysql> select 'David!' LIKE 'David\_';

-> 0

mysql> select 'David_' LIKE 'David\_'


arrow
arrow
    全站熱搜
    創作者介紹
    創作者 killworm737 的頭像
    killworm737

    紀錄些小事情

    killworm737 發表在 痞客邦 留言(0) 人氣()