您的位置:首页 > 数据库 > MySQL

【转】mysql数据类型详解

2009-03-23 11:33 549 查看
转载自:http://www.phpchina.com/html/05/32905-10136.html

MySQL支持大量的列类型,它们可以被分为3类:数字类型、日期和时间类型以及字符串(字符)类型。这个章节首先给出可用类型的概述,并且总结各类型所需的存储需求,然后提供各类型中的类型范畴更详细的描述。概述有意地简化了。更详细的说明应该参考特写列类型的附加信息,例如你能为其指定值的允许格式。

MySQL支持的列类型在下面列出。下列代码字母用于描述中:

方括号(“[”and“]”)指定可选的类型修饰部份。

注意,如果为一个列指定了
ZEROFILL
,MySQL将自动为这个列添加
UNSIGNED
属性。

警告:你应该知道当在两个整数类型值中使用减法时,如有一个为
UNSIGNED
类型,那么结果也是无符号的。查看章节6.3.5Cast函数。

TINYINT[(M)][UNSIGNED][ZEROFILL]
-128
127
。无符号的范围是
0
255
BIGINT
DOUBLE
值来完成的,因此你不应该使用大于
9223372036854775807
(63bits)的无符号大整数,除了位函数之外!如果你这样做了,结果中的某些大数字可能会出错,因为将
BIGINT
转换成
DOUBLE
时产生了舍入错误。MySQL4.0在下列情况下可以处理
BIGINT


在一个
BIGINT
列中使用整数存储一个大的无符号值。

MIN(big_int_column)
MAX(big_int_column)
中。

当两个操作数都是整数时使用操作符(
+
-
*
、等)。

BIT
BOOL
它们是
TINYINT(1)
的同义词。
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
列的一些事情:

通常你可以在一个
BIGINT
列中以字符串方式存储的一个精确的整数。在这种情况下,MySQL将执行一个字符串到数字的转换,包括无intermediate的双精度表示法。

当两个参数均是整数值时,“-”、“+”和“*”将使用
BIGINT
运算!这就意味着,如果两个大整数的乘积(或函数的结果返回整数)的结果大于
9223372036854775807
时,你可能会得到意想不到的结果。

