mysql-logo.gif (3082 bytes)MySQL中文参考手册

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


第一章, 前一章, 下一章, 最后一章目录.


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的先前版本,命名规则如下:

建议你不使用象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_namedb_name.tbl_name前缀,除非引用会有二义性。例如,假定表t1t2,每个均包含列c,并且你用一个使用t1t2SELECT语句检索c。在这种情况下,c有二义性,因为它在使用表的语句中不是唯一的,因此你必须通过写出t1.ct2.c来指明你想要哪个表。同样,如果你从数据库db1中一个表t和在数据库db2的一个表t检索,你必须用db1.t.col_namedb2.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;

列名在所有情况下都是忽略大小写的。

表的别名是区分大小写的。下列查询将不工作: 因为它用aA引用别名:

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。

方括号(“[”“]”)指出可选的类型修饰符的部分。

注意,如果你指定一个了为ZEROFILLMySQL将为该列自动地增加UNSIGNED属性。

TINYINT[(M)] [UNSIGNED] [ZEROFILL]
一个很小的整数。有符号的范围是-128127,无符号的范围是0255
SMALLINT[(M)] [UNSIGNED] [ZEROFILL]
一个小整数。有符号的范围是-3276832767,无符号的范围是065535
MEDIUMINT[(M)] [UNSIGNED] [ZEROFILL]
一个中等大小整数。有符号的范围是-83886088388607,无符号的范围是016777215
INT[(M)] [UNSIGNED] [ZEROFILL]
一个正常大小整数。有符号的范围是-21474836482147483647,无符号的范围是04294967295
INTEGER[(M)] [UNSIGNED] [ZEROFILL]
这是INT的一个同义词。
BIGINT[(M)] [UNSIGNED] [ZEROFILL]
一个大整数。有符号的范围是-92233720368547758089223372036854775807,无符号的范围是018446744073709551615。注意,所有算术运算用有符号的BIGINTDOUBLE值完成,因此你不应该使用大于9223372036854775807(63位)的有符号大整数,除了位函数!注意,当两个参数是INTEGER值时,-+*将使用BIGINT运算!这意味着如果你乘2个大整数(或来自于返回整数的函数),如果结果大于9223372036854775807,你可以得到意外的结果。一个浮点数字,不能是无符号的,对一个单精度浮点数,其精度可以<=24,对一个双精度浮点数,是在25 和53之间,这些类型如FLOATDOUBLE类型马上在下面描述。FLOAT(X)有对应的FLOATDOUBLE相同的范围,但是显示尺寸和小数位数是未定义的。在MySQL3.23中,这是一个真正的浮点值。在更早的MySQL版本中,FLOAT(precision)总是有2位小数。该句法为了ODBC兼容性而提供。
FLOAT[(M,D)] [ZEROFILL]
一个小(单精密)浮点数字。不能无符号。允许的值是-3.402823466E+38-1.175494351E-3801.175494351E-383.402823466E+38。M是显示宽度而D是小数的位数。没有参数的FLOAT或有<24 的一个参数表示一个单精密浮点数字。
DOUBLE[(M,D)] [ZEROFILL]
一个正常大小(双精密)浮点数字。不能无符号。允许的值是-1.7976931348623157E+308-2.2250738585072014E-30802.2250738585072014E-3081.7976931348623157E+308。M是显示宽度而D是小数位数。没有一个参数的DOUBLEFLOAT(X)(25 < = X < = 53)代表一个双精密浮点数字。
DOUBLE PRECISION[(M,D)] [ZEROFILL]
 
