个人MYSQL学习心得(四) 数据类型

MYSQL里的BLOB数据类型html

BLOB是一个二进制大对象,用来存储可变数量的数据。BLOB类型分为4种:TinyBlob、Blob、MediumBlob、LongBlob,mysql

这几个类型之间的惟一区别是在存储文件的最大大小上不一样。web

 

MySQL的四种BLOB类型     类型 大小(单位:字节)算法

TinyBlob                            最大 255
Blob                                  最大 65K
MediumBlob                       最大 16M
LongBlob                           最大 4Gsql

 

BLOB列存储的是二进制字符串(字节字符串);TEXT列存储的是非二进制字符串(字符字符串)。数据库

BLOB列没有字符集,而且排序和比较基于列值字节的数值;TEXT列有一个字符集,而且根据字符集对值进行排序和比较缓存

 

BLOB是二进制字符串,TEXT是非二进制字符串,二者都可存放大容量的信息。BLOB主要存储图片、音频信息等安全

而TEXT只能存储文本文件。服务器


SQLSERVER并发

SQLSERVER并无BLOB数据类型,只有大型对象数据类型(BLOB):

text,ntext,image,nvarchar(max),varchar(max),varbinary(max)和xml数据类型

这些数据类型的数据都存放在LOB类型的数据页面里

 

若有不对的地方,欢迎你们拍砖o(∩_∩)o 

 

其余类型

第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-3八、0和1.175494351E-38到3.402823466E+38。这些是理论限制,基于IEEE标准。实际的范围根据硬件或操做系统的不一样可能稍微小些。

M是小数纵位数,D是小数点后面的位数。若是MD被省略,根据硬件容许的限制来保存值。单精度浮点数精确到大约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是小数点后面的位数。若是MD被省略,根据硬件容许的限制来保存值。双精度浮点数精确到大约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,数据类型变为没有MD值的FLOAT。若是p为从25到53,数据类型变为没有MD值的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>
ERROR 1074 (42000): Column length too big for column 'col' (max = 255); use BLOB or TEXT instead
mysql>
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'相同。

数字值应为六、八、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到999九、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>

客户端能够按照下面方法让服务器为它的链接以MAXDB模式运行:

mysql>

 

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>
Query OK, 0 rows affected (0.02 sec)
 
mysql>
Query OK, 1 row affected (0.00 sec)
 
mysql>
+----------------+----------------+
| CONCAT(v, '+') | CONCAT(c, '+') |
+----------------+----------------+
| ab  +          | ab+            |
+----------------+----------------+
1 row in set (0.00 sec)

根据分配给列的字符集校对规则对CHAR和VARCHAR列中的值进行排序和比较。

请注意全部MySQL校对规则属于PADSPACE类。这说明在MySQL中的全部CHAR和VARCHAR值比较时不须要考虑任何尾部空格。例如:

mysql>
Query OK, 0 rows affected (0.09 sec)
 
mysql>
Query OK, 1 row affected (0.00 sec)
 
mysql>
+--------------------+----------------------+
| 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>
Query OK, 0 rows affected (0.01 sec)
 
mysql>
Query OK, 1 row affected (0.01 sec)
 
mysql>
+--------+---------+-------------+
| 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>
mysql>
    ->

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

mysql>
    ->

·         BLOB或TEXT对象的最大大小由其类型肯定,但在客户端和服务器之间实际能够传递的最大值由可用内存数量和通讯缓存区大小肯定。你能够经过更改max_allowed_packet变量的值更改消息缓存区的大小,但必须同时修改服务器和客户端程序。例如,可使用 mysqlmysqldump来更改客户端的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>

·         NULL值的索引是NULL。

例如,定义为ENUM的列('one','two','three')能够有下面所示任何值。还显示了每一个值的索引:

索引

NULL

NULL

''

0

'one'

1

'two'

2

'three'

3

枚举最多能够有65,535个元素。

当建立表时,ENUM成员值的尾部空格将自动被删除。

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

若是在数值上下文中检索一个ENUM值,将返回列值的索引。例如,你能够这样从ENUM列搜索数值值:

mysql>

若是将一个数字保存到ENUM列,数字被视为索引,而且保存的值是该索引对应的枚举成员。(可是,这不适合LOAD DATA,它将全部输入视为字符串)。不建议使用相似数字的枚举值来定义一个ENUM列,由于这很容易引发混淆。例如,下面的列含有字符串值'0'、'1'和'2'的枚举成员,但数值索引值为一、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>

若是将一个数字保存到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>

插入值'a,d'、'd,a'、'a,d,d'、'a,d,a'和'd,a,d':

mysql>
-> ('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>
+------+
| col  |
+------+
| a,d  |
| a,d  |
| a,d  |
| a,d  |
| a,d  |
+------+
5 rows in set (0.04 sec)

若是将SET列设置为一个不支持的值,则该值被忽略并发出警告:

mysql>
Query OK, 1 row affected, 1 warning (0.03 sec)
 
mysql>
+---------+------+------------------------------------------+
| Level   | Code | Message                                  |
+---------+------+------------------------------------------+
| Warning | 1265 | Data truncated for column 'col' at row 1 |
+---------+------+------------------------------------------+
1 row in set (0.04 sec)
 
mysql>
+------+
| 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>
mysql>

第1个语句找出SET_col包含value set成员的行。第2个相似,但有所不一样:它在其它地方找出set_col包含value的行,甚至是在另外一个SET成员的子字符串中。

下面的语句也是合法的:

mysql>
mysql>

第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 <= 且0 <= M <= 65535(参见下面的注释)

BINARY(M)

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

VARBINARY(M)

L+1个字节,其中L <= 且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',...)

一、二、三、4或者8个字节,取决于set成员的数目(最多64个成员)

VARCHAR、BLOB和TEXT类是变长类型。每一个类型的存储需求取决于列值的实际长度(用前面的表中的L表示),而不是该类型的最大可能的大小。例如,VARCHAR(10)列能够容纳最大长度为10的字符串。实际存储需求是字符串(L)的长度,加上一个记录字符串长度的字节。对于字符串'abcd',L是4,存储须要5个字节。

对于CHAR、VARCHAR和TEXT类型,前面的表中的值LM应解释为字符数目,而且列定义中的这些类型的长度表示字符数目。例如,要想保存一个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类须要 一、二、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个字节,四舍五入到一、二、三、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>
Query OK, 0 rows affected (0.08 sec)
 
mysql>
+-------+---------------+------+-----+---------+-------+
| 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    |       |
+-------+---------------+------+-----+---------+-------+
相关文章
相关标签/搜索