A.5.6解决没有匹配行的问题。6.2.2.2
DATETIME
DATE
TIMESTAMP
类型。6.2.2.2
DATETIME
DATE
TIMESTAMP
类型。6.2.2Date和Time类型。参数
M
只影响一个
TIMESTAMP
列的显示格式;它的值总是占用4个字节存储。注意,当
TIMESTAMP(M)
列的
M
是8或14时,它返回的是数字而其它的
TIMESTAMP(M)
列返回的是字符串。这仅仅是为了可以可靠地转储并恢复到其它格式的表中。查看章节6.2.2.2
DATETIME
DATE
TIMESTAMP
类型。6.2.2.3
TIME
类型。6.2.2.4
YEAR
类型。6.2.3.1
CHAR
VARCHAR
类型。
FLOAT(precision)[UNSIGNED][ZEROFILL]
一个浮点型数字。
precision
可以是
<=24
作为一个单精度的浮点数字和介于25和53之间作为一个双精度的浮点数字。这些类型与下面描述的
FLOAT
DOUBLE
类型相似。
FLOAT(X)
有与相应的
FLOAT
DOUBLE
类型同样的范围,但是显示尺寸和十进制小数位数是未定义的。在MySQL3.23中,它是一个真实的浮点值。而在MySQL早期的版本中,
FLOAT(precision)
通常有2小数位。注意,由于在MySQL中所有的计算都是以双精度执行的,所以使用
FLOAT
可能带来一些意想不到的问题。查看章节
FLOAT[(M,D)][UNSIGNED][ZEROFILL]
一个小的(单精度)浮点数字。允许的值是
-3.402823466E+38
-1.175494351E-38
0
1.175494351E-38
3.402823466E+38
。如果
UNSIGNED
被指定,负值是不允许的。
M
是显示宽度,
D
是小数位数。
FLOAT
没有参数或有
X
<=24的
FLOAT(X)
代表一个单精度的浮点数字。
DOUBLE[(M,D)][UNSIGNED][ZEROFILL]
一个正常大小的(双精度)浮上数字。允许的值是
-1.7976931348623157E+308
-2.2250738585072014E-308
0
2.2250738585072014E-308
1.7976931348623157E+308
。如果
UNSIGNED
被指定,负值是不允许的。
M
是显示宽度,
D
是小数位数。
DOUBLE
没胡参数或有25<=
X
<=53的
FLOAT(X)
代表一个双精度的浮点数字。
DOUBLEPRECISION[(M,D)][UNSIGNED][ZEROFILL]
REAL[(M,D)][UNSIGNED][ZEROFILL]
它们是
DOUBLE
同义词。
DECIMAL[(M[,D])][UNSIGNED][ZEROFILL]
一个未压缩(unpacked)的浮点数。运作如同一个
CHAR
列:“unpacked”意味着数字是以一个字符串存储的,值的每一位将使用一个字符。小数点并且对于负数,“-”符号不在
M
中计算(但是它们的空间是被保留的)。如果
D
是0,值将没有小数点或小数部份。
DECIMAL
值的最大范围与
DOUBLE
一致,但是对于一个给定的
DECIMAL
列,实际的范围可以被所选择的
M
D
限制。如果
UNSIGNED
被指定,负值是不允许的。如果
D
被忽略,缺省为0。如果
M
被忽略,缺省为10。在MySQL3.23以前,
M
参数必须包含符号与小数点所需的空间。
DEC[(M[,D])][UNSIGNED][ZEROFILL]
NUMERIC[(M[,D])][UNSIGNED][ZEROFILL]
DECIMAL
的同义词。
DATE
一个日期。支持的范围是
'1000-01-01'
'9999-12-31'
。MySQL以
'YYYY-MM-DD'
格式显示
DATE
值,但是允许你以字符串或数字给一个
DATE
列赋值。查看章节
DATETIME
一个日期和时间的组合。支持的范围是
'1000-01-0100:00:00'
'9999-12-3123:59:59'
。MySQL以
'YYYY-MM-DDHH:MM:SS'
格式显示
DATETIME
值,但是允许你以字符串或数字给一个
DATETIME
列赋值。查看章节
TIMESTAMP[(M)]
一个时间戳。范围是
'1970-01-0100:00:00'
2037
年间的任意时刻。MySQL4.0和更早版本中,
TIMESTAMP
值是以
YYYYMMDDHHMMSS
YYMMDDHHMMSS
YYYYMMDD
YYMMDD
格式显示的,它取决于
M
是否是
14
(或省略)、
12
8
6
,但是允许你以字符串或数字给一个
TIMESTAMP
列赋值。从MySQL4.1开始,
TIMESTAMP
'YYYY-MM-DDHH:MM:DD'
格式作为字符返回。如果你你希望以数字形式返回则必须在该时间戳字段后加上+0。不同的时间戳长度是不支持的。从MySQL4.0.12开始,选项
--new
可以被用来使服务器与4.1一样运作。
TIMESTAMP
列有益于记录一个
INSERT
UPDATE
操作的日期和时间,因为如果你自己没有给它赋值,它将被自动地设置为最近一次操作的日期和时间。也可以通过给它赋一个
NULL
而使它设置为当前的日期和时间。查看章节
TIME
一个时间。范围是
'-838:59:59'
'838:59:59'
。MySQL以
'HH:MM:SS'
格式显示
TIME
值,但是允许你使用字符串或数字来给
TIME
列赋值。查看章节
YEAR[(2|4)]
一个2或4位数字格式的年(缺省为4位)。允许的值是
1901
2155
0000
(4位年格式)以及使用2位格式的1970-2069(70-69)。MySQL以
YYYY
格式显示
YEAR
值,但是允许你使用字符串或数字来给
YEAR
列赋值。(
YEAR
类型在MySQL3.22之前不支持。)查看章节
[NATIONAL]CHAR(M)[BINARY]
一个定长的字符串,当存储时,总是以空格填满右边到指定的长度。
M
的范围是0到255(在MySQL3.23版本之前为1到255)。当该值被检索时,尾部空格将被删除。
CHAR
值根据缺省的字符集进行忽略大小写的排索与比较,除非指定了关键词
BINARY
NATIONALCHAR
(或短形式
NCHAR
)是以ANSISQL方式定义一个
CHAR
列,它将使用缺省的字符集。这在MySQL中是默认的。
CHAR
CHARACTER
的缩写。MySQL允许以
CHAR(0)
类型建立一个列。一些老程序运行时必需一个列,却又并不使用这个列的值,你就不得不为了适应它而建立该列,在这情况下,
CHAR(0)
将是很有益的。当需要一个列仅保存两个值时:一个为
CHAR(0)
(该列没有定义为
NOTNULL
),这将仅占用一个比特位来存储2个值:
NULL
""
。查看章节
CHAR
这是
CHAR(1)
的同义词。6.5.3.1隐式的列定义变化。
VARCHAR
CHARACTERVARYING
的缩写。查看章节6.2.3.1
CHAR
VARCHAR
类型。6.5.3.1隐式的列定义变化。查看章节6.2.3.2
BLOB
TEXT
类型。6.5.3.1隐式的列定义变化。查看章节6.2.3.2
BLOB
TEXT
类型。6.5.3.1隐式的列定义变化。查看章节6.2.3.2
BLOB
TEXT
类型。6.5.3.1隐式的列定义变化。注意,由于服务器/客户端的协议以及MyISAM表通常有一个16M每通信包/表行的限制,你仍然不能使用这个类型的整个范围。查看章节6.2.3.2
BLOB
TEXT
类型。对象,这个值选自值列
'value1'
'value2'
...
NULL
或特殊的
""
出错值。一个
ENUM
列可以有最大65535不同的值。查看章节6.2.3.3
ENUM
类型。6.2.3.4
SET
类型。