REAL[(M,D)] [ZEROFILL]
这些是DOUBLE同义词。
DECIMAL[(M[,D])] [ZEROFILL]
一个未压缩(unpack)的浮点数字。不能无符号。行为如同一个CHAR列:“未压缩”意味着数字作为一个字符串被存储,值的每一位使用一个字符。小数点,并且对于负数,“-”符号不在M中计算。如果D是0,值将没有小数点或小数部分。DECIMAL值的最大范围与DOUBLE相同,但是对一个给定的DECIMAL列,实际的范围可以通过MD的选择被限制。如果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年的某时。MySQLYYYYMMDDHHMMSSYYMMDDHHMMSSYYYYMMDDYYMMDD格式来显示TIMESTAMP值,取决于是否M14(或省略)、1286,但是允许你使用字符串或数字把值赋给TIMESTAMP列。一个TIMESTAMP列对于记录一个INSERTUPDATE操作的日期和时间是有用的,因为如果你不自己给它赋值,它自动地被设置为最近操作的日期和时间。你以可以通过赋给它一个NULL值设置它为当前的日期和时间。见7.3.6 日期和时间类型
TIME
一个时间。范围是'-838:59:59''838:59:59'MySQL'HH:MM:SS'格式来显示TIME值,但是允许你使用字符串或数字把值赋给TIME列。
YEAR[(2|4)]
一个2或4位数字格式的年(缺省是4位)。允许的值是19012155,和0000(4位年格式),如果你使用2位,1970-2069( 70-69)。MySQLYYYY格式来显示YEAR值,但是允许你把使用字符串或数字值赋给YEAR列。(YEAR类型在MySQL3.22中是新类型。)
CHAR(M) [BINARY]
一个定长字符串,当存储时,总是是用空格填满右边到指定的长度。M的范围是1 ~ 255个字符。当值被检索时,空格尾部被删除。CHAR值根据缺省字符集以大小写不区分的方式排序和比较,除非给出BINARY关键词。NATIONAL CHAR(短形式NCHAR)是ANSI SQL的方式来定义CHAR列应该使用缺省字符集。这是MySQL的缺省。CHARCHARACTER的一个缩写。
[NATIONAL] VARCHAR(M) [BINARY]
一个变长字符串。注意:当值被存储时,尾部的空格被删除(这不同于ANSI SQL规范)。M的范围是1 ~ 255个字符。 VARCHAR值根据缺省字符集以大小写不区分的方式排序和比较,除非给出BINARY关键词值。见7.7.1 隐式列指定变化VARCHARCHARACTER VARYING一个缩写。
TINYBLOB
 
TINYTEXT
一个BLOBTEXT列,最大长度为255(2^8-1)个字符。见7.7.1 隐式列指定变化
BLOB
 
TEXT
一个BLOBTEXT列,最大长度为65535(2^16-1)个字符。见7.7.1 隐式列指定变化
MEDIUMBLOB
 
MEDIUMTEXT
一个BLOBTEXT列,最大长度为16777215(2^24-1)个字符。见7.7.1 隐式列指定变化
LONGBLOB
 
LONGTEXT
一个BLOBTEXT列,最大长度为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 < = 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)

7.3.3 日期和时间类型

列类型 需要的存储量
DATE 3 个字节
DATETIME 8 个字节
TIMESTAMP 4 个字节
TIME 3 个字节
YEAR 1 字节

7.3.4 串类型

列类型 需要的存储量
CHAR(M) M字节,1 <= M <= 255
VARCHAR(M) L+1 字节, 在此L <= M1 <= 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个成员)

VARCHARBLOBTEXT类型是变长类型,对于其存储需求取决于列值的实际长度(在前面的表格中用L表示),而不是取决于类型的最大可能尺寸。例如,一个VARCHAR(10)列能保存最大长度为10个字符的一个字符串,实际的存储需要是字符串的长度(L),加上1个字节以记录字符串的长度。对于字符串'abcd'L是4而存储要求是5个字节。

BLOBTEXT类型需要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)。关键词INTINTEGER的一个同义词,而关键词DECDECIMAL一个同义词。

NUMERICDECIMAL类型被MySQL实现为同样的类型,这在SQL92标准允许。他们被用于保存值,该值的准确精度是极其重要的值,例如与金钱有关的数据。当声明一个类是这些类型之一时,精度和规模的能被(并且通常是)指定;例如:

salary DECIMAL(9,2) 

在这个例子中,9(precision)代表将被用于存储值的总的小数位数,而2(scale)代表将被用于存储小数点后的位数。因此,在这种情况下,能被存储在salary列中的值的范围是从-9999999.999999999.99。在ANSI/ISO SQL92中,句法DECIMAL(p)等价于DECIMAL(p,0)。同样,句法DECIMAL等价于DECIMAL(p,0),这里实现被允许决定值pMySQL当前不支持DECIMAL/NUMERIC数据类型的这些变种形式的任一种。这一般说来不是一个严重的问题,因为这些类型的主要益处得自于明显地控制精度和规模的能力。

DECIMALNUMERIC值作为字符串存储,而不是作为二进制浮点数,以便保存那些值的小数精度。一个字符用于值的每一位、小数点(如果scale>0)和“-”符号(对于负值)。如果scale是0,DECIMALNUMERIC值不包含小数点或小数部分。

