分类: Mysql/postgreSQL
2008-05-14 11:21:34
一个字符串是一个字符序列,由单引号(“'”)或双引号(“"”)字符(后者只有你不在ANSI模式运行)包围。例如:
'a string' "another string"
在字符串内,某个顺序有特殊的意义。这些顺序的每一个以一条反斜线(“\”)开始,称为转义字符。MySQL识别下列转义字符:
\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
\
'
"
如果你写C代码,你可以使用C API函数mysql_escape_string()
来为INSERT
语句转义字符。见。在 Perl中,你可以使用DBI
包中的quote
方法变换特殊的字符到正确的转义序列。见。
你应该在任何可能包含上述任何特殊字符的字符串上使用转义函数!
整数表示为一个数字顺序。浮点数使用“.”作为一个十进制分隔符。这两种类型的数字可以前置“-”表明一个负值。
有效整数的例子:
1221 0 -32
有效浮点数的例子:
294.42 -32032.6809e+10 148.00
一个整数可以在浮点上下文使用;它解释为等值的浮点数。
MySQL支持十六进制值。在数字上下文,它们表现类似于一个整数(64位精度)。在字符串上下文,它们表现类似于一个二进制字符串,这里每一对十六进制数字被变换为一个字符。
mysql> SELECT 0xa+0 -> 10 mysql> select 0x5061756c; -> Paul
十六进制字符串经常被ODBC使用,给出BLOB列的值。
NULL
值意味着“无数据”并且不同于例如数字类型的0
为或字符串类型的空字符串。见。
当使用文本文件导入或导出格式(LOAD DATA INFILE
, SELECT ... INTO OUTFILE
)时,NULL
可以用\N
表示。见。
数据库、表、索引、列和别名的名字都遵守MySQL同样的规则:
注意,从MySQL3.23.6开始规则改变了,此时我们引入了用'引用的标识符(数据库、表和列命名)(如果你以ANSI模式运行,"也将用于引用标识符)。
标识符 | 最大长度 | 允许的字符 |
数据库 | 64 | 在一个目录名允许的任何字符,除了/ . |
表 | 64 | 在文件名中允许的任何字符,除了/ 或. |
列 | 64 | 所有字符 |
别名 | 255 | 所有字符 |
注意,除了以上,你在一个标识符中不能有ASCII(0)或ASCII(255)。
注意,如果标识符是一个限制词或包含特殊字符,当你使用它时,你必须总是用`
引用它:
SELECT * from `select` where `select`.id > 100;
在 MySQL的先前版本,命名规则如下:
建议你不使用象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程序用一个“.”字符作为数据库表名的前缀。
在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;
列的别名是忽略大小写的。
MySQL支持线程特定的变量,用@variablename
句法。一个变量名可以由当前字符集的数字字母字符和“_”、“$”和“.”组成。缺省字符集是ISO-8859-1 Latin1;这可以通过重新编译MySQL改变。见。
变量不必被初始化。缺省地,他们包含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 | +----------------------+------+------+------+
(这里,我们不得不使用:=
句法,因为=
是为比较保留的)
MySQL支持大量的列类型,它可以被分为3类:数字类型、日期和时间类型以及字符串(字符)类型。本节首先给出可用类型的一个概述,并且总结每个列类型的存储需求,然后提供每个类中的类型性质的更详细的描述。概述有意简化,更详细的说明应该考虑到有关特定列类型的附加信息,例如你能为其指定值的允许格式。
由MySQL支持的列类型列在下面。下列代码字母用于描述中:
M
D
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
,你可以得到意外的结果。一个浮点数字,不能是无符号的,对一个单精度浮点数,其精度可以
是<=24
,对一个双精度浮点数,是在25 和53之间,这些类型如FLOAT
和DOUBLE
类型马上在下面描述。FLOAT(X)
有对应的FLOAT
和DOUBLE
相同的范围,但是显示尺寸和小数位数是未定义的。在MySQL3.23中,这是一个真正的浮点值。在更早的MySQL版本中,FLOAT(precision)
总是有2位小数。该句法为了ODBC兼容性而提供。
FLOAT[(M,D)] [ZEROFILL]
-3.402823466E+38
到-1.175494351E-38
,0
和1.175494351E-38
到3.402823466E+38
。M是显示宽度而D是小数的位数。没有参数的FLOAT
或有<24 的一个参数表示一个单精密浮点数字。
DOUBLE[(M,D)] [ZEROFILL]
-1.7976931348623157E+308
到-2.2250738585072014E-308
、 0
和2.2250738585072014E-308
到1.7976931348623157E+308
。M是显示宽度而D是小数位数。没有一个参数的DOUBLE
或FLOAT(X)
(25 < = X < = 53)代表一个双精密浮点数字。
DOUBLE PRECISION[(M,D)] [ZEROFILL]
REAL[(M,D)] [ZEROFILL]
DOUBLE
同义词。
DECIMAL[(M[,D])] [ZEROFILL]
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
值设置它为当前的日期和时间。见。
TIME
'-838:59:59'
到'838:59:59'
。MySQL以'HH:MM:SS'
格式来显示TIME
值,但是允许你使用字符串或数字把值赋给TIME
列。
YEAR[(2|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]
VARCHAR
值根据缺省字符集以大小写不区分的方式排序和比较,除非给出BINARY
关键词值。见。 VARCHAR
是CHARACTER VARYING
一个缩写。
TINYBLOB
TINYTEXT
BLOB
或TEXT
列,最大长度为255(2^8-1)个字符。见。
BLOB
TEXT
BLOB
或TEXT
列,最大长度为65535(2^16-1)个字符。见。
MEDIUMBLOB
MEDIUMTEXT
BLOB
或TEXT
列,最大长度为16777215(2^24-1)个字符。见。
LONGBLOB
LONGTEXT
BLOB
或TEXT
列,最大长度为4294967295(2^32-1)个字符。见
ENUM('value1','value2',...)
'value1'
、'value2'
, ...
,或NULL
。一个ENUM
最多能有65535不同的值。
SET('value1','value2',...)
'value1'
, 'value2'
, ...
选出。一个SET
最多能有64个成员。 对于每个由MySQL支持的列类型的存储需求在下面按类列出。
列类型 | 需要的存储量 |
TINYINT |
1 字节 |
SMALLINT |
2 个字节 |
MEDIUMINT |
3 个字节 |
INT |
4 个字节 |
INTEGER |
4 个字节 |
BIGINT |
8 个字节 |
FLOAT(X) |
4 如果 X < = 24 或 8 如果 25 < = X < = 53 |
FLOAT |
4 个字节 |
DOUBLE |
8 个字节 |
DOUBLE PRECISION |
8 个字节 |
REAL |
8 个字节 |
DECIMAL(M,D) |
M 字节(D +2 , 如果M < D ) |
NUMERIC(M,D) |
M 字节(D +2 , 如果M < D ) |
列类型 | 需要的存储量 |
DATE |
3 个字节 |
DATETIME |
8 个字节 |
TIMESTAMP |
4 个字节 |
TIME |
3 个字节 |
YEAR |
1 字节 |
列类型 | 需要的存储量 |
CHAR(M) |
M 字节,1 <= M <= 255 |
VARCHAR(M) |
L +1 字节, 在此L <= M 和1 <= M <= 255 |
TINYBLOB , TINYTEXT |
L +1 字节, 在此L < 2 ^ 8 |
BLOB , TEXT |
L +2 字节, 在此L < 2 ^ 16 |
MEDIUMBLOB , MEDIUMTEXT |
L +3 字节, 在此L < 2 ^ 24 |
LONGBLOB , LONGTEXT |
L +4 字节, 在此L < 2 ^ 32 |
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可能在某些条件下将一个列从一个变长类型改变为一个定长类型或相反。见。
一个ENUM
对象的大小由不同枚举值的数量决定。1字节被用于枚举,最大到255个可能的值;2个字节用于枚举,最大到65535 值。
一个SET
对象的大小由不同的集合成员的数量决定。如果集合大小是N
,对象占据(N+7)/8
个字节,四舍五入为1,2,3,4或8 个字节。一个SET
最多能有64个成员。
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()
得到类似以这些日期的正确值)。
当用日期和时间工作时,这里是的一些要记住的一般考虑:
'98-09-04'
),而不是以其他地方常用的月-日-年或日-月-年的次序(例如,'09-04-98'
、'04-09-98')。
TIME
值被剪切为适当的TIME
范围端点值。)下表显示对每种类型的“零”值的格式:
列类型 | “零”值 |
DATETIME |
'0000-00-00 00:00:00' |
DATE |
'0000-00-00' |
TIMESTAMP |
00000000000000 (长度取决于显示尺寸) |
TIME |
'00:00:00' |
YEAR |
0000 |
'0'
或0
做到, 这更容易写。
NULL
,因为ODBC不能处理这样的值。 MySQL本身Y2K安全的(见),但是呈交给MySQL的输入值可能不是。一个包含2位年份值的任何输入是由二义性的,因为世纪是未知的。这样的值必须被解释成4位形式,因为MySQL内部使用4位存储年份。
对于DATETIME
, DATE
, TIMESTAMP
和YEAR
类型,MySQL使用下列规则的解释二义性的年份值:
00-69
的年值被变换到2000-2069
。
70-99
的年值被变换到1970-1999
。 记得这些规则仅仅提供对于你数据的含义的合理猜测。如果MySQL使用的启发规则不产生正确的值,你应该提供无二义的包含4位年值的输入。
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
被设置到当前的日期和时间,但在以后无论何时行被更新时都不改变,你可以使用这个属性:
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'
不是一个合法的月份。
00-69
范围的年值被变换到2000-2069
。
70-99
围的年值被变换到1970-1999
。 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
类型是一个 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
列的长度被修正为在你创造表时你所声明的长度。长度可以是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
列的类型。见。
一个BLOB
是一个能保存可变数量的数据的二进制的大对象。4个BLOB
类型TINYBLOB
、BLOB
、MEDIUMBLOB
和LONGBLOB
仅仅在他们能保存值的最大长度方面有所不同。见。
4个TEXT
类型TINYTEXT
、TEXT
、MEDIUMTEXT
和LONGTEXT
对应于4个BLOB
类型,并且有同样的最大长度和存储需求。在BLOB
和TEXT
类型之间的唯一差别是对BLOB
值的排序和比较以大小写敏感方式执行,而对TEXT
值是大小写不敏感的。换句话说,一个TEXT
是一个大小写不敏感的BLOB
。
如果你把一个超过列类型最大长度的值赋给一个BLOB
或TEXT
列,值被截断以适合它。
在大多数方面,你可以认为一个TEXT
行列是你所希望大的一个VARCHAR
列。同样,你可以认为一个BLOB
列是一个VARCHAR BINARY
列。差别是:
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
对象的最大尺寸由其类型决定,但是你能在客户与服务器之间是实际传输的最大值由可用的内存数量和通讯缓冲区的大小来决定。你能改变消息缓冲区大小,但是你必须在服务器和客户两端做。见。 注意,每个BLOB
或TEXT
值内部由一个独立分配的对象表示。这与所有的其他列类型相反,它们是在打开表时,按列被分配一次存储。
一个ENUM
是一个字符对象,其值通常从一个在表创建时明确被列举的允许值的一张表中选择。
在下列的某个情形下,值也可以空字符串(""
)或NULL
:
ENUM
(即,一个不在允许的值列表中的字符串),空字符串作为一个特殊错误的值被插入。
ENUM
被声明为NULL
,NULL
也是列的合法值,并且缺省值是NULL
。如果一个ENUM
被声明为NOT NULL
,缺省值是允许值的列表的第一成员。 每枚举值有一个编号:
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
定义。
一个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
定义。
为了最有效地使用存储空间,试着在所有的情况下使用最精确的类型。例如,如果一个整数列被用于在之间1
和99999
的值, MEDIUMINT UNSIGNED
是最好的类型。
货币值的精确表示是一个常见的问题。在MySQL,你应该使用DECIMAL
类型,它作为一个字符串被存储,不会发生精确性的损失。如果精确性不是太重要,DOUBLE
类型也是足够好的。
对高精度,你总是能变换到以一个BIGINT
存储的定点类型。这允许你用整数做所有的计算,并且仅在必要时将结果转换回浮点值。见。
所有的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
列,你必须索引列的前缀,你不能索引列的全部。
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 < "N";
然而,name
索引将不用在下列询问中:
mysql> SELECT * FROM test WHERE first_name="Michael"; mysql> SELECT * FROM test WHERE last_name="Widenius" OR first_name="Michael";
关于MySQL使用索引改进性能的方式的更多的信息,见。
为了跟容易地使用为其他供应商的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类型报告表结构。
在一个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
( ... )
mysql> select 1+2*3; -> 7 mysql> select (1+2)*3; -> 9
一般的算术操作符是可用的。注意在-
、+
和*
情况下,如果两个参数是整数,结果用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
算术计算,只要在它的结果被转换到一个整数的上下文中执行!
MySQL为位操作使用BIGINT
(64位)算法,因此这些操作符有最大64位的一个范围。
|
mysql> select 29 | 15; -> 31
&
mysql> select 29 & 15; -> 13
<<
BIGINT
)数字。 mysql> select 1 << 2 -> 4
>>
BIGINT
)数字。 mysql> select 4 >> 2 -> 1
~
mysql> select 5 & ~1 -> 4
BIT_COUNT(N)
N
设定的位的数量。 mysql> select BIT_COUNT(29); -> 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
比较操作得出值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 <= 2; -> 1
<
mysql> select 2 <= 2; -> 1
>=
mysql> select 2 >= 2; -> 1
>
mysql> select 2 > 2; -> 0
<=>
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 <= expr AND expr <= max)
。第一个参数(expr
)决定比较如何被执行。如果expr
是一个大小写不敏感的字符串表达式,进行一个大小写不敏感的字符串比较。如果expr
是一个大小写敏感的字符串表达式,进行一个大小写敏感的字符串比较。如果expr
是一个整数表达式,进行整数比较。否则,进行一个浮点(实数)比较。 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)
NULL
的单元。 mysql> select COALESCE(NULL,1); -> 1 mysql> select COALESCE(NULL,NULL,NULL); -> NULL
INTERVAL(N,N1,N2,N3,...)
N
< N1
,返回0
,如果N
< N2
,返回1
等等。所有的参数被当作整数。为了函数能正确地工作,它要求N1
<N2
<N3
< ...
<Nn
。这是因为使用二进制搜索(很快)。 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
通常,如果在字符串比较中的任何表达式是区分大小写的,比较以大小写敏感的方式执行。
expr LIKE pat [ESCAPE 'escape-char']
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\_';
-> 1
为了指定一个不同的转义字符,使用ESCAPE
子句:
mysql> select 'David_' LIKE 'David|_' ESCAPE '|'; -> 1
LIKE
允许用在数字的表达式上!(这是MySQL对ANSI SQL LIKE
的一个扩充。)
mysql> select 10 LIKE '1%'; -> 1
注意:因为MySQL在字符串中使用C转义语法(例如,“\n”),你必须在你的LIKE
字符串中重复任何“\”。例如,为了查找“\n”,指定它为“ \\n”,为了查找“\”,指定它为“\\\\”(反斜线被分析器剥去一次,另一次是在模式匹配完成时,留下一条单独的反斜线被匹配)。
expr NOT LIKE pat [ESCAPE 'escape-char']
NOT (expr LIKE pat [ESCAPE 'escape-char'])
相同。
expr REGEXP pat
expr RLIKE pat
expr
对一个模式pat
的模式匹配。模式可以是一个扩充的正则表达式。见.如果expr
匹配pat
,返回1
,否则返回0
。RLIKE
是REGEXP
的一个同义词,提供了与mSQL
的兼容性。注意:因为MySQL在字符串中使用C转义语法(例如,“\n”), 你必须在你的REGEXP
字符串重复任何“\”。在MySQL
3.23.4中,REGEXP
对于正常的(不是二进制)字符串是忽略大小写。 mysql> select 'Monty!' REGEXP 'm%y%%'; -> 0 mysql> select 'Monty!' REGEXP '.*'; -> 1 mysql> select 'new*\n*line' REGEXP 'new\\*.\\*line'; -> 1 mysql> select "a" REGEXP "A", "a" REGEXP BINARY "A"; -> 1 0
REGEXP
和RLIKE
使用当前的字符集(缺省为ISO-8859-1 Latin1)。
expr NOT REGEXP pat
expr NOT RLIKE pat
NOT (expr REGEXP pat)
相同。
STRCMP(expr1,expr2)
STRCMP()
回来0
,如果第一参数根据当前的排序次序小于第二个,返回-1
,否则返回1
。 mysql> select STRCMP('text', 'text2'); -> -1 mysql> select STRCMP('text2', 'text'); -> 1 mysql> select STRCMP('text', 'text'); -> 0
BINARY
BINARY
操作符强制跟随它后面的字符串为一个二进制字符串。即使列没被定义为BINARY
或BLOB
,这是一个强制列比较区分大小写的简易方法。 mysql> select "a" = "A"; -> 1 mysql> select BINARY "a" = "A"; -> 0
BINARY
在MySQL 3.23.0中被引入。
IFNULL(expr1,expr2)
expr1
不是NULL
,IFNULL()
返回expr1
,否则它返回expr2
。IFNULL()
返回一个数字或字符串值,取决于它被使用的上下文环境。
mysql> select IFNULL(1,0); -> 1 mysql> select IFNULL(0,10); -> 0 mysql> select IFNULL(1/0,10); -> 10 mysql> select IFNULL(1/0,'yes'); -> 'yes'
IF(expr1,expr2,expr3)
expr1
是TRUE(expr1<>0
且expr1<>NULL
),那么IF()
返回expr2
,否则它返回expr3
。IF()
返回一个数字或字符串值,取决于它被使用的上下文。 mysql> select IF(1>2,2,3); -> 3 mysql> select IF(1<2,'yes','no'); -> 'yes' mysql> select IF(strcmp('test','test1'),'yes','no'); -> 'no'
expr1
作为整数值被计算,它意味着如果你正在测试浮点或字符串值,你应该使用一个比较操作来做。
mysql> select IF(0.1,1,0); -> 0 mysql> select IF(0.1<>0,1,0); -> 1
在上面的第一种情况中,IF(0.1)
返回0
,因为0.1
被变换到整数值, 导致测试IF(0)
。这可能不是你期望的。在第二种情况中,比较测试原来的浮点值看它是否是非零,比较的结果被用作一个整数。
CASE value WHEN [compare-value] THEN result [WHEN [compare-value] THEN result ...] [ELSE result] END
CASE WHEN [condition] THEN result [WHEN [condition] THEN result ...] [ELSE result] END
result
,其中value=compare-value
。第二个版本中如果第一个条件为真,返回result。如果没有匹配的result值,那么结果在ELSE
后的result被返回。如果没有ELSE
部分,那么NULL
被返回。 mysql> SELECT CASE 1 WHEN 1 THEN "one" WHEN 2 THEN "two" ELSE "more" END; -> "one" mysql> SELECT CASE WHEN 1>0 THEN "true" ELSE "false" END; -> "true" mysql> SELECT CASE BINARY "B" when "a" then 1 when "b" then 2 END; -> NULL