MySQL支持所有的ANSI/ISOSQL92数字类型。这些类型包括准确数字的数据类型(
NUMERIC
DECIMAL
INTEGER
SMALLINT
),也包括近似数字的数据类型(
FLOAT
REAL
DOUBLEPRECISION
)。关键词
INT
INTEGER
的同义词,关键词
DEC
DECIMAL
的同义词。

NUMERIC
DECIMAL
类型被MySQL以同样的类型实现,这在SQL92标准中是允许的。他们用于保存对准确精度有重要要求的值,例如与金钱有关的数据。当以它们中的之一声明一个列时,精度和数值范围可以(通常是)被指定;例如:

salaryDECIMAL(5,2)

在这个例子中,
5
(
精度(precision)
)代表重要的十进制数字的数目,
2
(
数据范围(scale)
)代表在小数点后的数字位数。在这种情况下,因此,
salary
列可以存储的值范围是从
-99.99
99.99
。(实际上MySQL在这个列中可以存储的数值可以一直到
999.99
,因为它没有存储正数的符号)。

译者注:

M与D对DECIMAL(M,D)取值范围的影响

类型说明取值范围(MySQL<3.23)取值范围(MySQL>=3.23)
DECIMAL(4,1)-9.9到99.9-999.9到9999.9
DECIMAL(5,1)-99.9到999.9-9999.9到99999.9
DECIMAL(6,1)-999.9到9999.9-99999.9到999999.9
DECIMAL(6,2)-99.99到999.99-9999.99到99999.99
DECIMAL(6,3)-9.999到99.999-999.999到9999.999

#在MySQL3.23及以后的版本中,DECIMAL(M,D)的取值范围等于早期版本中的DECIMAL(M+2,D)的取值范围。

注释结束:

在ANSI/ISOSQL92中,句法
DECIMAL(p)
等价于
DECIMAL(p,0)
。同样的,在执行被允许决定值
p
的地方,句法
DECIMAL
等价于
DECIMAL(p,0)
。MySQL目前还不支持
DECIMAL
/
NUMERIC
数据类型的这些变体形式中的任一种。一般来说这并不是一个严重的问题,通过明确地控制精度和数值范围可以得到这些类型的主要功能益处。

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

DECIMAL
NUMERIC
值的最大范围与
DOUBLE
一致,但是对于一个给定的
DECIMAL
NUMERIC
列,它的实际范围可制定该列时的
precision
scale
限制。当这样的列被赋给了小数点的位数超过
scale
所指定的值时,该将根据
scale
进行四舍五入。当一个
DECIMAL
NUMERIC
列被赋与一个大小超过指定(或缺省)的
precision
and
scale
的限止范围时,MySQL以该列范围的端点值存储该值。

示例(译者注):
mysql>CREATETABLE`tA`(
->`id`int(4)unsignedzerofillNOTNULL,
->`salary`decimal(5,2),
->PRIMARYKEY(`id`)
->)TYPE=MyISAM;
QueryOK,0rowsaffected(0.00sec)

mysql>INSERTINTO`tA`(`id`,`salary`)
->VALUES(1,-99.99),#以数字方式插入
->(2,"99.99"),#以字符串方式插入
->(3,-999.99),
->(4,"9999.99"),
->(5,-1000.00),#decimal(5,2)最小范围为-999.99该值插入时结果为-999.99
->(6,"10000.00"),#decimal(5,2)最大范围为9999.99该值插入时结果为9999.99
->(7,"-99.999"),#小数位数超过scale指定值,但因以字符串方式插入,结果值仅截去多余部分
->(8,"99.9999"),
->(9,-99.999),#小数位数超过scale指定值,对该值进行四舍五入,结果为-100.00
->(10,99.9999);
QueryOK,10rowsaffected(0.00sec)
Records:10Duplicates:0Warnings:4

mysql>SELECT*FROM`tA`;
+------+---------+
|id|salary|
+------+---------+
|0001|-99.99|
|0002|99.99|
|0003|-999.99|
|0004|9999.99|
|0005|-999.99|
|0006|9999.99|
|0007|-99.99|
|0008|99.99|
|0009|-100.00|
|0010|100.00|
+------+---------+
10rowsinset(0.00sec)

*以上结果在MySQL4.0.12中测试