DECIMALNUMERIC值得最大的范围与DOUBLE一样,但是对于一个给定的DECIMALNUMERIC列,实际的范围可由制由给定列的precisionscale限制。当这样的列赋给了小数点后面的位超过指定scale所允许的位的值,该值根据scale四舍五入。当一个DECIMALNUMERIC列被赋给了其大小超过指定(或缺省的)precisionscale隐含的范围的值,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个数字。用这个选项,第一个数字继续表示在字节计算的值存储需求,而第二个数字指定要被存储的和显示跟随小数点后的位数(就象DECIMALNUMERIC)。当MySQL要求为这样一个列,一个小数点后的小数位超过列指定的值,存储值时,该值被四舍五入,去掉额外的位。

REALDOUBLE PRECISION类型不接受精度说明。作为对 ANSI/ISO SQL92 标准的扩展,MySQL识别出DOUBLE作为DOUBLE PRECISION类型的一个同义词。与REAL精度比用于DOUBLE PRECISION的更小的标准要求相反,MySQL实现了两种,作为8字节双精度浮点值(当运行不是“Ansi模式”时)。为了最大的移植性,近似数字的数据值的存储所需代码应该使用没有精度或小数位数说明的FLOATDOUBLE PRECISION

当要求在数字的列存储超出该列类型允许的范围的值时,MySQL剪切该值到范围内的正确端点值并且存储剪切后的结果值。

例如,一个INT列的范围是-21474836482147483647。如果你试图插入-9999999999到一个INT列中,值被剪切到范围的低部端点,并存储-2147483648。同样,如果你试图插入99999999992147483647被存储。

如果INT列是UNSIGNED,列的范围的大小是相同的,但是它的端点移到了04294967295。如果你试图存储-99999999999999999999,在列被存储的值变为04294967296

对于ALTER TABLELOAD DATA INFILEUPDATE和多行INSERT语句,由于剪切所发生的变换作为“警告”被报告。

7.3.6 日期和时间类型

日期和时间类型是DATETIMEDATETIMESTAMPTIMEYEAR。这些的每一个都有合法值的一个范围,而“零”当你指定确实不合法的值时被使用。注意,MySQL允许你存储某个“不严格地”合法的日期值,例如1999-11-31,原因我们认为它是应用程序的责任来处理日期检查,而不是SQL服务器。为了使日期检查更“快”,MySQL仅检查月份在0-12的范围,天在0-31的范围。上述范围这样被定义是因为MySQL允许你在一个DATEDATETIME列中存储日期,这里的天或月是零。这对存储你不知道准确的日期的一个生日的应用程序来说是极其有用的,在这种情况下,你简单地存储日期象1999-00-001999-01-00。(当然你不能期望从函数如DATE_SUB()DATE_ADD()得到类似以这些日期的正确值)。

当用日期和时间工作时,这里是的一些要记住的一般考虑:

7.3.6.1 Y2K问题和日期类型

MySQL本身Y2K安全的(见1.6 2000年一致性),但是呈交给MySQL的输入值可能不是。一个包含2位年份值的任何输入是由二义性的,因为世纪是未知的。这样的值必须被解释成4位形式,因为MySQL内部使用4位存储年份。

对于DATETIME, DATE, TIMESTAMPYEAR类型,MySQL使用下列规则的解释二义性的年份值:

记得这些规则仅仅提供对于你数据的含义的合理猜测。如果MySQL使用的启发规则不产生正确的值,你应该提供无二义的包含4位年值的输入。

7.3.6.2 DATETIME, DATETIMESTAMP类型

DATETIME, DATETIMESTAMP类型是相关的。本节描述他们的特征,他们是如何类似的而又不同的。

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列类型提供一种类型,你可以使用它自动地用当前的日期和时间标记INSERTUPDATE的操作。如果你有多个TIMESTAMP列,只有第一个自动更新。

自动更新第一个TIMESTAMP列在下列任何条件下发生:

除第一个以外的TIMESTAMP列也可以设置到当前的日期和时间,只要将列设为NULL,或NOW()

通过明确地设置希望的值,你可以设置任何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范围的奇数值尺寸被强制为下一个更大的偶数。

使用一个常用的格式集的任何一个,你可以指定DATETIMEDATETIMESTAMP值:

