վÄÚËÑË÷: ÇëÊäÈëËÑË÷¹ؼü´Ê
µ±ǰҳÃæ: ÔÚÏßÎĵµÊ×ҳ > MySQL 5.1²ο¼ÊֲáÖÐÎİæ

Chapter 11. Column Types - MySQL 5.1²ο¼ÊֲáÖÐÎİæ

ç¬�11章:列类åž�

MySQL支持多种列类型:数值类型、日æœ�/时间类型和字符串(字符)类型。本章首先对这些列类型进行了概述,然后更加详细地描述了各种列的类型,以及列类型存储需求的总结。概述很简单。关于具体列类型的详细信息应查阅详细的描述,例如指定值时允许使用的格式ã€�

MySQL支持处理空间数据的扩展名。关于空间类型的信息参见ç¬�19章:MySQL中的空间扩展ã€�

几种列类型描述使用了下述惯例ï¼�

·         M

表示最大显示宽度。最大有效显示宽度是255ã€�

·         D

适用于浮点和定点类型,并表示小数点后面的位数。最大可能的值是30,但不应大于M-2ã€�

·         方括å��(â€�[’和â€�]â€�)表示可选部分ã€�

11.1. 列类型概è¿�

11.1.1. 数值类型概è¿�

下面为数值列类型的概述。详细信息参è§�11.2节,“数值类型â€�。列存储需求参è§�11.5节,“列类型存储需求â€�ã€�

M指示最大显示宽度。最大有效显示宽度是255。显示宽度与存储大小或类型包含的值的范围无关,相关描述见11.2节,“数值类型â€�ã€�

如果为一个数值列指定ZEROFILLï¼�MySQL自动为该列添åŠ�UNSIGNED属性ã€�

SERIALæ˜�BIGINT UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE的一个别名ã€�

在整数列定义中,SERIAL DEFAULT VALUEæ˜�NOT NULL AUTO_INCREMENT UNIQUE的一个别名ã€�

警告ï¼�应当清楚,当使用在整数值(其中一个是UNSIGNED类型)之间使用减号时,结果是无符号。参è§�12.8节,“Cast函数和操作符â€�ã€�

·         BIT[(M)]

位字段类型ã€�M表示每个值的位数,范围为ä»�1åˆ�64。如æž�M被省略, 默认ä¸�1ã€�

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

很小的整数。带符号的范围是-128åˆ�127。无符号的范围是0åˆ�255ã€�

·         BOOLï¼�BOOLEAN

æ˜�TINYINT(1)的同义词ã€�zero值被视为假。非zero值视为真ã€�

在将来,将根据标å‡�SQL引入完全布尔类型的处理ã€�

·         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列的下述内容ï¼�

o        使用带符号的BIGINTæˆ�DOUBLE值进行所有算法,因此除了位函数,不应使用大于9223372036854775807(63ä½�)的无符号的大整数! 如果这样做,结果中的最后几位可能出错,这是由于å°�BIGINT值转换为DOUBLE进行四舍五入时造成的错误ã€�

MySQL可以在以下情况下处理BIGINTï¼�

§         当使用整数在一ä¸�BIGINT列保存大的无符号的值时ã€�

§         åœ�MIN(col_name)æˆ�MAX(col_name)中,其中col_nameæŒ�BIGINT列ã€�

§         使用操作ç¬�(+ï¼�-ï¼�*等等)并且两个操作数均为整数时ã€�

o        总是可以使用一个字符串åœ�BIGINT列中保存严格整数值。在这种情况下,MySQL执行字符ä¸�-数字转换,其间不存在双精度表示ã€�

o        当两个操作数均为整数值时ï¼�-ã€�+å’�* 操作符使ç”�BIGINT算法。这说明如果乘两个大整数(或来自返回整数的函数),当结果大于9223372036854775807时,会得到意想不到的结果ã€�

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

å°�(单精åº�)浮点数。允许的值是-3.402823466E+38åˆ�-1.175494351E-38ã€�0å’�1.175494351E-38åˆ�3.402823466E+38。这些是理论限制,基äº�IEEE标准。实际的范围根据硬件或操作系统的不同可能稍微小些ã€�

M是小数纵位数ï¼�D是小数点后面的位数。如æž�Må’�D被省略,根据硬件允许的限制来保存值。单精度浮点数精确到大约7位小数位ã€�

如果指定UNSIGNED,不允许负值ã€�

使用浮点数可能会遇到意想不到的问题,因为åœ�MySQL中的所有计算用双精度完成。参è§�A.5.7节,“解决与不匹配行有关的问题â€�ã€�

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

普通大å°�(双精åº�)浮点数。允许的值是-1.7976931348623157E+308åˆ�-2.2250738585072014E-308ã€�0å’�2.2250738585072014E-308åˆ� 1.7976931348623157E+308。这些是理论限制,基äº�IEEE标准。实际的范围根据硬件或操作系统的不同可能稍微小些ã€�

M是小数总位数,D是小数点后面的位数。如æž�Må’�D被省略,根据硬件允许的限制来保存值。双精度浮点数精确到大约15位小数位ã€�

如果指定UNSIGNED,不允许负值ã€�

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

ä¸�DOUBLE的同义词。除了:如果SQL服务器模式包æ‹�REAL_AS_FLOAT选项ï¼�REALæ˜�FLOAT的同义词而不æ˜�DOUBLE的同义词ã€�

·         FLOAT(p) [UNSIGNED] [ZEROFILL]

浮点数ã€�p表示精度(以位数表示),ä½�MySQL只使用该值来确定是否结果列的数据类型ä¸�FLOATæˆ�DOUBLE。如æž�p为从0åˆ�24,数据类型变为没æœ�Mæˆ�D值的FLOAT。如æž�p为从25åˆ�53,数据类型变为没æœ�Mæˆ�D值的DOUBLE。结果列范围与本节前面描述的单精åº�FLOAT或双精度DOUBLE数据类型相同ã€�

FLOAT(p)语法ä¸�ODBC兼容ã€�

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

压缩的â€�严格”定点数ã€�M是小数位æ•�(精度)的总数ï¼�D是小数点(标度)后面的位数。小数点å’�(负数)的â€�-’符号不包括åœ�M中。如æž�Dæ˜�0,则值没有小数点或分数部分ã€�DECIMAL整数最大位æ•�(M)ä¸�65。支持的十进制数的最大位æ•�(D)æ˜�30。如æž�D被省略, 默认æ˜�0。如æž�M被省略, 默认æ˜�10ã€�

如果指定UNSIGNED,不允许负值ã€�

所æœ�DECIMAL列的基本计算(+ï¼�-ï¼�*ï¼�/)ç”�65位精度完成ã€�

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

æ˜�DECIMAL的同义词ã€�FIXED同义词适用于与其它服务器的兼容性ã€�

11.1.2. 日期和时间类型概è¿�

本节综合讨论了临时列类型。详细信息,参见11.3节,“日期和时间类型â€�。列存储需求参è§�11.5节,“列类型存储需求â€�ã€�

·         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年ã€�

TIMESTAMP列用äº�INSERTæˆ�UPDATE操作时记录日期和时间。如果你不分配一个值,表中的第一ä¸�TIMESTAMP列自动设置为最近操作的日期和时间。也可以通过分配一ä¸�NULL值,å°�TIMESTAMP列设置为当前的日期和时间ã€�

TIMESTAMP值返回后显示ä¸�'YYYY-MM-DD HH:MM:SS'格式的字符串,显示宽度固定为19个字符。如果想要获得数字值,应在TIMESTAMP 列添åŠ�+0ã€�

注释ï¼�MySQL 4.1以前使用çš�TIMESTAMP格式åœ�MySQL 5.1中不支持;关于旧格式的信息参è§�MySQL 4.1 参考手å†�ã€�

·         TIME

时间。范围是'-838:59:59'åˆ�'838:59:59'ã€�MySQLä»�'HH:MM:SS'格式显示TIME值,但允许使用字符串或数字为TIME列分配值ã€�

·         YEAR[(2|4)]

两位或四位格式的年。默认是四位格式。在四位格式中,允许的值是1901åˆ�2155å’�0000。在两位格式中,允许的值是70åˆ�69,表示从1970年到2069年ã€�MySQLä»�YYYY 格式显示YEAR值,但允许使用字符串或数字为YEAR列分配值ã€�

11.1.3. 字符串类型概è¿�

本节综合讨论了字符串列类型。详细信息参è§�11.4节,“String类型â€�。列存储需求参è§�11.5节,“列类型存储需求â€�ã€�

在某些情况中ï¼�MySQL可以将一个字符串列更改为不同äº�CREATE TABLEæˆ�ALTER TABLE语句中所给出的类型。参è§�13.1.5.1节,“沉寂的列规格变更â€�ã€�

MySQL 5.1字符串数据类型包括部分在MySQL 4.1之前的版本中没有的特性:

·         许多字符串数据类型的列定义可以包括指定字符集çš�CHARACTER SET属性,也可能包括校对规则ã€�(CHARSETæ˜�CHARACTER SET的一个同义词ï¼�ã€�这些属性适用äº�CHARã€�VARCHARã€�TEXT类型ã€�ENUMå’�SET。例如:

·                CREATE TABLE t
·                (
·                    c1 CHAR(20) CHARACTER SET utf8,
·                    c2 CHAR(20) CHARACTER SET latin1 COLLATE latin1_bin
·                );

该表定义创建了一个名ä¸�c1的列,具有一ä¸�utf8字符集和该字符集的默è®� 校对规则,和一个名ä¸�c2的列以及latin1字符集和该字符集的二å…� 校对规则。二元校对规则对大小写不敏感ã€�

·         MySQL 5.1用字符单位解释在字符列定义中的长度规范ã€�(以前的一äº�MySQL版本以字节解释长度)ã€�

·         对于CHARã€�VARCHARå’�TEXT类型ï¼�BINARY属性可以为列分配该列字符集çš� 校对规则ã€�

·         字符列的排序和比较基于分配给列的字符集。在以前的版本中,排序和比较基于服务器字符集的校对规则。对äº�CHARå’�VARCHAR 列,你可以用BINARY属性声明列让排序和 校对规则使用当前的字符代码值而不是词汇顺序ã€�

关于MySQL 5.1中字符集的支持,参见ç¬�10章:字符集支æŒ�ã€�

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

固定长度字符串,当保存时在右侧填充空格以达到指定的长度ã€�M表示列长度ã€�M的范围是0åˆ�255个字符ã€�

注释ï¼�当检ç´�CHAR值时尾部空格被删除ã€�

如果想要将某ä¸�CHAR的长度设为大äº�255,执行的CREATE TABLEæˆ�ALTER TABLE语句将失败并提示错误ï¼�

mysql> CREATE TABLE c1 (col1 INT, col2 CHAR(500));
ERROR 1074 (42000): Column length too big for column 'col' (max = 255); use BLOB or TEXT instead
mysql> SHOW CREATE TABLE c1;
ERROR 1146 (42S02): Table 'test.c1' doesn't exist

CHARæ˜�CHARACTER的简写ã€�NATIONAL CHAR(或其等效短形å¼�NCHAR)是标准的定义CHAR列应使用 默认字符集的SQL方法。这åœ�MySQL中为默认值ã€�

BINARY属性是指定列字符集的二å…� 校对规则的简写。排序和比较基于数值字符值ã€�

列类åž�CHAR BYTEæ˜�CHAR BINARY的一个别名。这是为了保证兼容性ã€�

可以ä¸�CHAR指定ASCII属性。它分配latin1字符集ã€�

可以ä¸�CHAR指定UNICODE属性。它分配ucs2字符集ã€�

MySQL允许创建类型CHAR(0)的列。这主要用于必须有一个列但实际上不使用值的旧版本的应用程序相兼容。当你需要只能取两个值的列时也很好:没有定义ä¸�NOT NULL的一ä¸�CHAR(0)列只占用一位,只可以取å€�NULLå’�''(空字符串)ã€�

·         CHAR

这是CHAR(1)的同义词ã€�

·         [NATIONAL] VARCHAR(M) [BINARY]

变长字符串ã€�M 表示最大列长度ã€�M的范围是0åˆ�65,535ã€�(VARCHAR的最大实际长度由最长的行的大小和使用的字符集确定。最å¤�有效长度æ˜�65,532字节ï¼�ã€�

注释ï¼�MySQL 5.1遵从标准SQL规范,并且不删除VARCHAR值的尾部空格ã€�

VARCHAR是字ç¬�VARYING的简写ã€�

BINARY属性是指定列的字符集的二元 校对规则的简写。排序和比较基于数值字符值ã€�

VARCHAR保存时用一个字节或两个字节长的前缀+数据。如æž�VARCHAR列声明的长度大于255,长度前缀是两个字节ã€�

·         BINARY(M)

BINARY类型类似äº�CHAR类型,但保存二进制字节字符串而不是非二进制字符串ã€�

·         VARBINARY(M)

VARBINARY类型类似äº�VARCHAR类型,但保存二进制字节字符串而不是非二进制字符串ã€�

·         TINYBLOB

最大长度为255(28â€�1)字节çš�BLOB列ã€�

·         TINYTEXT

最大长度为255(28â€�1)字符çš�TEXT列ã€�

·         BLOB[(M)]

最大长度为65,535(216â€�1)字节çš�BLOB列ã€�

可以给出该类型的可选长åº�M。如果给出,åˆ�MySQL将列创建为最小的但足以容çº�M字节长的值的BLOB类型ã€�

·         TEXT[(M)]

最大长度为65,535(216â€�1)字符çš�TEXT列ã€�

可以给出可选长åº�M。则MySQL将列创建为最小的但足以容çº�M字符长的值的TEXT类型ã€�

·         MEDIUMBLOB

最大长度为16,777,215(224â€�1)字节çš�BLOB列ã€�

·         MEDIUMTEXT

最大长度为16,777,215(224â€�1)字符çš�TEXT列ã€�

·         LONGBLOB

最大长度为4,294,967,295æˆ�4GB(232â€�1)字节çš�BLOB列ã€�LONGBLOB列的最å¤�有效(允许çš�)长度取决于客户端/服务器协议中配置最大包大小和可用的内存ã€�

·         LONGTEXT

最大长度为4,294,967,295æˆ�4GB(232â€�1)字符çš�TEXT列ã€�LONGTEXT列的最å¤�有效(允许çš�)长度取决于客户端/服务器协议中配置最大包大小和可用的内存ã€�

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

枚举类型。只能有一个值的字符串,从值列'value1'ï¼�'value2'ï¼�...ï¼�NULL中或特殊 ''错误值中选出ã€�ENUM列最多可以有65,535个截然不同的值ã€�ENUM值在内部用整数表示ã€�

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

一个设置。字符串对象可以有零个或多个值,每个值必须来自列å€�'value1'ï¼�'value2'ï¼�...SET列最多可以有64个成员ã€�SET值在内部用整数表示ã€�

11.2. 数值类åž�

MySQL支持所有标å‡�SQL数值数据类型。这些类型包括严格数值数据类åž�(INTEGERã€�SMALLINTã€�DECIMALå’�NUMERIC),以及近似数值数据类åž�(FLOATã€�REALå’�DOUBLE PRECISION)。关键字INTæ˜�INTEGER的同义词,关键字DECæ˜�DECIMAL的同义词ã€�

BIT数据类型保存位字段值,并且支持MyISAMã€�MEMORYã€�InnoDBå’�BDB表ã€�

作为SQL标准的扩展,MySQL也支持整数类åž�TINYINTã€�MEDIUMINTå’�BIGINT。下面的表显示了需要的每个整数类型的存储和范围ã€�

类型

字节

最小å€�

最大å€�

 

 

(带符号的/无符号的)

(带符号的/无符号的)

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还支持选择在该类型关键字后面的括号内指定整数值的显示宽度(例如ï¼�INT(4))。该可选显示宽度规定用于显示宽度小于指定的列宽度的值时从左侧填满宽度ã€�

显示宽度并不限制可以在列内保存的值的范围,也不限制超过列的指定宽度的值的显示ã€�

当结合可选扩展属æ€�ZEROFILL使用时, 默认补充的空格用零代替。例如,对于声明ä¸�INT(5) ZEROFILL的列,å€�4检索为00004。请注意如果在整数列保存超过显示宽度的一个值,å½�MySQL为复杂联接生成临时表时会遇到问题,因为在这些情况ä¸�MySQL相信数据适合原列宽度ã€�

所有整数类型可以有一个可é€�(非标å‡�)属æ€�UNSIGNED。当你想要在列内只允许非负数和该列需要较大的上限数值范围时可以使用无符号值ã€�

浮点和定点类型也可以ä¸�UNSIGNED。同数类型,该属性防止负值保存到列中。然而,与整数类型不同的是,列值的上范围保持不变ã€�

如果为一个数值列指定ZEROFILLï¼�MySQL自动为该列添åŠ�UNSIGNED属性ã€�

对于浮点列类型,åœ�MySQL中单精度值使ç”�4个字节,双精度值使ç”�8个字节ã€�

FLOAT类型用于表示近似数值数据类型ã€�SQL标准允许在关键字FLOAT后面的括号内选择用位指定精度(但不能为指数范围)ã€�MySQL还支持可选的只用于确定存储大小的精度规定ã€�0åˆ�23的精度对åº�FLOAT列的4字节单精度ã€�24åˆ�53的精度对åº�DOUBLE列的8字节双精度ã€�

MySQL允许使用非标准语法:FLOAT(M,D)æˆ�REAL(M,D)æˆ�DOUBLE PRECISION(M,D)。这里,â€�(M,D)”表示该值一共显ç¤�M位整数,其中D位位于小数点后面。例如,定义ä¸�FLOAT(7,4)的一个列可以显示ä¸�-999.9999ã€�MySQL保存值时进行四舍五入,因此如果在FLOAT(7,4)列内插入999.00009,近似结果是999.0001ã€�

MySQLå°�DOUBLE视为DOUBLE PRECISION(非标准扩å±�)的同义词ã€�MySQL还将REAL视为DOUBLE PRECISION(非标准扩å±�)的同义词,除é��SQL服务器模式包æ‹�REAL_AS_FLOAT选项ã€�

为了保证最大可能的可移植性,需要使用近似数值数据值存储的代码应使ç”�FLOATæˆ�DOUBLE PRECISION,不规定精度或位数ã€�

DECIMALå’�NUMERIC类型åœ�MySQL中视为相同的类型。它们用于保存必须为确切精度的值,例如货币数据。当声明该类型的列时,可ä»�(并且通常è¦�)指定精度和标度;例如ï¼�

salary DECIMAL(5,2)

在该例子中,5是精度,2是标度。精度表示保存值的主要位数,标度表示小数点后面可以保存的位数ã€�

åœ�MySQL 5.1中以二进制格式保å­�DECIMALå’�NUMERIC值ã€�

标准SQL要求salary列能够用5位整数位和两位小数保存任何值。因此,在这种情况下可以保存åœ�salary列的值的范围是从-999.99åˆ�999.99ã€�

在标å‡�SQL中,语法DECIMAL(M)等价äº�DECIMAL(M,0)。同样,语法DECIMAL等价äº�DECIMAL(M,0),可以通过计算确定M的值。在MySQL 5.1中支æŒ�DECIMALå’�NUMERIC数据类型的变量形式ã€�M默认值是10ã€�

DECIMALæˆ�NUMERIC的最大位数是65,但具体çš�DECIMALæˆ�NUMERIC列的实际范围受具体列的精度或标度约束。如果此类列分配的值小数点后面的位数超过指定的标度允许的范围,值被转换为该标度ã€�(具体操作与操作系统有关,但一般结果均被截取到允许的位数)ã€�

BIT数据类型可用来保存位字段值ã€�BIT(M)类型允许存储M位值ã€�M范围ä¸�1åˆ�64ã€�

要指定位值,可以使用b'value'符ã€�value是一个用0å’�1编写的二进制值。例如,b'111'å’�b'100000000'分别表示7å’�128。参è§�9.1.5节,“位字段值â€�ã€�

如果ä¸�BIT(M)列分配的值的长度小于M位,在值的左边ç”�0填充。例如,ä¸�BIT(6)列分配一个å€�b'101',其效果与分é…�b'000101'相同ã€�

当要在一个数值列内保存一个超出该列允许范围的值时ï¼�MySQL的操作取决于此时有效çš�SQL模式。如果模式未设置ï¼�MySQL将值裁剪到范围的相应端点,并保存裁减好的值。但是,如果模式设置ä¸�traditional(“严æ �模式â€�),超出范围的值将被拒绝并提示错误,并且根æ��SQL标准插入会失败。参è§�5.3.2节,“SQL服务器模式â€�ã€�

如果INT列是UNSIGNED,列范围的大小相同,但其端点会变为到0å’�4294967295。如果你试图保存-9999999999å’�9999999999,以非严格模式保存到列中的值是0å’�4294967296ã€�

如果在浮点或定点列中分配的值超过指å®�(或默è®�)精度和标度规定的范围ï¼�MySQL以非严格模式保存表示范围相应端点的值ã€�

å½�MySQL没有工作在严格模式时,对äº�ALTER TABLEã€�LOAD DATA INFILEã€�UPDATE和多è¡�INSERT语句,由于裁剪发生的转换将报告为警告。当MySQL工作在严格模式时,这些语句将失败,并且部分或全部值不会插入或更改,取决于是否表为事务表和其它因素。详情参è§�5.3.2节,“SQL服务器模式â€�ã€�

11.3. 日期和时间类åž�

表示时间值的DATE和时间类型为DATETIMEã€�DATEã€�TIMESTAMPã€�TIMEå’�YEAR。每个时间类型有一个有效值范围和一个â€�é›�”值,当指定不合法çš�MySQL不能表示的值时使用â€�é›�”值ã€�TIMESTAMP类型有专有的自动更新特性,将在后面描述ã€�

如果试图插入一个不合法的日期,MySQL将给出警告或错误。可以使ç”�ALLOW_INVALID_DATES SQL模式è®�MySQL接受某些日期,例å¦�'1999-11-31'。当你想要保存一个â€�可能错误çš�”用户已经在数据库中指定(例如,以web形式)用于将来处理的值时很有用。在这种模式下,MySQL只验证月范围为从0åˆ�12,日范围为从0åˆ�31。这些范围可以包括零,因ä¸�MySQL允许åœ�DATEæˆ�DATETIME列保存日/月和日是零的日期。这在应用程序需要保存一个你不知道确切日期的生日时非常有用。在这种情况下,只需要将日期保存ä¸�'1999-00-00'æˆ�'1999-01-00'。如果保存此类日期,DATE_SUB()æˆ�DATE_ADD等需要完整日期的函数不会得到正确的结果ã€�(如果你不想在日期中出现零,可以使ç”�NO_ZERO_IN_DATE SQL模式)ã€�

MySQL还允许将'0000-00-00'保存为“伪日期â€�(如果不使ç”�NO_ZERO_DATE SQL模式)。这在某些情况下比使ç”�NULL值更方便(并且数据和索引占用的空间更小)ã€�

å°�sql_mode系统变量设置为相应模式值,可以更确切你想让MySQL支持哪种日期。参è§�5.3.2节,“SQL服务器模式â€�ã€�

当使用日期和时间类型时应记住以下几点ï¼�

·         MySQL以标准输出格式检索给定日期或时间类型的值,但它尽力解释你指定的各种输入值格å¼�(例如,当你指定一个分配给或与日期或时间类型进行比较的值时)。只支持下面章节中描述的格式。期望你能提供有效值。如果你使用其它格式的值会发生意想不到的结果ã€�

·         包含两位年值的日期会令人模糊,因为世纪不知道ã€�MySQL使用以下规则解释两位年值:

o        70-99范围的年值转换为1970-1999ã€�

o        00-69范围的年值转换为2000-2069ã€�

·         尽管MySQL尝试解释几种格式的值,日期总是以年-æœ�-日顺åº�(例如ï¼�'98-09-04'),而不是其它地方常用的æœ�-æ—�-年或æ—�-æœ�-年顺åº�(例如ï¼�'09-04-98'ï¼�'04-09-98')ã€�

·         如果值用于数值上下文中,MySQL自动将日期或时间类型的值转换为数字,反之亦然ã€�

·         å½� MySQL遇到一个日期或时间类型的超出范围或对于该类型不合法的值时(如本节开始所描述),它将该值转换为该类的â€�é›�”值。一个例外是超出范围çš�TIME值被裁剪åˆ�TIME范围的相应端点ã€�

下面的表显示了各类â€�é›�”值的格式。请注意如果启用NO_ZERO_DATE SQL模式,使用这些值会产生警告ã€�

列类åž�

â€�é›�”å€�

DATETIME

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

DATE

'0000-00-00'

TIMESTAMP

00000000000000

TIME

'00:00:00'

YEAR

0000

·         â€�é›�”值是特殊值,但你可以使用表内显示的值显式保存或引用它们。你也可以使用å€�'0'æˆ�0来保存或引用,写起来更容易ã€�

·         MyODBC中使用的â€�é›�”日期或时间值在MyODBC 2.50.12和以上版本中被自动转换为NULL,因ä¸�ODBC不能处理此类值ã€�

11.3.1. 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列类型的属性不固定,取决于MySQL版本和服务器运行çš�SQL模式。这些属性将在本节后面描述ã€�

可以使用任何常见格式指定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',但'971122129015'是不合法çš�(它有一个没有意义的分钟部分),将变为'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,不需要指定两位数ã€�'1979-6-9'ä¸�'1979-06-09'是相同的。同样,对于包括时间部分间割符的字符串值,如果时、分和秒的值小äº�10,不需要指定两位数ã€�'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,但日部分完全丢失,因此该值不是一个合法的日期。但是,可以明显指定一个零值来代表缺少的月或日部分。例如,可以使用'990300'来插入å€�'1999-03-00'ã€�

在一定程度上,可以将一个日期类型的值分配给一个不同的日期类型。但是,值可能会更改或丢失一些信息:

·         如果你为一ä¸�DATETIMEæˆ�TIMESTAMP对象分配一ä¸�DATE值,结果值的时间部分被设置为'00:00:00',因ä¸�DATE值未包含时间信息ã€�

·         如果你为一ä¸�DATE对象分配一ä¸�DATETIMEæˆ�TIMESTAMP值,结果值的时间部分被删除,因为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'不是合法月ã€�

·         在非严格模式ï¼�MySQL服务器只对日期的合法性进行基本检查:年、月和日的范围分别是1000åˆ�9999ã€�00åˆ�12å’�00åˆ�31。任何包含超出这些范围的部分的日期被转换æˆ�'0000-00-00'。请注意仍然允许你保存非法日期,例如'2002-04-31'。要想确保不使用严格模式时日期有效,应检查应用程序ã€�

在严格模式,非法日期不被接受,并且不转换ã€�

详细信息参见5.3.2节,“SQL服务器模式â€�ã€�

·         包含两位年值的日期会令人模糊,因为世纪不知道ã€�MySQL使用以下规则解释两位年值:

o        00-69范围的年值转换为2000-2069ã€�

o        70-99范围的年值转换为1970-1999ã€�

11.3.1.1. 自MySQL 4.1以来的TIMESTAMP属æ€�

注释ï¼�åœ�旧版本的MySQLä¸�(4.1之前)ï¼�TIMESTAMP列类型的属性在许多方面于本节所描述的大大不同。如果你需要对旧的TIMESTAMP数据进行转化以便åœ�MySQL 5.1中工作,详情请参è§�MySQL 4.1 参考手å†�ã€�

TIMESTAMP列的显示格式ä¸�DATETIME列相同。换句话说,显示宽度固定åœ�19字符,并且格式为YYYY-MM-DD HH:MM:SSã€�

MySQL服务器也可以ä»�MAXDB模式运行。当服务器以该模式运行时ï¼�TIMESTAMPä¸�DATETIME相等。也就是说,如果创建表时服务器以MAXDB模式运行ï¼�TIMESTAMP列创建为DATETIME列。结果是,该列使ç”�DATETIME显示格式,有相同的值范围,并且没有自动对当前的日期和时间进行初始化或更新ã€�

要想启用MAXDB模式,在启动服务器时使用--sql-mode=MAXDB服务器选项或在运行时通过设置全局sql_mode变量å°�SQL服务器模式设置为MAXDBï¼�

mysql> SET GLOBAL sql_mode=MAXDB�

客户端可以按照下面方法让服务器为它的连接ä»�MAXDB模式运行ï¼�

mysql> SET SESSION sql_mode=MAXDB;

 

MySQL不接受在日或月列包括一个零或包含非法日期值的时间戳值。该规则的唯一例外是特殊å€�'0000-00-00 00:00:00'ã€�

你可以非常灵便地确定什么时候初始化和更æ–�TIMESTAMP和对哪些列进行初始化和更新:

·         你可以将当前的时间戳指定为默认值和自动更新的值。但只能选择一个,或者两者都不选ã€�(不可能一个列选择一个行为而另一个列选择另一个行为)ã€�

·         你可以指定哪ä¸�TIMESTAMP列自动初始化或更新为当前的日期和时间。不再需要为ç¬�1ä¸�TIMESTAMP列ã€�

请注意下面讨论所信息只适用于创建时未启ç”�MAXDB模式的表çš�TIMESTAMP列ã€�(如上所述,MAXDB模式使列创建ä¸�DATETIME列)ã€�控制TIMESTAMP列的初始化和更新的规则如下所示:

·         如果一个表内的ç¬�1ä¸�TIMESTAMP列指定为一ä¸�DEFAULT值,则不能忽略ã€� 默认值可以为CURRENT_TIMESTAMP或常量日期和时间值ã€�

·         DEFAULT NULL与第1ä¸�TIMESTAMP 列的DEFAULT CURRENT_TIMESTAMP相同。对于其å®�TIMESTAMP列,DEFAULT NULL被视ä¸�DEFAULT 0ã€�

·         表内的任何一ä¸�TIMESTAMP列可以设置为自动初始化为当前时间戳和/或更新ã€�

·         åœ�CREATE TABLE语句中,可以用下面的任何一种方式声明第1ä¸�TIMESTAMP列:

o        ç”�DEFAULT CURRENT_TIMESTAMPå’�ON UPDATE CURRENT_TIMESTAMP子句,列为默认值使用当前的时间戳,并且自动更新ã€�

o        不使ç”�DEFAULTæˆ�ON UPDATE子句,与DEFAULT CURRENT_TIMESTAMP ON UPDATECURRENT_TIMESTAMP相同ã€�

o        ç”�DEFAULT CURRENT_TIMESTAMP子句不用ON UPDATE子句,列为默认值使用当前的时间戳但是不自动更新ã€�

o        不用DEFAULT子句但用ON UPDATE CURRENT_TIMESTAMP子句,列有默认å€�0并自动更新ã€�

o        用常é‡�DEFAULT值,列有给出çš� 默认值。如果列有一ä¸�ON UPDATE CURRENT_TIMESTAMP子句,它自动更新,否则不ã€�

换句话说,你可以为初始值和自动更新的值使用当前的时间戳,或者其中一个使用,或者两个皆不使用ã€�(例如,你可以指定ON UPDATE来启用自动更新而不让列自动初始化)ã€�

·         åœ�DEFAULTå’�ON UPDATE子句中可以使ç”�CURRENT_TIMESTAMPã€�CURRENT_TIMESTAMP()或è€�NOW()。它们均具有相同的效果ã€�

两个属性的顺序并不重要。如果一ä¸�TIMESTAMP列同时指定了DEFAULTå’�ON UPDATE,任何一个可以在另一个的前面ã€�

例子,下面这些语句是等效的:

CREATE TABLE t (ts TIMESTAMP);
CREATE TABLE t (ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP
                             ON UPDATE CURRENT_TIMESTAMP);
CREATE TABLE t (ts TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
                             DEFAULT CURRENT_TIMESTAMP);

·         要为TIMESTAMP列而不是第1列指定自动默认或更新,必须通过将第1ä¸�TIMESTAMP列显式分配一个常é‡�DEFAULT值来禁用自动初始化和更新ã€�(例如ï¼�DEFAULT 0æˆ�DEFAULT'2003-01-01 00:00:00')。然后,对于其它TIMESTAMP列,规则与第1ä¸�TIMESTAMP列相同,例外情况是不能忽ç•�DEFAULTå’�ON UPDATE子句。如果这样做,则不会自动进行初始化或更新ã€�

例如:下面这些语句是等效的:

CREATE TABLE t (
    ts1 TIMESTAMP DEFAULT 0,
    ts2 TIMESTAMP DEFAULT CURRENT_TIMESTAMP
                  ON UPDATE CURRENT_TIMESTAMP);
CREATE TABLE t (
    ts1 TIMESTAMP DEFAULT 0,
    ts2 TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
                  DEFAULT CURRENT_TIMESTAMP);

可以对每个连接设置当前的时区,相关描述参è§�5.10.8节,“MySQL服务器时区支持â€�ã€�TIMESTAMP值以UTC格式保存,存储时对当前的时区进行转换,检索时再转换回当前的时区。只要时区设定值为常量,便可以得到保存时的值。如果保存一ä¸�TIMESTAMP值,应更改时区然后检索该值,它与你保存的值不同。这是因为在两个方向的转换中没有使用相同的时区。当前的时区可以用作time_zone系统变量的值ã€�

可以åœ�TIMESTAMP列的定义中包æ‹�NULL属性以允许列包å��NULL值。例如:

CREATE TABLE t
(
  ts1 TIMESTAMP NULL DEFAULT NULL,
  ts2 TIMESTAMP NULL DEFAULT 0,
  ts3 TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP
);

如果未指å®�NULL属性,将列设置ä¸�NULL设置则会将它设置为当前的时间戳。请注意允许NULL值的TIMESTAMP列不会采用当前的时间戳,除非要么å…� 默认值定义为CURRENT_TIMESTAMP,或è€�NOW()æˆ�CURRENT_TIMESTAMP被插入到该列内。换句话说,只有使用如下定义创建,定义为 NULLçš�TIMESTAMP列才会自动更新:

CREATE TABLE t (ts NULLDEFAULT CURRENT_TIMESTAMP)�

否则-也就是说,如果使ç”�NULL而不æ˜�DEFAULT TIMESTAMP来定ä¹�TIMESTAMP列,如下所ç¤�...

CREATE TABLE t1 (ts NULL DEFAULT NULL);
CREATE TABLE t2 (ts NULL DEFAULT '0000-00-00 00:00:00');

...则必须显式插入一个对应当前日期和时间的值。例如:

INSERT INTO t1 VALUES (NOW());
INSERT INTO t2 VALUES (CURRENT_TIMESTAMP);

11.3.2. TIME类型

MySQLä»�'HH:MM:SS'格式检索和显示TIMEå€�(或对于大的小时值采ç”�'HHH:MM:SS'格式)ã€�TIME值的范围可以ä»�'-838:59:59'åˆ�'838:59:59'。小时部分会因此大的原因æ˜�TIME类型不仅可以用于表示一天的时间(必须小于24小时),还可能为某个事件过去的时间或两个事件之间的时间间隔(可以大于24小时,或者甚至为è´�)ã€�

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

·         'D HH:MM:SS.fraction'格式的字符串。还可以使用下面任何一种â€�非严æ �”语法:'HH:MM:SS.fraction'ã€�'HH:MM:SS'ã€�'HH:MM'ã€�'D HH:MM:SS'ã€�'D HH:MM'ã€�'D HH'æˆ�'SS'。这é‡�D表示日,可以å��0åˆ�34之间的值。请注意MySQL还不保存分数ã€�

·         'HHMMSS'格式的没有间割符的字符串,假定是有意义的时间。例如,'101112'被理解为'10:11:12',但'109712'是不合法çš�(它有一个没有意义的分钟部分),将变为'00:00:00'ã€�

·         HHMMSS格式的数值,假定是有意义的时间。例如,101112被理解为'10:11:12'。下面格式也可以理解ï¼�SSã€�MMSSã€�HHMMSSã€�HHMMSS.fraction。请注意MySQL还不保存分数ã€�

·         函数返回的结果,其值适合TIME上下文,例如CURRENT_TIMEã€�

对于指定为包括时间部分间割符的字符串çš�TIME值,如果时、分或者秒值小äº�10,则不需要指定两位数ã€�'8:3:2'ä¸�'08:03:02'相同ã€�

ä¸�TIME列分配简写值时应注意。没有冒号,MySQL解释值时假定最右边的两位表示秒ã€�(MySQL解释TIME值为过去的时间而不是当天的时间ï¼�ã€�例如,你可能认为'1112'å’�1112表示'11:12:00'(11点过12åˆ�),但MySQL将它们解释为'00:11:12'(11分,12 ç§�)。同样,'12'å’�12 被解释为 '00:00:12'。相反,TIME值中使用冒号则肯定被看作当天的时间。也就是说,'11:12'表示'11:12:00',而不æ˜�'00:11: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'还是不合法的值ã€�

11.3.3. YEAR类型

YEAR类型是一个单字节类型用于表示年ã€�

MySQLä»�YYYY格式检索和显示YEAR值。范围是1901åˆ�2155ã€�

可以指定各种格式çš�YEAR值:

·         四位字符串,范围ä¸�'1901'åˆ�'2155'ã€�

·         四位数字,范围为1901åˆ�2155ã€�

·         两位字符串,范围ä¸�'00'åˆ�'99'ã€�'00'åˆ�'69'å’�'70'åˆ�'99'范围的值被转换ä¸�2000åˆ�2069å’�1970åˆ�1999范围çš�YEAR值ã€�

·         两位整数,范围为1åˆ�99ã€�1åˆ�69å’�70åˆ�99范围的值被转换ä¸�2001åˆ�2069å’�1970åˆ�1999范围çš�YEAR值。请注意两位整数范围与两位字符串范围稍有不同,因为你不能直接将零指定为数字并将它解释ä¸�2000。你必须将它指定为一个字符串'0'æˆ�'00'或它被解释为0000ã€�

·         函数返回的结果,其值适合YEAR上下文,例如NOW()ã€�

非法YEAR值被转换ä¸�0000ã€�

11.3.4. Y2K事宜和日期类åž�

MySQL本身对于2000å¹�(Y2K)是安全的(参见1.4.5节,â€�2000年兼容性â€�),但输入ç»�MySQL的值可能不安全。任何包含两位年值的输入都会令人模糊,因为世纪不知道。这些值必须解释为四位形式,因ä¸�MySQL内部使用四位来保存年ã€�

对于DATETIMEã€�DATEã€�TIMESTAMPå’�YEAR类型ï¼�MySQL使用以下规则解释含模糊年值的日期ï¼�

·         00-69范围的年值转换为2000-2069ã€�

·         70-99范围的年值转换为1970-1999ã€�

请记住这些规则只是合理猜测数据值表示什么。如æž�MySQL使用的启发不能产生正确的值,你应提供包含四位年值的确切输入ã€�

ORDER BY可以正确排序有两位年çš�TIMESTAMPæˆ�YEAR值ã€�

部分函数å¦�MIN()å’�MAX()å°�TIMESTAMPæˆ�YEAR转换为一个数字。这说明使用有两位年值的值,这些函数不能工作正确。在这种情况下的修复方法是将TIMESTAMPæˆ�YEAR转换为四位年格式或使ç”�MIN(DATE_ADD(TIMESTAMP,INTERVAL 0 DAYS))ã€�

11.4. String类型

字符串类型指CHARã€�VARCHARã€�BINARYã€�VARBINARYã€�BLOBã€�TEXTã€�ENUMå’�SET。该节描述了这些类型如何工作以及如何在查询中使用这些类型ã€�

11.4.1. CHAR和VARCHAR类型

CHARå’�VARCHAR类型类似,但它们保存和检索的方式不同。它们的最大长度和是否尾部空格被保留等方面也不同。在存储或检索过程中不进行大小写转换ã€�

CHARå’�VARCHAR类型声明的长度表示你想要保存的最大字符数。例如,CHAR(30)可以占用30个字符ã€�

CHAR列的长度固定为创建表时声明的长度。长度可以为ä»�0åˆ�255的任何值。当保存CHAR值时,在它们的右边填充空格以达到指定的长度。当检索到CHAR值时,尾部的空格被删除掉。在存储或检索过程中不进行大小写转换ã€�

VARCHAR列中的值为可变长字符串。长度可以指定为0åˆ�65,535之间的值ã€�(VARCHAR的最大有效长度由最大行大小和使用的字符集确定。整体最大长度是65,532字节ï¼�ã€�

å��CHAR对比ï¼�VARCHAR值保存时只保存需要的字符数,另加一个字节来记录长度(如果列声明的长度超过255,则使用两个字节)ã€�

VARCHAR值保存时不进行填充。当值保存和检索时尾部的空格仍保留,符合标å‡�SQLã€�

如果分配ç»�CHARæˆ�VARCHAR列的值超过列的最大长度,则对值进行裁剪以使其适合。如果被裁掉的字符不是空格,则会产生一条警告。如果裁剪非空格字符,则会造成错误(而不是警å‘�)并通过使用严格SQL模式禁用值的插入。参è§�5.3.2节,“SQL服务器模式â€�ã€�

下面的表显示了将各种字符串值保存到CHAR(4)å’�VARCHAR(4)列后的结果,说明äº�CHARå’�VARCHAR之间的差别:

�

CHAR(4)

存储需æ±�

VARCHAR(4)

存储需æ±�

''

'    '

4个字èŠ�

''

1个字èŠ�

'ab'

'ab  '

4个字èŠ�

'ab '

3个字èŠ�

'abcd'

'abcd'

4个字èŠ�

'abcd'

5个字èŠ�

'abcdefgh'

'abcd'

4个字èŠ�

'abcd'

5个字èŠ�

请注意上表中最后一行的值只适用不使用严格模å¼�时;如果MySQL运行在严格模式,超过列长度不的å€�ä¸�保存,并且会出现错误ã€�

ä»�CHAR(4)å’�VARCHAR(4)列检索的值并不总是相同,因为检索时ä»�CHAR列删除了尾部的空格。通过下面的例子说明该差别ï¼�

mysql> CREATE TABLE vc (v VARCHAR(4), c CHAR(4));
Query OK, 0 rows affected (0.02 sec)
 
mysql> INSERT INTO vc VALUES ('ab  ', 'ab  ');
Query OK, 1 row affected (0.00 sec)
 
mysql> SELECT CONCAT(v, '+'), CONCAT(c, '+') FROM vc;
+----------------+----------------+
| CONCAT(v, '+') | CONCAT(c, '+') |
+----------------+----------------+
| ab  +          | ab+            |
+----------------+----------------+
1 row in set (0.00 sec)

根据分配给列的字符集校对规则å¯�CHARå’�VARCHAR列中的值进行排序和比较ã€�

请注意所æœ�MySQL校对规则属于PADSPACE类。这说明åœ�MySQL中的所æœ�CHARå’�VARCHAR值比较时不需要考虑任何尾部空格。例如:

mysql> CREATE TABLE names (myname CHAR(10), yourname VARCHAR(10));
Query OK, 0 rows affected (0.09 sec)
 
mysql> INSERT INTO names VALUES ('Monty ', 'Monty ');
Query OK, 1 row affected (0.00 sec)
 
mysql> SELECT myname = 'Monty  ', yourname = 'Monty  ' FROM names;
+--------------------+----------------------+
| myname = 'Monty  ' | yourname = 'Monty  ' |
+--------------------+----------------------+
|                  1 |                    1 |
+--------------------+----------------------+
1 row in set (0.00 sec)

请注意所æœ�MySQL版本均如此,并且它不å��SQL服务器模式的影响ã€�

对于尾部填充字符被裁剪掉或比较时将它们忽视掉的情形,如果列的索引需要唯一的值,在列内插入一个只是填充字符数不同的值将会造成复制键值错误ã€�

CHAR BYTEæ˜�CHAR BINARY的别名。这是为了保证兼容性ã€�

ASCII属性为CHAR列分é…�latin1字符集ã€�UNICODE属性分é…�ucs2字符集ã€�

11.4.2. BINARY和VARBINARY类型

BINARYå’�VARBINARY类类似于CHARå’�VARCHAR,不同的是它们包含二进制字符串而不要非二进制字符串。也就是说,它们包含字节字符串而不是字符字符串。这说明它们没有字符集,并且排序和比较基于列值字节的数值值ã€�

BINARYå’�VARBINARY允许的最大长度一样,如同CHARå’�VARCHAR,不同的æ˜�BINARYå’�VARBINARY的长度是字节长度而不是字符长度ã€�

BINARYå’�VARBINARY数据类型不同äº�CHAR BINARYå’�VARCHAR BINARY数据类型。对于后一种类型,BINARY属性不会将列视为二进制字符串列。相反,它致使使用列字符集的二元 校对规则,并且列自身包含非二进制字符字符串而不是二进制字节字符串。例å¦�CHAR(5) BINARY被视ä¸�CHAR(5) CHARACTER SET latin1 COLLATE latin1_bin,假定默认字符集æ˜�latin1。这不同äº�BINARY(5),它保存5字节二进制字符串,没有字符集æˆ� 校对规则ã€�

当保å­�BINARY值时,在它们右边填充值以达到指定长度。填充值是0x00(零字èŠ�)。插入值时在右侧添åŠ�0x00 on,并且选择时不删除尾部的字节。比较时所有字节很重要,包æ‹�ORDER BYå’�DISTINCT操作。比较时0x00字节和空格是不同的,0x00<空格ã€�

例如:对于一ä¸�BINARY(3)列,当插入时 'a' 变为 'a \0'ã€�'a\0'插入时变ä¸�'a\0\0'。当选择时两个插入的值均不更改ã€�

对于VARBINARY,插入时不填充字符,选择时不裁剪字节。比较时所有字节很重要,包æ‹�ORDER BYå’�DISTINCT操作。比较时0x00字节和空格是不同的,0x00<空格ã€�

对于尾部填充字符被裁剪掉或比较时将它们忽视掉的情形,如果列的索引需要唯一的值,在列内插入一个只是填充字符数不同的值将会造成复制键值错误ã€�

如果你计划使用这些数据类型来保存二进制数据并且需要检索的值与保存的值完全相同,应考虑前面所述的填充和裁剪特征。下面的例子说明了用0x00填充çš�BINARY值如何影响列值比较:

mysql> CREATE TABLE t (c BINARY(3));
Query OK, 0 rows affected (0.01 sec)
 
mysql> INSERT INTO t SET c = 'a';
Query OK, 1 row affected (0.01 sec)
 
mysql> SELECT HEX(c), c = 'a', c = 'a\0\0' from t;
+--------+---------+-------------+
| HEX(c) | c = 'a' | c = 'a\0\0' |
+--------+---------+-------------+
| 610000 |       0 |           1 |
+--------+---------+-------------+
1 row in set (0.09 sec)

如果检索的值必须与指定进行存储而没有填充的值相同,最好使ç”�BLOB数据类型ã€�

创建表时ï¼�MySQL可以默默更改BINARYæˆ�VARBINARY列的类型。参è§�13.1.5.1节,“沉寂的列规格变更â€�ã€�

11.4.3. BLOB和TEXT类型

BLOB是一个二进制大对象,可以容纳可变数量的数据。有4ç§�BLOB类型ï¼�TINYBLOBã€�BLOBã€�MEDIUMBLOBå’�LONGBLOB。它们只是可容纳值的最大长度不同ã€�

æœ�4ç§�TEXT类型ï¼�TINYTEXTã€�TEXTã€�MEDIUMTEXTå’�LONGTEXT。这些对åº�4ç§�BLOB类型,有相同的最大长度和存储需求ã€�

参见11.5节,“列类型存储需求â€�ã€�

BLOB 列被视为二进制字符串(字节字符ä¸�)ã€�TEXT列被视为非二进制字符ä¸�(字符字符ä¸�)ã€�BLOB列没有字符集,并且排序和比较基于列值字节的数值值ã€�TEXT列有一个字符集,并且根据字符集çš� 校对规则对值进行排序和比较ã€�

åœ�TEXTæˆ�BLOB列的存储或检索过程中,不存在大小写转捀€�

当未运行在严格模式时,如果你ä¸�BLOBæˆ�TEXT列分配一个超过该列类型的最大长度的值值,值被截取以保证适合。如果截掉的字符不是空格,将会产生一条警告。使用严æ �SQL模式,会产生错误,并且值将被拒绝而不是截取并给出警告。参è§�5.3.2节,“SQL服务器模式â€�ã€�

在大多数方面,可以将BLOB列视为能够足够大çš�VARBINARY列。同样,可以å°�TEXT列视ä¸�VARCHAR列ã€�BLOBå’�TEXT在以下几个方面不同于VARBINARYå’�VARCHARï¼�

·         当保存或检ç´�BLOBå’�TEXT列的值时不删除尾部空格ã€�(这与VARBINARYå’�VARCHAR列相同)ã€�

请注意比较时将用空格å¯�TEXT进行扩充以适合比较的对象,正如CHARå’�VARCHARã€�

·         对于BLOBå’�TEXT列的索引,必须指定索引前缀的长度。对äº�CHARå’�VARCHAR,前缀长度是可选的。参è§�7.4.3节,“列索引â€�ã€�

·         BLOBå’�TEXT列不能有 默认值ã€�

LONGå’�LONG VARCHAR对应MEDIUMTEXT数据类型。这是为了保证兼容性。如æž�TEXT列类型使ç”�BINARY属性,将为列分配列字符集的二元 校对规则ã€�

MySQL连接程序/ODBCå°�BLOB值定义为LONGVARBINARY,将TEXT值定义为LONGVARCHARã€�

由于BLOBå’�TEXT值可能会非常长,使用它们时可能遇到一些约束:

·         当排序时只使用该列的å‰�max_sort_length个字节ã€�max_sort_lengthçš� 默认值是1024;该值可以在启动mysqld服务器时使用--max_sort_length选项进行更改。参è§�5.3.3节,“服务器系统变量â€�ã€�

运行时增åŠ�max_sort_length的值可以在排序或组合时使更多的字节有意义。任何客户端可以更改其会è¯�max_sort_length变量的值:

mysql> SET max_sort_length = 2000;
mysql> SELECT id, comment FROM tbl_name
    -> ORDER BY comment;

当你想要使超è¿�max_sort_length的字节有意义,对含长值的BLOBæˆ�TEXT列使ç”�GROUP BYæˆ�ORDER BY的另一种方式是将列值转换为固定长度的对象。标准方法是使用SUBSTRING函数。例如,下面的语句对comment列的2000个字节进行排序:

mysql> SELECT id, SUBSTRING(comment,1,2000) FROM tbl_name
    -> ORDER BY SUBSTRING(comment,1,2000);

·         BLOBæˆ�TEXT对象的最大大小由其类型确定,但在客户端和服务器之间实际可以传递的最大值由可用内存数量和通信缓存区大小确定。你可以通过更改max_allowed_packet变量的值更改消息缓存区的大小,但必须同时修改服务器和客户端程序。例如,可以使用 mysqlå’�mysqldump来更改客户端çš�max_allowed_packet值。参è§�7.5.2节,“调节服务器参数â€�ã€�8.3节,“mysql:MySQL命令行工具â€�å’�8.8节,“mysqldump:数据库备份程序â€�ã€�

每个BLOBæˆ�TEXT值分别由内部分配的对象表示。这与其它列类型形成对比,后者是当打开表时为每1列分配存储引擎ã€�

11.4.4. ENUM类型

ENUM是一个字符串对象,其值来自表创建时在列规定中显式枚举的一列值ã€�

在某些情况下ï¼�ENUM值也可以为空字符ä¸�('')æˆ�NULLï¼�

·         如果你将一个非法值插å…�ENUM(也就是说,允许的值列之外的字符串),将插入空字符串以作为特殊错误值。该字符串与“普通”空字符串不同,该字符串有数值å€�0。后面有详细讨论ã€�

·         如果å°�ENUM列声明为允许NULLï¼�NULL值则为该列的一个有效值,并且 默认值为NULL。如æž�ENUM列被声明ä¸�NOT NULL,其默认值为允许的值列的第1个元素ã€�

每个枚举值有一个索引:

·         来自列规定的允许的值列中的值从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

枚举最多可以有65,535个元素ã€�

当创建表时,ENUM成员值的尾部空格将自动被删除ã€�

当检索时,保存在ENUM列的值使用列定义中所使用的大小写来显示。请注意可以ä¸�ENUM列分配字符集å’� 校对规则。对于二进制或大小写敏感的校对规则,当为列分配值时应考虑大小写ã€�

如果在数值上下文中检索一ä¸�ENUM值,将返回列值的索引。例如,你可以这样从ENUM列搜索数值值:

mysql> SELECT enum_col+0 FROM tbl_name;

如果将一个数字保存到ENUM列,数字被视为索引,并且保存的值是该索引对应的枚举成员ã€�(但是,这不适合LOAD DATA,它将所有输入视为字符串ï¼�ã€�不建议使用类似数字的枚举值来定义一ä¸�ENUM列,因为这很容易引起混淆。例如,下面的列含有字符串å€�'0'ã€�'1'å’�'2'的枚举成员,但数值索引值为1ã€�2å’�3ï¼�

numbers ENUM('0','1','2')

根据枚举成员在列定义中列出的顺序å¯�ENUM值进行排序ã€�(换句话说ï¼�ENUM值根据索引编号进行排序)ã€�例如,对äº�ENUM('a'ï¼�'b')ï¼�'a'排在'b'前面,但对于ENUM('b'ï¼�'a')ï¼�'b'排在'a'前面。空字符串排在非空字符串前面,并ä¸�NULL值排在所有其它枚举值前靀€‚要想防止意想不到的结果,按字母顺序规定ENUM列。还可以使用GROUP BY  CAST(col AS CHAR)æˆ�GROUP BY  CONCAT(col)来确保按照词汇对列进行排序而不是用索引数字ã€�

如果你想要确定一ä¸�ENUM列的所有可能的值,使用SHOW COLUMNS FROM tbl_name LIKE enum_col,并解析输出中第2列的ENUM定义ã€�

11.4.5. SET类型

SET是一个字符串对象,可以有零或多个值,其值来自表创建时规定的允许的一列值。指定包括多ä¸�SET成员çš�SET列值时各成员之间用逗号(â€�,â€�)间隔开。这æ �SET成员值本身不能包含逗号ã€�

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

''
'one'
'two'
'one,two'

SET最多可以有64个不同的成员ã€�

当创建表时,SET成员值的尾部空格将自动被删除ã€�

当检索时,保存在SET列的值使用列定义中所使用的大小写来显示。请注意可以ä¸�SET列分配字符集å’� 校对规则。对于二进制或大小写敏感的校对规则,当为列分配值时应考虑大小写ã€�

MySQL用数字保å­�SET值,所保存值的低阶位对应第1ä¸�SET成员。如果在数值上下文中检索一ä¸�SET值,检索的值的位设置对应组成列值的SET成员。例如,你可以这样从一ä¸�SET列检索数值值:

mysql> SELECT set_col+0 FROM tbl_name;

如果将一个数字保存到SET列中,数字中二进制表示中的位确定了列值中çš�SET成员。对于指定为SET('a','b','c','d')的列,成员有下面的十进制和二进制值:

SET成员

十进制å€�

二进制å€�

'a'

1

0001

'b'

2

0010

'c'

4

0100

'd'

8

1000

 

如果你为该列分配一个å€�9,其二进制形式为1001,因此第1个和ç¬�4ä¸�SET值成å‘�'a'å’�'d'被选择,结果值为 'a,d'ã€�

对于包含多个SET元素的值,当插入值时元素所列的顺序并不重要。在值中一个给定的元素列了多少次也不重要。当以后检索该值时,值中的每个元素出现一次,根据表创建时指定的顺序列出元素。例如,假定某个列指定为SET('a','b','c','d')ï¼�

mysql> CREATE TABLE myset (col SET('a', 'b', 'c', 'd'));

插入å€�'a,d'ã€�'d,a'ã€�'a,d,d'ã€�'a,d,a'å’�'d,a,d':

mysql> INSERT INTO myset (col) VALUES 
-> ('a,d'), ('d,a'), ('a,d,a'), ('a,d,d'), ('d,a,d');
Query OK, 5 rows affected (0.01 sec)
Records: 5  Duplicates: 0  Warnings: 0

当检索时所有这些值显示为 'a,d'ï¼�

mysql> SELECT col FROM myset;
+------+
| col  |
+------+
| a,d  |
| a,d  |
| a,d  |
| a,d  |
| a,d  |
+------+
5 rows in set (0.04 sec)

如果å°�SET列设置为一个不支持的值,则该值被忽略并发出警告:

mysql> INSERT INTO myset (col) VALUES ('a,d,d,s');
Query OK, 1 row affected, 1 warning (0.03 sec)
 
mysql> SHOW WARNINGS;
+---------+------+------------------------------------------+
| Level   | Code | Message                                  |
+---------+------+------------------------------------------+
| Warning | 1265 | Data truncated for column 'col' at row 1 |
+---------+------+------------------------------------------+
1 row in set (0.04 sec)
 
mysql> SELECT col FROM myset;
+------+
| col  |
+------+
| a,d  |
| a,d  |
| a,d  |
| a,d  |
| a,d  |
| a,d  |
+------+
6 rows in set (0.01 sec)

SET值按数字顺序排序ã€�NULL值排在非NULL SET值的前面ã€�

通常情况,可以使ç”�FIND_IN_SET()函数æˆ�LIKE操作符搜ç´�SET值:

mysql> SELECT * FROM tbl_name WHERE FIND_IN_SET('value',set_col)>0;
mysql> SELECT * FROM tbl_name WHERE set_col LIKE '%value%';

ç¬�1个语句找å‡�SET_col包含value set成员的行。第2个类似,但有所不同:它在其它地方找å‡�set_col包含value的行,甚至是在另一ä¸�SET成员的子字符串中ã€�

下面的语句也是合法的ï¼�

mysql> SELECT * FROM tbl_name WHERE set_col & 1;
mysql> SELECT * FROM tbl_name WHERE set_col = 'val1,val2';

ç¬�1个语句寻找包含第1ä¸�set成员的值。第2个语句寻找一个确切匹配的值。应注意ç¬�2类的比较。将set值与'val1,val2'比较返回的结果与å��'val2,val1'比较返回的结果不同。指定值时的顺序应与在列定义中所列的顺序相同ã€�

如果想要ä¸�SET列确定所有可能的值,使用SHOW COLUMNS FROM tbl_name LIKE set_col并解析输出中ç¬�2列的SET定义ã€�

11.5. 列类型存储需æ±�

根据类别列出äº�MySQL支持的每个列类型的存储需求ã€�

MyISAM表中行的最大大小为65,534字节。每ä¸�BLOBå’�TEXTåˆ� 账户只占其中çš�5è‡�9个字节ã€�

如果MyISAM表包括变长列类型,记录格式也是可变长度。当创建表时,在某些条件下,MySQL可以将一个列从变长类型改为固定长度的类型或反之亦然。详细信息参è§�13.1.5.1节,“沉寂的列规格变更â€�ã€�

数值类型存储需æ±�

列类åž�

存储需æ±�

TINYINT

1个字èŠ�

SMALLINT

2个字èŠ�

MEDIUMINT

3个字èŠ�

INT, INTEGER

4个字èŠ�

BIGINT

8个字èŠ�

FLOAT(p)

如果0 <= p <= 24ä¸�4个字èŠ�, 如果25 <= p <= 53ä¸�8个字èŠ�

FLOAT

4个字èŠ�

DOUBLE [PRECISION], item REAL

8个字èŠ�

DECIMAL(M,D), NUMERIC(M,D)

变长;参见下面的讨论

BIT(M)

大约(M+7)/8个字èŠ�

DECIMAL(å’�NUMERIC)的存储需求与具体版本有关ï¼�

使用二进制格式将9个十进制(基于10)数压缩为4个字节来表示DECIMAL列值。每个值的整数和分数部分的存储分别确定。每ä¸�9位数的倍数需è¦�4个字节,并且“剩余的”位需è¦�4个字节的一部分。下表给出了超出位数的存储需求:

剩余çš�

字节

位数

数目

0

0

1

1

2

1

3

2

4

2

5

3

6

3

7

4

8

4

9

4

日期和时间类型的存储需æ±�

列类åž�

存储需æ±�

DATE

3个字èŠ�

DATETIME

8个字èŠ�

TIMESTAMP

4个字èŠ�

TIME

3个字èŠ�

YEAR

1个字èŠ�

字符串类型的存储需æ±�

列类åž�

存储需æ±�

CHAR(M)

M个字节,0 <= M <= 255

VARCHAR(M)

L+1个字节,其中L <= M ä¸�0 <= M <= 65535(参见下面的注é‡�)

BINARY(M)

M个字节,0 <= M <= 255

VARBINARY(M)

L+1个字节,其中L <= M ä¸�0 <= M <= 255

TINYBLOB, TINYTEXT

L+1个字节,其中L < 28

BLOB, TEXT

L+2个字节,其中L < 216

MEDIUMBLOB, MEDIUMTEXT

L+3个字节,其中L < 224

LONGBLOB, LONGTEXT

L+4个字节,其中L < 232

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

1æˆ�2个字节,取决于枚举值的个数(最å¤�65,535个å€�)

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

1ã€�2ã€�3ã€�4或è€�8个字节,取决äº�set成员的数ç›�(最å¤�64个成å‘�)

VARCHARã€�BLOBå’�TEXT类是变长类型。每个类型的存储需求取决于列值的实际长度(用前面的表中çš�L表示),而不是该类型的最大可能的大小。例如,VARCHAR(10)列可以容纳最大长度为10的字符串。实际存储需求是字符ä¸�(L)的长度,加上一个记录字符串长度的字节。对于字符串'abcd'ï¼�Læ˜�4,存储需è¦�5个字节ã€�

对于CHARã€�VARCHARå’�TEXT类型,前面的表中的å€�Lå’�M应解释为字符数目,并且列定义中的这些类型的长度表示字符数目。例如,要想保存一ä¸�TINYTEXT值需è¦�L字符+ 1个字节ã€�

要想计算用于保存具体CHARã€�VARCHAR或è€�TEXT列值的字节数,需要考虑该列使用的字符集。在具体情况中,当使ç”�Unicode时,必须记住所æœ�Unicode字符使用相同的字节数。为了细分用于不同类Unicode字符使用的存储,参见10.5节,“Unicode支持â€�ã€�

注释ï¼�VARCHAR列的有效最大长度为65,532字符ã€�

NDBCLUSTER引擎只支持固定宽度的列。这说明MySQL簇中的表中的VARCHAR列的行为如同类型CHAR(不同的是每个记录仍然有一个额外字节空é—�)。例如,åœ�Cluster表中,声明为VARCHAR(100)的列中的每个记录存储时将占用101个字节,无论实际存储的记录中的字符串的长度为多少ã€�

BLOBå’�TEXT类需è¦� 1ã€�2ã€�3或è€�4个字节来记录列值的长度,取决于该类的最大可能的长度。参è§�11.4.3节,“BLOB和TEXT类型â€�ã€�

åœ�NDB Cluster存储引擎中,TEXTå’�BLOB列的实施是不同的,其ä¸�TEXT列中的每个记录由两个单独部分组成。一个是固定大小(256字节),并且实际上保存在原表中。另一个包括超å‡�256字节的任何数据,保存在隐含的表中。第2个表中的记录总是2,000字节长。这说明如果size<= 256ï¼�TEXT列的大小ä¸�256(其中size表示记录的大å°�);否则,大小æ˜�256 +size+(2000â€�(sizeâ€�256)%2000)ã€�

ENUM对象的大小由不同的枚举值的数目确定。枚举用一个字节,可以æœ�255个可能的值。当枚举的值位äº�256å’�65,535之间时,用两个字节。参è§�11.4.4节,“ENUM类型â€�ã€�

SET对象的大小由不同çš�set成员的数量确定。如æž�set大小æ˜�N,对象占(N+7)/8个字节,四舍五入åˆ�1ã€�2ã€�3ã€�4或è€�8个字节ã€�SET最多可以有64个成员。参è§�11.4.5节,“SET类型â€�ã€�

11.6. 选择正确的列类型

为了优化存储,在任何情况下均应使用最精确的类型。例如,如果列的值的范围为从1åˆ�99999,若使用整数,则MEDIUMINT UNSIGNED是好的类型。在所有可以表示该列值的类型中,该类型使用的存储最少ã€�

用精度为65位十进制æ•�(基于10)å¯�DECIMAL 列进行所有基本计ç®�(+ã€�-ã€�*ã€�/)。参è§�11.1.1节,“数值类型概述â€�ã€�

使用双精度操作对DECIMAL值进行计算。如果准确度不是太重要或如果速度为最高优先级ï¼�DOUBLE类型即足够了。为了达到高精度,可以转换到保存åœ�BIGINT中的定点类型。这样可以用64位整数进行所有计算,根据需要将结果转换回浮点值ã€�

11.7. 使用来自其他数据库引擎的列类åž�

为了使用由其它卖方编写的SQL执行代码ï¼�MySQL按照下表所示对列类型进行映射。通过这些映射,可以很容易地从其它数据库引擎将表定义导入到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

在创建表时对列类型进行映射,然后原来的类型定义被丢弃。如果你使用其它卖方的类型创建一个表,然后执è¡�DESCRIBE tbl_name语句ï¼�MySQL使用等效çš�MySQL类型来报告表的结构。例如:

mysql> CREATE TABLE t (a BOOL, b FLOAT8, c LONG, d NUMERIC);
Query OK, 0 rows affected (0.08 sec)
 
mysql> DESCRIBE t;
+-------+---------------+------+-----+---------+-------+
| Field | Type          | Null | Key | Default | Extra |
+-------+---------------+------+-----+---------+-------+
| a     | tinyint(1)    | YES  |     | NULL    |       |
| b     | double        | YES  |     | NULL    |       |
| c     | mediumtext    | YES  |     | NULL    |       |
| d     | decimal(10,0) | YES  |     | NULL    |       |
+-------+---------------+------+-----+---------+-------+
4 rows in set (0.00 sec)

这是MySQL参考手册的翻译版本,关于MySQL参考手册,请访é—�dev.mysql.comã€� 原始参考手册为英文版,与英文版参考手册相比,本翻译版可能不是最新的ã€