示例结束(译者注)
作为对ANSI/ISOSQL92标准的一个扩展,MySQL也支持上面的表格所列出的整型类型
TINYINT
MEDIUMINT
BIGINT
。另外一个扩展是MySQL支持随意指定一个整型数值的显示格式,这通过在类型的基本关键词后跟一个括号来实现(例如
INT(4)
)。这个可选的宽度规格说明是用于在数值显示时,对某些值的宽度短于该列宽度的值进行左填补显示的,而不是为了限制在该列中存储值的宽度,也不是为了限制那些超过该列指定宽度的值的可被显示的数字位数。当与可选的扩展属性
ZEROFILL
一起使用时,缺省填补用的空格被零代替。举例来说,一个列被定义为
INT(5)ZEROFILL
,插入的值
4
被检索出来时为
00004
。注意,如果在一个整型列中存储一个超过显示宽度的更大值时,当MySQL为某些复杂的联结(join)生成临时表时,你可能会遇到问题,因为在这种情况下,MySQL信任地认为所有的值均适合原始的列宽度。

示例(译者注):
mysql>CREATETABLE`tA`(
->`id`int(4)unsignedzerofillNOTNULL,
->PRIMARYKEY(`id`)
->)TYPE=MyISAM;
QueryOK,0rowsaffected(0.00sec)

mysql>INSERTINTO`tA`(`id`)
->VALUES(1),(12),(1234),(12345678);
QueryOK,4rowsaffected(0.01sec)
Records:4Duplicates:0Warnings:0

mysql>SELECT*FROM`tA`;
+----------+
|id|
+----------+
|0001|
|0012|
|1234|
|12345678|
+----------+
4rowsinset(0.00sec)

*以上结果在MySQL4.0.12中测试

示例结束(译者注)
所有的整型类型可以有一个可选(非标准的)属性
UNSIGNED
。如果希望在一个列中只允许正值并且需要一个稍大一点的数字范围,就可以使用无符号值。

从MySQL4.0.2开始,浮点类型也可以存在
UNSIGNED
。与整型类型一致的,这个属性可以防止在该列中存在负值。而与整型类型不一致的,该列的高部范围仍然与原范围保持一致。

FLOAT
类型被用于表示近似数字的数值类型。ANSI/ISOSQL92标准允许一个可选的精度说明(但不是指数的范围),跟在关键词
FLOAT
后的括号内。MySQL实现也支持这个可选的精度规格说明。当关键词被用于一个列的类型说明而没有精度规格说明时,MySQL使用四个字节来存储该字段值。在关键词
FLOAT
后的括号里给出两个数字,这种变形的句法也是被支持的。使用这个选项时,第一个数字继续表示值存储所占的字节数,第二个数字指定能被存储和显示的跟随在小数点后的位数(就像
DECIMAL
NUMERIC
)。当MySQL被要求为这样的一个列存储一个小数点后的小数位数超过指定值的数值时,该值将会被四舍五入,去除额外的位。

示例(译者注):
mysql>CREATETABLE`tA`(
->`id`int(4)unsignedzerofillNOTNULL,
->`float_date`float(4,2)unsignedNOTNULL,
->PRIMARYKEY(`id`)
->)TYPE=MyISAM;
QueryOK,0rowsaffected(0.00sec)

mysql>INSERTINTO`tA`(`id`,`float_date`)
->VALUES(1,-100),#插入无效的负值
->(2,100.99),#以数字方式插入
->(3,"100.99"),#以字符串方式插入
->(4,"100.99999"),#小数位数超过指定倍数,该值进行四舍五入
->(5,100.99999),
->(6,"100.9911"),
->(7,100.9911);
QueryOK,7rowsaffected(0.00sec)
Records:7Duplicates:0Warnings:1

mysql>SELECT*FROM`tA`;
+------+------------+
|id|float_date|
+------+------------+
|0001|0.00|
|0002|100.99|
|0003|100.99|
|0004|101.00|
|0005|101.00|
|0006|100.99|
|0007|100.99|
+------+------------+
7rowsinset(0.00sec)

*以上结果在MySQL4.0.12中测试

示例结束(译者注)
REAL
DOUBLEPRECISION
类型不接受精度规格说明。作为对ANSI/ISOSQL92标准的扩展,MySQL接受
DOUBLE
作为
DOUBLEPRECISION
类型的一个同义词。标准要求
REAL
的精度比用于
DOUBLEPRECISION
的更小,而与之相反的,MySQL以8字节的双精度浮点值(当不以“ANSI模式”运行时)来实现两者。为了得到最大的可移植性,近似数字的数值存储所需代码应该使用没有精度或小数位数规格说明的
FLOAT
DOUBLEPRECISION
类型。

当试图在一个数字列中存储一个超过该列允许范围的值时,MySQL会剪切该值到范围内的适当端点值,并以结果值代替存储。

举例来说,一个整型列的范围是
-2147483648
2147483647
。如果试图在一个
INT
列中插入值
-9999999999
,该值将会被剪切到该范围的低部端点,以
-2147483648
代替存储。同样的,如果试图插入
9999999999
2147483647
将被代替存储。

如果
INT
列是
UNSIGNED
的,列的范围大小是一致的,不过它的端点移动到了
0
4294967295
。如果你试图存储
-9999999999
9999999999
,而实际列中存储的值将会变成
0
4294967296