不合法DATETIME, DATETIMESTAMP值被变换到适当类型的“零”值('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位长,它被假定以YYYYMMDDYYYYMMDDHHMMSS格式并且年份由头4位数字给出。如果数字是6或12位长,它被假定是以YYMMDDYYMMDDHHMMSS格式且年份由头2位数字给出。不是这些长度之一的数字通过填补前头的零到最接近的长度来解释。

指定为无分隔符的字符串用它们给定的长度来解释。如果字符串长度是8或14个字符,年份被假定头4个字符给出,否则年份被假定由头2个字符给出。对于字符串中呈现的多个部分,字符串从左到右边被解释,以找出年、月、日、小时、分钟和秒值,这意味着,你不应该使用少于 6 个字符的字符串。例如,如果你指定'9903',认为将代表1999年3月,你会发现MySQL把一个“零”日期插入到你的表中,这是因为年份和月份值9903,但是日期部分丢失(零),因此该值不是一个合法的日期。

TIMESTAMP列使用被指定的值的完整精度的存储合法的值,不考虑显示大小。这有几个含意:

在某种程度上,你可以把一种日期类型的值赋给一个不同的日期类型的对象。然而,这可能值有一些改变或信息的损失:

当指定日期值时,当心某些缺陷:

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值:

对于作为包括一个时间分隔符的字符串被指定的TIME值,不必为小于10的小时、分钟或秒值指定2位数字,'8:3:2''08:03:02'是一样的。

将“短的”TIME值赋值给一个TIME行列是要格外小心。MySQL使用最右位代表秒的假设来解释值。(MySQLTIME值解释为经过的时间,而非作为一天的时间 )例如,你可能想到'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值,其范围是19012155

你能用多种格式指定YEAR值:

不合法YEAR值被变换到0000

7.3.7 字符串类型

字符串类型是CHARVARCHARBLOBTEXTENUMSET

7.3.7.1 CHARVARCHAR类型

CHARVARCHAR类型是类似的,但是在他们被存储和检索的方式不同。

一个CHAR列的长度被修正为在你创造表时你所声明的长度。长度可以是1和255之间的任何值。(在MySQL 3.23中,CHAR长度可以是0~255。) 当CHAR值被存储时,他们被用空格在右边填补到指定的长度。当CHAR值被检索时,拖后的空格被删去。

VARCHAR列中的值是变长字符串。你可以声明一个VARCHAR列是在1和255之间的任何长度,就像对CHAR列。然而,与CHAR相反,VARCHAR值只存储所需的字符,外加一个字节记录长度,值不被填补;相反,当值被存储时,拖后的空格被删去。(这个空格删除不同于ANSI SQL规范。)

如果你把一个超过列最大长度的值赋给一个CHARVARCHAR列,值被截断以适合它。

下表显示了两种类型的列的不同,通过演示存储变长字符串值到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列上被删除。

CHARVARCHAR列中存储和比较值是以大小写不区分的方式进行的,除非当桌子被创建时,BINARY属性被指定。BINARY属性意味着该列的值根据MySQL服务器正在运行的机器的ASCII顺序以大小写区分的方式存储和比较。

BINARY属性是“粘性”的。这意味着,如果标记了BINARY的列用于一个表达式中,整个的表达式作为一个BINARY值被比较。

MySQL在表创建时可以隐含地改变一个CHARVARCHAR列的类型。见7.7.1 隐含的的列说明改变

7.3.7.2 BLOBTEXT类型

一个BLOB是一个能保存可变数量的数据的二进制的大对象。4个BLOB类型TINYBLOBBLOBMEDIUMBLOBLONGBLOB仅仅在他们能保存值的最大长度方面有所不同。见7.3.1 列类型存储需求

4个TEXT类型TINYTEXTTEXTMEDIUMTEXTLONGTEXT对应于4个BLOB类型,并且有同样的最大长度和存储需求。在BLOBTEXT类型之间的唯一差别是对BLOB值的排序和比较以大小写敏感方式执行,而对TEXT值是大小写不敏感的。换句话说,一个TEXT是一个大小写不敏感的BLOB

如果你把一个超过列类型最大长度的值赋给一个BLOBTEXT列,值被截断以适合它。

在大多数方面,你可以认为一个TEXT行列是你所希望大的一个VARCHAR列。同样,你可以认为一个BLOB列是一个VARCHAR BINARY列。差别是:

MyODBC定义BLOBLONGVARBINARYTEXT值为LONGVARCHAR

因为BLOBTEXT值可以是非常长的,当使用他们时,你可能遇到一些限制:

注意,每个BLOBTEXT值内部由一个独立分配的对象表示。这与所有的其他列类型相反,它们是在打开表时,按列被分配一次存储。

7.3.7.3 ENUM类型

一个ENUM是一个字符对象,其值通常从一个在表创建时明确被列举的允许值的一张表中选择。

在下列的某个情形下,值也可以空字符串("")或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