第11章:列类型
目录
11.1. 列类型概述
11.1.1. 数值类型概述
11.1.2. 日期和时间类型概述
11.1.3. 字符串类型概述
11.2. 数值类型
11.3. 日期和时间类型
11.3.1. DATETIME、DATE和TIMESTAMP类型
11.3.2. TIME类型
11.3.3. YEAR类型
11.3.4. Y2K事宜和日期类型
11.4. String类型
11.4.1. CHAR和VARCHAR类型
11.4.2. BINARY和VARBINARY类型
11.4.3. BLOB和TEXT类型
11.4.4. ENUM类型
11.4.5. SET类型
11.5. 列类型存储需求
11.6. 选择正确的列类型
11.7. 使用来自其余数据库引擎的列类型
MySQL支持多种列类型:数值类型、日期/时间类型和字符串(字符)类型。本章首先对这些列类型进行了概述,而后更加详细地描述了各类列的类型,以及列类型存储需求的总结。概述很简单。关于具体列类型的详细信息应查阅详细的描述,例如指定值时容许使用的格式。
MySQL支持处理空间数据的扩展名。关于空间类型的信息参见第19章:MySQL中的空间扩展。
几种列类型描述使用了下述惯例:
· M
表示最大显示宽度。最大有效显示宽度是255。
· D
适用于浮点和定点类型,并表示小数点后面的位数。最大可能的值是30,但不该大于M-2。
· 方括号(‘[’和‘]’)表示可选部分。
11.1. 列类型概述
11.1.1. 数值类型概述
11.1.2. 日期和时间类型概述
11.1.3. 字符串类型概述
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-3八、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-30八、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. 日期和时间类型
11.3.1. DATETIME、DATE和TIMESTAMP类型
11.3.2. TIME类型
11.3.3. YEAR类型
11.3.4. Y2K事宜和日期类型
表示时间值的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不能处理此类值。