对于
ALTERTABLE
LOADDATAINFILE
UPDATE
和多行
INSERT
语句,由于剪切发生的转换,将以“Warnings”被报告。

类型占用字节
TINYINT
1-128127
SMALLINT
2-3276832767
MEDIUMINT
3-83886088388607
INT
4-21474836482147483647
BIGINT
8-92233720368547758089223372036854775807

日期和时间类型有
DATETIME
DATE
TIMESTAMP
TIME
YEAR
。每一个类型均有合法值的范围,当给它们赋于一个真正不合法的值时,这些值将会被“零”代替。注意,MySQL允许存储某个“不严格地”合法的日期,例如
1999-11-31
。这样做的原因是,我们认为应用程序有责任来处理日期合法性的检查,而不是由SQL服务器来处理。为了“加快”对日期的检查,MySQL仅检查月份应在0-12范围内,以及天在0-31范围内。因为上面所述的范围定义方式,MySQL因而允许你在一个
DATE
DATETIME
列中存储日或月日均为0的日期。当一个应用程序希望存储一个出生日期,而你并不知准确的出生日月时,这将变得非常有用。在这种情况下,你可以简单地以
1999-00-00
1999-01-00
形式存储日期。(当然你不能期望
DATE_SUB()
DATE_ADD
之类的函数能正确地处理这样的日期,并得到正确的值。)

当使用日期和时间类型工作时,这里有一些要记住的总则:

MySQL对一个给定的日期或时间类型以标准的格式进行检索,但是它会努力以各种格式匹配解释你所提供的(例如,当你指定一个值,将其赋给一个日期或时间类型或与之比较时)。然而,只在下面部分所描述的格式是被支持的。期望你能够提供合法的值,如果你使用其它格式的值,可能会造成无法预料的结果。

尽管MySQL会尝试以各种格式解释值,它通常期望日期的年部分放在最左边。日期必须以年-月-日次序给出(例如,
'98-09-04'
),而不是其它地方常用的月-日-年或日-月-年次序(例如,
'09-04-98'
'04-09-98'
)。

如果一个值被用于在数字的语境中,MySQL将自动地将一个日期或时间类型值转换成数字,反之亦然。

当MySQL遇到一个日期或时间类型的值超出范围或对该类型是一个不合法的值时(查看这个章节的开头部分),它会将该类型的值变换到“零”值。(例外的是超出范围的
TIME
值将被剪切为适当的
TIME
范围端点值。)下表每种类型的“零”值格式:
列类型“零”值
DATETIME
'0000-00-0000:00:00'
DATE
'0000-00-00'
TIMESTAMP
00000000000000
(长度取决于显示格式)
TIME
'00:00:00'
YEAR
0000
“零”值是特殊的,但是你可以以表中显示的值来明确地存储或引用他们。你也可以使用值
'0'
0
,这更易于书写。

MyODBC
2.50.12和以上的版本中,“零”值的日期和时间值通过
MyODBC
将被自动转换成
NULL
,因为ODBC不能够处理这样的值。

MySQL自身是Y2K安全的(查看章节1.2.52000年兼容性),但是呈交给MySQL的值可能并不是。任何一个包含2位年份的值是存在二义性的,因为世纪值是未知的。这样的值必须被解释为4位格式,因为MySQL内部使用四位存储年份。

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

在范围
00-69
内的年值被转换为
2000-2069


在范围Y
70-99
内的年值被转换为
1970-1999


记住,这些规则仅仅提供对于你的数据含义的合理猜测。如果MySQL使用的探索法无法得到正确的值,你应该以包含4位年份的格式提供一个明确的值。

ORDERBY
将以适当的顺序对2位
YEAR/DATE/DATETIME
类型排序。

注意,某些像
MIN()
MAX()
之类的函数会将
TIMESTAMP/DATE
转换为一个数字。这就意味着,一个2位年份的时间戳将完全不能与这些函数一同工作。在这种情况下,解决的办法是将
TIMESTAMP/DATE
转换为4位年份格式或者使用诸如
MIN(DATE_ADD(timestamp,INTERVAL0DAYS))的方法


DATETIME
DATE
TIMESTAMP
类型

DATETIME
DATE
TIMESTAMP
类型是相似的。这个章节描述了它们的特性以及它们的相似点与不同点。

DATETIME
类型可用于需要同时包含日期和时间信息的值。MySQL以
'YYYY-MM-DDHH:MM:SS'
格式检索与显示
DATETIME
类型。支持的范围是
'1000-01-0100:00:00'
'9999-12-3123:59:59'
。(“支持”的含义是,尽管更早的值可能工作,但不能保证他们均可以。)

DATE
类型可用于需要一个日期值而不需要时间部分时。MySQL以
'YYYY-MM-DD'
格式检索与显示
DATE
值。支持的范围是
'1000-01-01'
'9999-12-31'


