4.1MySQL数据类型
数据类型是数据的一种属性,其可以决定数据的存储格式、有效范围和相应的限制。 MySQL的数据类型包括整数类型、浮点数类型、定点数类型、日期和时间类型、字符串 类型和二进制数据类型。在本章中将讲解的内容包括:
整数类型、浮点数类型和定点数类型;
日期与时间类型;
字符串类型;
进制类型;
如何选择数据类型。
通过本章的学习,读者可以了解各种数据类型的含义、特点、使用范围和存储方式。 同时,读者可以了解如何选择合适的数据类型。
4.1 MySQL数据类型介绍
MySQL数据库提供了多种数据类型。其中包括整数类型、浮点数类型、定点数类型、 日期和时间类型、字符串类型和二进制数据类型。不同的数据类型有各自的特点,使用范 围不相同。而且,存储方式也不一样。本节将详细讲解各种数据类型。
4.1.1整数类型
整数类型是数据库中最基本的数据类型。标准SQL中支持INTEGER和SMALLINT 这两类整数类型。MySQL数据库除了支持这两种类型以外,还扩展支持了 TmYmT、 MEDIUM^T和BIGINT。本小节将讲解各种整数类型的取值范围、存储的字节数、特点 等内容。下面从不同整数类型的字节数、取值范围等方面进行对比,如表所示。
整数类型 | 字节数 | 无符合数的取值范围 | 有符合数的取值范围 |
---|---|---|---|
TINYINT | 1 | 0~255 | -128~127 |
SMALLINT | 2 | 0~65535 | -32768~32767 |
MEDIUMINT | 3 | 0~16777215 | -8388608~8388607 |
INT | 4 | 0~4294967295 | -2147483648~2147483647 |
INTEGER | 4 | 0~4294967295 | -2147483648~2147483647 |
BIGINT | 8 | 0~18446744073709551615 | -9223372036854775808~9223372036854775807 |
从表中可以看到,INT类型和INTEGER类型的字节数和取值范围都是一样的。其实,在MySQL中INT类型和取TEGER类型是一样的。TINYINT类型占用的字节最小,只需要1个字节。因此,其取值范围是最小的。BIGINT类型占用的字节最大,需要8个字节。因此,其取值范围是最大的。
不同类型的整数类型的字节数不同。根据类型所占的字节数可以算出该类型的取值范围。例如,TINYINT的空间为1个字节,1个字节是8位。那么,TINYINT无符号数的最大值为28-1,即为255。TINYINT有符号数的最大值为27-1,即为127。同理可以算出其他不同整数类型的取值范围。
MySQL支持数据类型的名称后面指定该类型的显示宽度。其基本形式如下:
数据类型(显示宽度)
其中,数据类型参数是整数数据类型的名称;显示宽度参数是指定宽度的数值。显示 宽度是指能够显示的最大数据的长度。例如,以T(4)就是指定INT类型的显示宽度为4。 在不指定宽度的情况下,每个整数类型都有默认的显示宽度。 【示例】下面某表的字段a、b、 c、d和e的数据类型分别为TINYINT、SMALLINT、 MEDIUMINT、INT和BIGINT。这些整数类型都没有设置显示宽度,都为其默认值。该表 的数据类型显示如下:
+----------+------------+ | Field | Type | +----------+------------+ | a |tinyint(4) | | b |smallint(6) | | c |mediumint(9)| | d |int(11) | | e |bigint(20) | +----------+------------+
从上面结果可以看出各种整数类型的默认显示宽度。TINYINT类型的默认显示宽度为 4;SMALLINT类型的默认显示宽度为6;MEDIUMINT类型的默认显示宽度为9;INT类型的默认显示宽度为11; BIGINT类型的默认显示宽度为20。仔细观察会发现,TINYINT类型的默认显示宽度与其有符号数的最小值的显示宽度相同。因为此处负号是占一个位置的。依此类推,其他整数类型的默认显示宽度与其有符号数的最大值的显示宽度相同。这个可以理解为,一个数据类型的默认显示宽度刚好能显示该数据类型的所有值。
在整数类型使用时,还可以搭配使用zerofill参数。zerofill参数表示数字不足的显示空间由0来填补。值得注意的是,使用zerofill参数时,MySQL会自动加上UNSIGNED 属性。那么,该整数类型只能表示无符号数,其显示宽度比默认宽度小1。如果査询表中 使用了 zerofill参数,表的值将显示为:
+-----+-------+----------+------------------+ | 001 | 00001 | 00000001 | 0000000000000001 | +-----+-------+----------+------------------+
从上面显示结果可以看出,未达到显示宽度的位置由0来补全了。而且,显示宽度都不默认显示宽度小1。虽然上面提到可以设置显示宽度,但依然可以插入大于显示宽度的值。【示例】下面某表的字段a和b分别为取INT(4)和INT,向表中插入111111和 22222222。其显示结果如下:
+--------+----------+ | 111111 | 22222222 | +--------+----------+
结果显示,a字段中仍然可以显示111111。这说明,当插入数据的显示宽度大于设置 的显示宽度时,数据依然可以插入。而且,可以完整的显示出来,设置的显示宽度在显示该记录时失效。
注意:数据的宽度不能大于默认宽度。如果大于默认宽度,那该数据已经超过了该类型的最大值。因为最大值的宽度必须是小于等于默认宽度。如果一个值大于了这个类型的最大值,那么这个值是不可能插入的。
整数类型还有一个AUTO_INCREMENT属性。该属性可以使字段成为自增字段。具有该属性的字段,在插入新的记录时,该字段的值都会在前一条记录的基础上加1。字段选择哪个整数类型,取决于该字段的范围。如果字段的最大值不超过255,那么 选择TINYINT类型就足够了。取值很大时,根据最大值的范围选择取INT类型或BIGINT类型。现在最常用的整数类型是INT类型。
4.1.2浮点数类型和定点数类型
MySQL中使用浮点数类型和定点数类型来表示小数。浮点数类型包括单精度浮点数 (FLOAT型)和双精度浮点数(DOUBLE型)。定点数类型就是DECIMAL型。本小节中将讲解FLOAT型、DOUBLE型和DECIMAL型的取值范围、存储的字节数和特点等内容。下面从这三种类型的字节数、取值范围等方面进行对比,如表所示。
整数类型 | 字节数 | 负数的取值范围 | 非负数的取值范围 |
---|---|---|---|
FLOAT | 4 | -3.402823466E+38~ -1.175494351E-38 | 0和1.175494351E-38~ 3.402823466E+38 |
DOUBLE | 8 | -1.7976931348623157E+308~ -2.225073 8585072014E-308 | 0和2.22507385850720]4E-308~1.7976931348623157E+308 |
DECIMAL(M,D) 或 DEC(M,D) | M+2 | 同DOUBLE型 | 同DOUBLE型 |
从上面表中可以看到,DECIMAL型的取值范围与DOUBLE相同。但是,DECIMAL 的有效取值范围由M和D决定。而且,DECIMAL型的字节数是M+2。也就是说,定点数的存储空间是根据其精度决定的。MySQL中可以指定浮点数和定点数的精度。其基本形式如下:
数据类型(M,D)
其中,“数据类型”参数是浮点数或定点数的数据类型名称;M参数称为精度,是数 据的总长度,小数点不占位置;D参数成为标度,是指小数点后的长度为D。例如FLOAT(6,2) 的含义数据FLOAT型,数据长度为6,小数点后保留2位。按此定义,1234.56是符合要求的。
注意:上述指定小数精度的方法虽然都适合于浮点数和定点数,但不是浮点数的标准用法。建议在定义浮点数时,如果不是实际情况需要,最好不要使用。如果使用了, 可能会影响数据库的迁移。对定点数而言,DOUBLE(M,D)是定点数的标准格式, 一般情况下可以选择这种数据类型。
如果插入值的精度高于实际定义的精度,系统会自动进行四舍五入处理,使值的精度达到要求。不同的是,FLOAT型和DOUBLE型在四舍五入时不会报错,而DECIMAL型会有警告。【示例4】下面某表的字段a、b和c的数据类型分别是FLOAT(6,2)、DOUBLE(6,2)和DECIMAL(6,2),向表中插入3.143、3.145和3.1434。其显示结果如下:
+-----+------+------+ |3.14 | 3.15 | 3.14 | +-----+------+------+
结果显示,插入的数值都进行了四舍五入处理。同时系统出现警告,显示如下:
+-------+------+----------------------------------------+ | Leve | Code | Message | | Note | 1265 | Data truncates for column 'c' at row 1 | +-------+------+----------------------------------------+
警告显示,字段c插入的信息被截断。而a和b字段却没有警告。 如果不指定精度,浮点数和定点数有其默认的精度。FLOAT和DOUBLE型默认会 保存实际精度,但这与操作系统和硬件的精度有关。DECIMAL型默认整数位为10,小数位为0,即默认为整数。【示例】下面某表的字段a、b和c的数据类型分别是FLOAT、DOUBLE和 DECIMAL,向表中插入3.143、3.145和3.1434。其显示结果如下:
+-------+-------+---+ | 3.143 | 3.145 | 3 | +-------+-------+---+
上面程序结果显示,字段a和b是按照实际精度保存的。而字段c进行了四舍五入处理,而且没有小数位。同时系统出现警告,显示如下:
+-------+------+----------------------------------------+ | Leve | Code | Message | | Note | 1265 | Data truncates for column 'c' at row 1 | +-------+------+----------------------------------------+
字段C的值被截断时依然出现了系统报警。
技巧:在MySQL中,定点数以字符串形式存储。因此,其精度比浮点数要高。而且, 浮点数会出现误差,这是浮点数一直存在的缺陷。如果要对数据的精度要求比较高,还是选择定点数(DECIMAL )比较安全。
4.1.3日期与时间类型
日期与时间类型是为了方便在数据库中存储日期和时间而设计的。MySQL中有多种表示日期和时间的数据类型。其中,YEAR类型表示时间;DATE类型表示日期;TIME 类型表示时间;DATETIME和TIMESTAMP表示日期和时间。本小节将介绍上述类型的 存储的字节数、取值范围和特点。
下面从这5种日期与时间类型的字节数、取值范围和零值等方面进行对比,如表所示。
整数类型 | 字节数 | 取值范围 | 零值 |
---|---|---|---|
YEAR | 1 | 1901~2155 | 0000 |
DATE | 4 | 100-01-01~9999-12-31 | 0000:00:l00 |
TIME | 3 | -838:59:59~838:59:59 | 00:00:00 |
DATETIME | 8 | 1000-01-01 00:00:00~9999-12-31 23:59:59 | 0000-00-00 00:00:00 |
TIMESTAMP | 4 | 1700101080001~20380119111407 | 00000000000000 |
从上表可以看到,每种日期与时间类型都有一个有效范围。如果插入的值超过了这个范围,系统会报错,并将零值插入到数据库中。不同的日期与实践类型有不同的零值。
1.YEAR类型
YEAR类型使用1个字节来表示年份。MYSQL中以YYYY的形式显示YEAR类型的值。给YEAR类型的字段赋值的表示方法如下:
使用4位字符串或数字表示。其范围从1901~2155.输入格式为‘YYYY’或YYYY.
使用2位字符串表示。'00'~'69'转换为2000~2069,'70'~'79'转换为1970~1999.
注意:使用YEAR类型时,一定要注意区分0和‘0’。如果向YEAR类型的字段插入 0,存入该字段的年份是0000。如果向YEAR类型的字段插入‘0’,存入的年份是2000。 ‘00’和‘0’是一样的效果。因此,插入记录时一定要注意,虽然 只相差个引号,实际却是相差了2000年。
2.TIME类型
TIME类型使用3个字节来表示时间。MySQL 中以HH:MM:SS的形式显示TIME类型的值。其中,HH表示时;MM表示分,取值范围为0~59; SS表示秒,取值范围是0~59。TIME类型的范围可以从‘-838:59:59’~‘838:59:59’。虽然,小时的范围是0~23。 但是为了表示某种特殊需要的时间间隔,将TIME类型的范围扩大了。而且,还支持了负 值。TIME类型的字段赋值的表示方法如下。
‘D HH:MM:SS’格式的字符串表示。其中,D表示天数,取值范围是0~34。保存时,小时的值等于(D*24+HH)。例如,输入‘2 11:30:50’,TIME类型会转 换为59:30:50。当然,输入时可以不严格按照这个格式,也可以是“HH:MM:SS”、“HH:MM”、“DHH:MM”、“DHH”或者“SS”等形式。例如,输入‘30’,TIME类型会转换为00:00:30。
'HHMMSS'格式的字符串或HHMMSS的数值表示。例如,输入‘345454’, TIME类型会转换为34:54:54;输入值为数值345454,TIME类型也会转换为 34:54:54。如果输入0和‘0’ ’那么TIME类型会转换为0000:00:00。
使用CURRENTIME或者NOW()输入当前系统时间。
3.DATE类型
DATE类型使用4个字节来表示日期。MySQL中是以YYYY-MM-DD的形式显示 DATE类型的值。其中,YYYY表示年;MM表示月;DD表示日。DATE类型的范围可 以从‘1000-01-01’~‘9999-12-31’。给DATE类型的字段赋值的表示方法如下:
'YYYY-MM-DD'或‘YYYYMMDD’格式的字符串表示。这种方式可以表达的 范围是 ‘1000-01-01’~‘9999-12-31’。
'YY-MM-DD'或者‘YYMMDD’格式的字符串表示。其中‘YY’的取值,‘00’~‘69’转换为2000~2069, (70’~‘99’转换为1970~1999。
使用CURRENT_DATE或NOW()来输入当前系统日期。
4.DATETIME类型
DATETIME类型使用8个字节来表示日期和时间。MySQL中以‘YYYY-MM-DD HH:MM:SS’的形式显示DATETIME类型的值。从其形式可以看出,DATETIME类型可 以直接用DATE类型和TIME类型组合而成。给DATETIME类型的字段赋值的表示方法如下:
'YYYY-MM-DDHH:MM:SS'或‘YYYYMMDDHHMMSS’ 格式的字符串表示.这种方式可以表达的范围是 ‘1000-01-01 00:00:00’~‘9999-12-31 23:59:59’。
'YY-MM-DD HH:MM:SS'或‘YYMMDDHHMMSS’格式的字符串表示。其中‘YY’的取值,‘00’~‘69’转换为2000~2069,‘70’~‘99’转换为1970~1999.与YEAR型和DATE型相同。
YYYYMMDDHHMMSS或YYMMDDHHMMSS格式的数字表示。例如,输入20080808080808,DATETIME类型转换为2008-08-08 08:08:08;输入 080808080808,同样转换为2008-08-08 08:08:08。如果输入的值为0,那么DATETME类型转换为0000-00-00 00-00-00。
使用NOW()来输入当前系统日期和时间。
5.TIMESTAMP
TIMESTAMP类型使用4个字节来表示日期和时间。TIMESTAMP类型的范围是从 1970-01-01 08:00:01~2038-01-19 ll:14:07.MySQL 中也是以‘YYYY-MM-DD HH:MM:SS' 的形式显示TIMESTAMP类型的值。从其形式可以看出,TIMESTAMP类型与DATETIME 类型显示的格式是一样的。给1TIMESTAMP类型的字段赋值的表示方法基本与DATETIME
下面介绍TIMESTAMP类型的几种与DATETIME类型不同的形式。内容如下:
使用CURRENT_TIMESTAMP来输入系统当前日期与时间。
输入null时,系统会输入系统当前日期与时间。
无任何输入时,系统会输入系统当前日期与时间。
TIMESTAMP类型还有一个很大的特殊点,就是时间是根据时区来显示的。例如,在东八区插入的TIMESTAMP类型为2009-09-30 ]4:21:25。在东七区显示时,时间部分就变成了 13:21:25。在东九区显示时,时间部分就变成了 15:21:25。需要显示日期与时间,TIMESTAMP类型能够根据不同地区的时区来转换时间。但是,TIMESTAMP类型的范围太小。其最大时间为2038-01-19 11:14:07。如果插入的时间 比这个大,将会出错。例如,输入2038-01-19 11:14:08,系统会出现“ERROR1292(22007): tocorrect datetime value: '2038-01-19 11:15:08' for column 'a' at row 1 ”这样的错误提示。因此,若需要的时间范围比较大,还是选择DATETIME类型比较安全。
4.1.4字符串类型
字符串类型是在数据库中存储字符串的数据类型.字符串类型包括CHAR、VARCHAR、BLOB、TEXT、ENUN和SET。本小节将讲解各种字符串类型的特点和差异.
1.CHAR类型和VARCHAR类型
CHAR类型和VARCHAR类型都是在创建表时指定了最大长度,其基本形式如下:
字符串类型(M)
其中,“字符串类型”参数指定了数据类型为CHAR类型还是VARCHAR类型;M 参数指定了该字符串的最大长度为M。例如,CHAR(4)就是指数据类型为CHAR,其最大长度为4。
CHAR类型的长度是固定的,在创建表时就指定了。其长度可以是0~255的任意值。 例如,CHAR(100)就是指定CHAR类型的长度为100。
VARCHAR类型的长度是可变的,在创建表时指定了最大长度。定义时,其最大值可 以取0~65535之间的任意值。指定VARCHAR类型的最大值以后,其长度可以在0到最大长度之间。例如,VARCHAR(100)的最大长度是100。但是不是每条记录都要占用100 个字节。而是在这个最大值范围内,使用多少分配多少。VARCHAR类型实际占用的空间 为字符串的实际长度加1。这样,即可有效节约系统的空间.
2.text类型
TEXT类型是一种特殊的字符串类型。TEXT只能保存字符数据,如新闻的内容等。 TEXT 类型包括 TENYTEXT、TEXT、MEDRJMTEXT 和 LONGTEXT。
3.ENUM类型
ENUM类型又称为枚举类型。在创建表时,ENUM类型的取值范围就以列表的形式指定了。其基本形式如下:
属性名 ENUM('值1','值2','值3',......'值n')
其中,属性名参数指字段的名称;“值n”参数表示列表中的第n个值,这些值末尾的 空格将会被系统直接删除。ENUM类型的值只能取列表中的一个元素。其取值列表中最多能有65535个值。列表中的每个值都有一个顺序排列的编号,MySQL中存入的是这个编号,而不是列表中的值。如果ENUM类型加上了NOT NULL属性,其默认值为取值列表的第一个元素。如果 不加NOT NULL属性,ENUM类型将允许插入NULL而且NULL为默认值。
4.SET类型
在创建表时,SET类型的取值范围就以列表的形式指定了。其基本形式如下。属性名SET('值1', '值'2,…,'值n')其中,“属性名”参数指字段的名称;“值n”参数表示列表中的第n个值,这些值末尾的空格将会被系统直接删除。其基本形式与ENUM类型一样。SET类型的值可以取列表中的一个元素或者多个元素的组合。取多个元素时,不同元素之间用逗号隔开。SET类 型的值最多只能是有64个元素构成的组合。同ENUM类型一样,列表中的每个值都有一个顺序排列的编号。MYSQL中存入的是这个编号,而不是列表中的值。插入记录时,SET字段中的元素顺序无关紧要。存入MYSQL数据库后,数据库系统 会自动按照定义时的顺序显示。
4.1.5 二进制类型
二进制类型是在数据库中存储二进制数据的数据类型。二进制类型包括BWARY、 VARBWARY、BIT、TINYBLOB、BLOB、MEDIUMBLOB和LONGBLOB.
1.BINARY和VARBINARY类型
BINARY类型和VARBINARY类型都是在创建表时指定了最大长度,其基本形式 如下:
字符串类型(M)
其中,“字符串类型”参数指定了数据类型为BINARY类型还是VARBINARY类型;M参数指定了该二进制数的最大字节长度为M。这与 CHAR类型和VARCHAR类型相似。 例如,BINARY(10)就是指数据类型为BINARY类型,其最大长度为10。
BINARY类型的长度是固定的,在创建表时就指定了。不足最大长度的空间由“\0” 补全。例如,BINARY(50)就是指定BINARY类型的长度为50。VARBINARY类型的长度是可变的,在创建表时指定了最大长度。指定好了VARBINARY类型的最大值以后,其长度可以在0到最大长度之间。例如,VARBINARY(50)的最大字节长度是50。但是,不是每条记录的字节长度都是50。在这个最大值范围内, 使用多少分配多少。VARBINARY类型实际占用的空间为实际长度加1。这样,可以有效的节约系统的空间。
2.BIT类型
BIT类型也是在创建表时指定了最大长度,其基本形式如下:
BIT(M)
其中,“M”指定了该二进制数的最大字节长度为M,M的最大值为64。例如,BIT(4) 就是数据类型为BIT类型,长度为4。若字段的类型BIT(4),存储的数据是从0~15。因为,变成二进制以后,15的值为1111,其长度为4。如果插入的值为16,其二进制数为 10000,长度为5,超过了最大长度。因此,大于等于16的数是不能插入到BIT(4)类型的字段中的。在查询BIT类型类型的数据时,要用BIN(字段名+0)来将值转换为二进制显示。
3.BLOB类型
BLOB类型是一种特殊的二进制类型。BLOB可以用来保存数据量很大的二进制数据,如图片等。BLOB类型包括TINYBLOB、BLOB、MEDIUMBLOB和LONGBLOB。这几种BLOB类型最大的区别就是能够保存的最大长度不同。LONGBLOB的长度最大,TINBLOB的长度最小。BLOB类型与TEXT类型很类似。不同点在于BLOB类型用于存储二进制数据,BLOB 类型数据是根据其二进制编码进行比较和排序。而TEXT类型是文本模式进行比较和排序的。