TIMESTAMP
列类型提供了一种类型,通过它你可以以当前操作的日期和时间自动地标记
INSERT
UPDATE
操作。如果一张表中有多个
TIMESTAMP
列,只有第一个被自动更新。

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

列值没有明确地在一个
INSERT
LOADDATAINFILE
语句中被指定。

列值没有明确地在一个
UPDATE
语句中被指定,并且其它的一些列值已发生改变。(注意,当一个
UPDATE
设置一个列值为它原有值时,这将不会引起
TIMESTAMP
列的更新,因为,如果你设置一个列值为它当前值时,MySQL为了效率为忽略更新。)

明确地以
NULL
设置
TIMESTAMP
列。

第一个列以外其它
TIMESTAMP
列,可以设置到当前的日期和时间,只要将该列赋值
NULL
NOW()


任何
TIMESTAMP
列均可以被设置一个不同于当前操作日期与时间的值,这通过为该列明确指定一个你所期望的值来实现。这也适用于第一个
TIMESTAMP
列。这个选择性是很有用的,举例来说,当你希望
TIMESTAMP
列保存该记录行被新添加时的当前的日期和时间,但该值不再发生改变,无论以后是否对该记录行进行过更新:

当该记录行被建立时,让MySQL设置该列值。这将初始化该列为当前日期和时间。

以后当你对该记录行的其它列执行更新时,为
TIMESTAMP
列值明确地指定为它原来的值。

另一方面,你可能发现更容易的方法,使用
DATETIME
列,当新建记录行时以
NOW()
初始化该列,以后在对该记录行进行更新时不再处理它。

示例(译者注):

mysql>CREATETABLE`tA`(
->`id`int(3)unsignedNOTNULLauto_increment,
->`date1`timestamp(14)NOTNULL,
->`date2`timestamp(14)NOTNULL,
->PRIMARYKEY(`id`)
->)TYPE=MyISAM;
QueryOK,0rowsaffected(0.01sec)

mysql>INSERTINTO`tA`SET`id`=1;
QueryOK,1rowaffected(0.02sec)

#没有明确地指定第一个timestamp列值,该列值被设为插入的当前时刻
#没有明确地指定其它的timestamp列值,MySQL则认为插入的是一个非法值,而该列值被设为0

mysql>INSERTINTO`tA`VALUES(2,NOW(),NULL);
QueryOK,1rowaffected(0.01sec)

mysql>SELECT*FROM`tA`;
+----+----------------+----------------+
|id|date1|date2|
+----+----------------+----------------+
|1|20030503104118|00000000000000|
|2|20030503104254|20030503104254|
+----+----------------+----------------+
2rowsinset(0.00sec)

mysql>UPDATE`tA`SET`id`=3WHERE`id`=1;
QueryOK,1rowaffected(0.01sec)
Rowsmatched:1Changed:1Warnings:0

#对某一记录行进行了更新,第一个timestamp列值也将被更新

mysql>UPDATE`tA`SET`id`=2WHERE`id`=2;
QueryOK,0rowsaffected(0.00sec)
Rowsmatched:1Changed:0Warnings:0

#MySQL忽略了这次操作,第一个timestamp列值不会被更新

mysql>SELECT*FROM`tA`;
+----+----------------+----------------+
|id|date1|date2|
+----+----------------+----------------+
|3|20030503104538|00000000000000|
|2|20030503104254|20030503104254|
+----+----------------+----------------+
2rowsinset(0.00sec)

mysql>UPDATE`tA`SET`id`=1,`date1`=`date1`WHERE`id`=3;
QueryOK,1rowaffected(0.00sec)
Rowsmatched:1Changed:1Warnings:0

#明确地指定了第一个timestamp列值为它原有值,该值将不会被更新

mysql>SELECT*FROM`tA`;
+----+----------------+----------------+
|id|date1|date2|
+----+----------------+----------------+
|1|20030503104538|00000000000000|
|2|20030503104254|20030503104254|
+----+----------------+----------------+
2rowsinset(0.00sec)

*以上结果在MySQL4.0.12中测试

示例结束(译者注)

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范围内的奇数会被强制为下一个更大的偶数。

例如(译者注):
字段定义强制字段长度
TIMESTAMP(0)TIMESTAMP(14)
TIMESTAMP(15)TIMESTAMP(14)
TIMESTAMP(1)TIMESTAMP(2)
TIMESTAMP(5)TIMESTAMP(6)
注意:从MySQL4.1开始,
TIMESTAMP
'YYYY-MM-DDHH:MM:DD'
格式作为字符串返回。不同的时间戳长度不再被支持。

译者注:如果你你希望在MySQL4.1中以数字形式返回时间戳,则必须在该时间戳字段后加上+0。从MySQL4.0.12开始,选项--new可以被用来使服务器与4.1一样运作。

你可以使用常用的格式集中的任何一个指定
DATETIME
DATE
TIMESTAMP
值:

一个
'YYYY-MM-DDHH:MM:SS'
'YY-MM-DDHH:MM:SS'
格式的字符串。一个“宽松”的语法是被允许的:以任何标点符号作为日期部分和时间部分中的定界符。例如,
'98-12-3111:30:45'
'98.12.311+30+45'
'98/12/3111*30*45'
'98@12@3111^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-2309:15:28'
,但是
'971122129015'
却是违法的(它的分部分是无意义的),该值被插入时将变成
'0000-00-0000:00:00'


一个无定界符的
'YYYYMMDD'
'YYMMDD'
格式的字符串,只要字符串看起来像是一个日期。例如,
'19970523'
'970523'
被解释成为
'1997-05-23'
,但是
'971332'
却是违法的(它的月和日部分是无意义的),该值被插入时将变成
'0000-00-00'


一个
YYYYMMDDHHMMSS
YYMMDDHHMMSS
格式的数字,只要数字看起来像是一个日期。例如,
19830905132800
830905132800
被解释成为
'1983-09-0513:28:00'


一个
YYYYMMDD
YYMMDD
格式的数字,只要数字看起来像是一个日期。例如,
19830905
830905
被解释成为
'1983-09-05'


在一个
DATETIME
DATE
TIMESTAMP
语境中,一个函数的返回值将随之而变化,例如
NOW()
CURRENT_DATE


非法的
DATETIME
DATE
TIMESTAMP
值将会被转换到适当形式的“零”值(
'0000-00-0000:00:00'
'0000-00-00'
00000000000000
)。

对于以字符串格式指定的包含日期定界符的值,不必要为小于
10
的月或天的值指定2位数字。
'1979-6-9'
等同于
'1979-06-09'
。同样的,对于以字符串指定的包含时间定界符的值,不必要为小于
10
的时、分或秒指定2位数字。
'1979-10-301:2:3'
等同于
'1979-10-3001:02:03'


以数字指定的值应该是6、8、12或14位长。如果数字是8或14位长的,该值将被假定为年份是由头4位数字给出的
YYYYMMDD
YYYYMMDDHHMMSS
格式。如果数字是6或12数字长,它将被假定为年份是由头2位数字给出的
YYMMDD
YYMMDDHHMMSS
格式。不是这些长度之一的数字通过在值前补零到最接近的长度后解释。

'9903'
,你可能认为它代表1999年3月,但你将会发现MySQL会将一个“零”值插入到你的表中。这是因为,年份和月份分别为
99
03
,但是日期部分丢失(为0),因此这个值是不合法的。

TIMESTAMP
列总是以完全精度存储给定的合法值,而不考虑显示尺寸的大小。这包含几个含义:

赋值时总是给出年、月和日,即使你的列类型定义为
TIMESTAMP(4)
TIMESTAMP(2)
。否则,该值将是不合法的,而被
0
代替存储。
示例(译者注):

mysql>CREATETABLE`tA`(
->`id`int(3)unsignedNOTNULLauto_increment,
->`date1`timestamp(4)NOTNULL,
->PRIMARYKEY(`id`)
->)TYPE=MyISAM;
QueryOK,0rowsaffected(0.01sec)

mysql>INSERTINTO`tA`(`id`,`date1`)
->VALUES(1,NULL),#插入当前日期和时间
->(2,0305),#以数字格式给出值,而值长度小于6,在最左边补0至6位数字
->(3,'0305');#以字符串格式给出值,而值长不包括年、月和日,因而是一个非法值
QueryOK,3rowsaffected(0.01sec)
Records:3Duplicates:0Warnings:1

mysql>SELECT*FROM`tA`;
+----+-------+
|id|date1|
+----+-------+
|1|0305|
|2|0003|
|3|0000|
+----+-------+
3rowsinset(0.00sec)

*以上结果在MySQL4.0.12中测试

示例结束(译者注)

如果以
ALTERTABLE
拓展一个
TIMESTAMP
窄列,以前被“隐蔽”的信息将被显示出来。
示例(译者注):

*接上例结果

mysql>ALTERTABLE`ta`CHANGE`date1``date1`TIMESTAMP(11);
QueryOK,3rowsaffected(0.01sec)
Records:3Duplicates:0Warnings:0

#设置`date1`为TIMESTAMP(11),MySQL会自动将其转化为TIMESTAMP(11)

mysql>SELECT*FROM`tA`;
+----+--------------+
|id|date1|
+----+--------------+
|1|030503150142|
|2|000305000000|
|3|000000000000|
+----+--------------+
3rowsinset(0.00sec)

*以上结果在MySQL4.0.12中测试

示例结束(译者注):

同样的,缩小一个
TIMESTAMP
列的宽度不会引起信息的丢失,除了在感觉上值在被显示时显示了较少的信息。

尽管
TIMESTAMP
列值是以全部精度存储的,但是
UNIX_TIMESTAMP()
是唯一能直接操作内部存储值的函数。其它的函数操作的是格式化后的检索的值。这就意味着不能够使用诸如
HOUR()
SECOND()
之类的函数,除非相关部分存在于格式化后的
TIMESTAMP
值中。例如,在小于10的显示格式上,为了使
TIMESTAMP
列中的
HH
部分能够显示,显示格式的尺寸必须不小于10,因此在一个更短的
TIMESTAMP
列值上使用
HOUR()
将会产生一个无意义的结果。
示例(译者注):

*接上例结果
#下列示例结果与上述结果相悖
mysql>ALTERTABLE`ta`CHANGE`date1``date1`TIMESTAMP(4);
QueryOK,3rowsaffected(0.02sec)
Records:3Duplicates:0Warnings:0

mysql>SELECT*FROM`tA`;
+----+-------+
|id|date1|
+----+-------+
|1|0305|
|2|0003|
|3|0000|
+----+-------+
3rowsinset(0.01sec)

mysql>SELECTHOUR(`date1`)FROM`tA`;
+---------------+
|Hour(`date1`)|
+---------------+
|15|
|0|
|NULL|
+---------------+
3rowsinset(0.02sec)

mysql>SELECTSECOND(`date1`)FROM`tA`;
+-----------------+
|second(`date1`)|
+-----------------+
|42|
|0|
|NULL|
+-----------------+
3rowsinset(0.01sec)

*以上结果在MySQL4.0.12中测试

示例结束(译者注):

在某种程序上,你可以将一个日期值赋给另一种日期类型的对象。然而,这可能会使值产生改变或丢失一部分信息。

如果将一个
DATE
值赋给一个
DATETIME
TIMESTAMP
对象,结果值的时间部分将被设为
'00:00:00'
,因为
DATE
值不包含时间信息。

如果将一个
DATETIME
TIMESTAMP
值赋给一个
DATE
对象,结果值的时间部分被删除,因为
DATE
类型不能存储时间信息。

记住,尽管
DATETIME
DATE
TIMESTAMP
值全都可以用同样的格式集来指定,但所有类型不都有同有同样的值范围。例如,
TIMESTAMP
值不能早于
1970
或晚于
2037
。这就意味着,一个日期例如
'1968-01-01'
,作为一个
DATETIME
DATE
值是合法的,但不是一个有效的
TIMESTAMP
值,当它被赋于一个这样的对象时,它将被转换为
0


你可能会被以字符串指定值时所允许的宽松格式欺骗。例如,一个值如
'10:11:12'
的,因为分界符“:”可能看起来像是一个时间值,但是当它被用于一个日期语境中时,它将被解释成为
'2010-11-12'
年。而值
'10:45:15'
将被转换成
'0000-00-00'
,因为
'45'
是一个不合法的月份。

MySQL服务器仅对日期的有效性执行基本的检验:天为
00-31
,月为
00-12
,年为
1000-9999
。任何不是这个范围内的日期将被转换为
0000-00-00
。请注意,这仍然允许你存储一个无效的日期例如
2002-04-31
。它允许一个WEB应用程序不进行进一步的检查而存储一个表单中的数据。为了确保一个日期值的有效性,在你的应用程序里执行有效性检查。

以两位数字指定年份是存在二义性的,因为世纪是未知的。MySQL以下面的规则解释一个2位年份值:

00-69
范围的年份值被转换为
2000-2069


70-99
范围的年份值被转换为
1970-1999


TIME
类型

MySQL以
'HH:MM:SS'
格式(或对大的小时值时使用
'HHH:MM:SS'
格式)检索和显示
TIME
值。


[NATIONAL]VARCHAR(M)[BINARY]
一个变长的字符串。注意:尾部的空格在存储时将会被删除(这与ANSISQL约规不同)。
M
的范围是0到255(在MySQL4.0.2之前的版本中是1到255)。
VARCHAR
值以大小写忽略方式进行排索与比较,除非关键词
BINARY
被指定。查看章节
TINYBLOB
TINYTEXT
一个
BLOB
TEXT
列,最大长度为255(2^8-1)个字符。查看章节
BLOB
TEXT
一个
BLOB
TEXT
列,最大长度为65535(2^16-1)个字符。查看章节
MEDIUMBLOB
MEDIUMTEXT
一个
BLOB
TEXT
列,最大长度为16777215(2^24-1)个字符。查看章节
LONGBLOB
LONGTEXT
一个
BLOB
TEXT
列,最大长度为4294967295(2^32-1)个字符。查看章节
ENUM('value1','value2',...)
一个枚举类型。一个仅能有一个值的字符串
SET('value1','value2',...)
一个集合。一个能有零个或更多个值的字符串对象,其中每个值必须选自值列
'value1'
'value2'
...
。一个
SET
列可以有最大64个成员。查看章节
M
指出最大的显示尺寸。最大的显示尺寸长度为255。
D
适用于浮点类型。指出跟随在十进制小数点后的数字数量。最大可能值为30,但不应大于
M
-2。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: