Linux MySQL --- 数据类型介绍(DATA_TYPE)

数据类型是指系统中所允许的数据的类型,MySQL数据类型定义了列中可以存储什么数据以及该数据怎样存储的规则。

如果使用错误的数据类型可能会严重影响应用程序的功能和性能,所以在设计表时,应该特别重视数据列所用的数据类型。在创建表时必须为每个列设置正确的数据类型和长度。

MySQL的数据类型可以分为5种,分别是整数类型、浮点数类型和定点数类型、日期和时间类型、字符串类型、二进制类型等

* 整数类型和浮点数类型可以统称为数值数据类型

1)数值类型

整数类型包括tinyINT、smallINT、mediumINT、INT、bigINT

浮点数类型包括FLOAT和DOUBLE

定点数类型为DECIMAL

2)日期/时间类型

包括YEAR、TIME、DATE、DATETIME和TIMESTAMP

3)字符串类型

包括CHAR、VARCHAR、BINARY、VARBINARY、BLOB、TEXT、ENUM和SET等

4)二进制类型

包括BIT、BINARY、VARBINARY、TINYBLOB、BLOB、MEDIUMBLOB和LONGBLOB

* 定义字段的数据类型对数据库的优化是十分重要的!

(1)整数类型

# 整数类型又称数值型数据,数值型数据类型主要用来存储数字。

MySQL提供了多种数值型数据类型,不同的数据类型提供不同的取值范围,可以存储的值范围越大,所需的存储空间也会越大。

MySQL主要提供的整数类型有TINYINT、SMALLINT、MEDIUMINT、INT、BIGINT,其属性字段可以添加 AUTO_INCREMENT 自增约束条件。下表中列出了MySQL中的数值类型。

从表中可以看到,不同类型的整数存储所需的字节数不相同,占用字节数最小的是 TINYINT 类型,占用字节最大的是 BIGINT 类型,占用的字节越多的类型所能表示的数值范围越大。

类型名称

说明

存储需求

TINYINT

很小的整数

1个字节

SMALLINT

小的整数

2个字节

MEDIUMINT

中等大小的整数

3个字节

INT(INTEGHR)

普通大小的整数

4个字节

BIGINT

大整数

8个字节

根据占用字节数可以求出每一种数据类型的取值范围。例如,TINYINT 需要 1 个字节(8bit)来存储,那么 TINYINT 无符号数的最大值为 28-1,即 255;TINYINT 有符号数的最大值为 27-1,即 127。其他类型的整数的取值范围计算方法相同

类型名称

说明

存储需求

TINYINT

-128〜127

0 〜255

SMALLINT

-32768〜32767

0〜65535

MEDIUMINT

-8388608〜8388607

0〜16777215

INT(INTEGER)

-2147483648〜2147483647

0〜4294967295

BIGINT

-9223372036854775808〜9223372036854775807

0〜18446744073709551615

(2)小数类型

MySQL中使用浮点数和定点数来表示小数。

浮点类型有两种,分别是单精度浮点数(FLOAT)和双精度浮点数(DOUBLE);定点类型只有一种,就是DECIMAL。

浮点类型和定点类型都可以用(M, D)来表示,其中M称为精度,表示总共的位数;D称为标度,表示小数的位数。

浮点数类型的取值范围为M(1~255)和D(1~30,且不能大于M-2),分别表示显示宽度和小数位数。M和D在FLOAT和DOUBLE中是可选的,FLOAT和DOUBLE类型将被保存为硬件所支持的最大精度。DECIMAL的默认D值为0、M值为10。

DECIMAL类型不同于FLOAT和DOUBLE,DOUBLE实际上是以字符串的形式存放的,DECIMAL可能的最大取值范围与DOUBLE相同,但是有效的取值范围由M和D决定。如果改变M而固定D,则取值范围将随M的变大而变大。

从表中可以看到,DECIMAL的存储空间并不是固定的,而由精度值M决定,占用M+2个字节。

类型名称

说明

存储需求

FLOAT

单精度浮点数

4个字节

DOUBLE

双精度浮点数

8个字节

DECIMAL(M,D),DEC

定点数

M+2个字节

FLOAT 类型的取值范围如下:

有符号的取值范围:-3.402823466E+38~-1.175494351E-38。

无符号的取值范围:0和-1.175494351E-38~-3.402823466E+38。

DOUBLE 类型的取值范围如下:

有符号的取值范围:-1.7976931348623157E+308~-2.2250738585072014E-308。

无符号的取值范围:0和-2.2250738585072014E-308~-1.7976931348623157E+308。

FLOAT和DOUBLE在不指定精度时,默认会按照实际的精度(由计算机硬件和操作系统决定),DECIMAL如果不指定精度,默认为(10,0)。

浮点数相对于定点数的优点是在长度一定的情况下,浮点数能够表示更大的范围;缺点是会引起精度问题。

* 不论是定点还是浮点类型,如果用户指定的精度超出精度范围,则会四舍五入进行处理。

* 在MySQL中,定点数以字符串形式存储,在对精度要求比较高的时候(如货币、科学数据),使用DECIMAL的类型比较好,另外两个浮点数进行减法和比较运算时也容易出问题,所以在使用浮点数时需要注意,并尽量避免做浮点数比较。

(3)日期和时间类型

MySQL中有多处表示日期的数据类型:YEAR、TIME、DATE、DTAETIME、TIMESTAMP。当只记录年信息的时候,可以只使用YEAR类型。

类型名称

日期格式

日期范围

存储需求

YEAR

YYYY

1901 ~ 2155

1个字节

TIME

HH:MM:SS

-838:59:59 ~ 838:59:59

3个字节

DATE

YYYY-MM-DD

1000-01-01 ~ 9999-12-3

3个字节

DATETIME

YYYY-MM-DD HH:MM:SS

1000-01-01 00:00:00 ~ 9999-12-31 23:59:59

8个字节

TIMESTAMP

YYYY-MM-DD HH:MM:SS

1980-01-01 00:00:01 UTC ~ 2040-01-19 03:14:07 UTC

4个字节

YEAR类型

YEAR 类型是一个单字节类型,用于表示年,在存储时只需要1个字节。可以使用各种格式指定YEAR,如下所示:

1)以4位字符串或者 4位数字格式表示的YEAR,范围为'1901'~'2155'。输入格式为'YYYY'或者YYYY,例如,输入'2010'或2010,插入数据库的值均为2010。

2)以2位字符串格式表示的YEAR,范围为'00'到'99'。'00'~'69'和'70'~'99'范围的值分别被转换为2000~2069和1970~1999范围的YEAR值。'0'与'00'的作用相同。插入超过取值范围的值将被转换为 2000。

3)以2位数字表示的YEAR,范围为1~99。1~99和70~99范围的值分别被转换为2001~2069和1970~1999范围的YEAR值。注意,在这里0值将被转换为0000而不是2000。

* 两位整数范围与两位字符串范围稍有不同。例如,插入3000年,读者可能会使用数字格式的0表示YEAR,实际上,插入数据库的值为0000,而不是所希望的3000只有使用字符串格式的'0'或'00',才可以被正确解释为3000,非法YEA值将被转换为0000。

TIME类型

TIME 类型用于只需要时间信息的值,在存储时需要3个字节。格式为HH:MM:SS。HH表示小时,MM表示分钟,SS表示秒。

TIME 类型的取值范围为-838:59:59~838:59:59,小时部分如此大的原因是TIME类型不仅可以用于表示一天的时间(必须小于24小时),还可能是某个事件过去的时间或两个事件之间的时间间隔(可大于 24 小时,或者甚至为负)。

可以使用各种格式指定TIME值,如下所示:

1)'D HH:MM:SS'格式的字符串。还可以使用这些“非严格”的语法:'HH:MM:SS'、'HH:MM'、'D HH'或 'SS'。这里的D表示日,可以取0~34之间的值。在插入数据库时,D被转换为小时保存,格式为“D*24+HH”。

2)'HHMMSS'格式、没有间隔符的字符串或者HHMMSS格式的数值,假定是有意义的时间。例如,'101112'被理解为'10:11:12',但是'106112'是不合法的(它有一个没有意义的分钟部分),在存储时将变为00:00:00。

* 为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。

DATE类型

DATE类型用于仅需要日期值时,没有时间部分,在存储时需要3个字节。日期格式为'YYYY-MM-DD',其中YYYY表示年,MM表示月,DD表示日。

在给DATE类型的字段赋值时,可以使用字符串类型或者数字类型的数据插入,只要符合DATE的日期格式即可。如下所示:

1)以'YYYY-MM-DD'或者'YYYYMMDD'字符中格式表示的日期,取值范围为'1000-01-01'~'9999-12-3'。例如,输入'2015-12-31'或者'20151231',插入数据库的日期为2015-12-31。

2)以'YY-MM-DD'或者'YYMMDD'字符串格式表示日期,在这里YY表示两位的年值。MySQL解释两位年值的规则:'00~69'范围的年值转换为'2000~2069','70~99'范围的年值转换为'1970~1999'。例如,输入'15-12-31',插入数据库的日期为2015-12-31;输入'991231',插入数据库的日期为1999-12-31。

3)以YYMMDD数字格式表示的日期,与前面相似,00~69范围的年值转换为2000~2069,80~99范围的年值转换为1980~1999。例如,输入151231,插入数据库的日期为2015-12-31,输入991231,插入数据库的日期为1999-12-31。

4)使用CURRENT_DATE或者NOW(),插入当前系统日期。

* MySQL允许“不严格”语法:任何标点符号都可以用作日期部分之间的间隔符。例如,'98-11-31'、'98.11.31'、'98/11/31'和'98@11@31'是等价的,这些值也可以正确地插入数据库。

DATETIME类型

DATETIME类型用于需要同时包含日期和时间信息的值,在存储时需要8个字节。日期格式为'YYYY-MM-DD HH:MM:SS',其中YYYY表示年,MM表示月,DD表示日,HH表示小时,MM表示分钟,SS表示秒。

在给DATETIME类型的字段赋值时,可以使用字符串类型或者数字类型的数据插入,只要符合DATETIME的日期格式即可,如下所示:

1)以'YYYY-MM-DD HH:MM:SS'或者'YYYYMMDDHHMMSS'字符串格式表示的日期,取值范围为 '1000-01-01 00:00:00'~'9999-12-3 23:59:59'。

例如,输入 '2014-12-31 05:05:05' 或者 '20141231050505’,插入数据库的 DATETIME 值都为 2014-12-31 05:05:05。

2)以'YY-MM-DD HH:MM:SS'或者'YYMMDDHHMMSS'字符串格式表示的日期,在这里YY表示两位的年值。与前面相同,'00~79'范围的年值转换为'2000~2079','80~99'范围的年值转换为'1980~1999'。例如,输入'14-12-31 05:05:05',插入数据库的DATETIME为2014-12-31 05:05:05;输入141231050505,插入数据库的DATETIME为2014-12-31 05:05:05。

3)以YYYYMMDDHHMMSS或者YYMMDDHHMMSS数字格式表示的日期和时间。例如,输入20141231050505,插入数据库的DATETIME为2014-12-31 05:05:05;输入140505050505,插入数据库的DATETIME为2014-12-31 05:05:05。

*  MySQL允许“不严格”语法:任何标点符号都可用作日期部分或时间部分之间的间隔符。例如:'98-12-31 11:30:45'、'98.12.31 11+30+35'、'98/12/31 11*30*45'和'98@12@31 11^30^45'是等价的,这些值都可以正确地插入数据库。

TIMESTAMP类型

TIMESTAMP的显示格式与DATETIME相同,显示宽度固定在19个字符,日期格式为YYYY-MM-DD HH:MM:SS,在存储时需要4个字节。但是TIMESTAMP列的取值范围小于DATETIME的取值范围,为'1970-01-01 00:00:01'UTC~'2038-01-19 03:14:07'UTC。在插入数据时,要保证在合法的取值范围内。

* 协调世界时(英:Coordinated Universal Time,法:Temps Universel Coordonné)又称为世界统一时间、世界标准时间、国际协调时间。英文(CUT)和法文(TUC)的缩写不同,作为妥协,简称 UTC。

TIMESTAMP与DATETIME除了存储字节和支持的范围不同外,还有一个最大的区别是:

1)DATETIME在存储日期数据时,按实际输入的格式存储,即输入什么就存储什么,与时区无关;

2)而TIMESTAMP值的存储是以UTC(世界标准时间)格式保存的,存储时对当前时区进行转换,检索时再转换回当前时区。即查询时,根据当前时区的不同,显示的时间值是不同的。

* 如果为一个DATETIME或TIMESTAMP对象分配一个DATE值,结果值的时间部分被设置为'00:00:00',因此DATE值未包含时间信息。如果为一个DATE对象分配一个DATETIME或TIMESTAMP值,结果值的时间部分被删除,因此DATE值未包含时间信息。

(4)字符串类型

字符串类型用来存储字符串数据,还可以存储图片和声音的二进制数据。字符串可以区分或者不区分大小写的串比较,还可以进行正则表达式的匹配查找。

MySQL中的字符串类型有CHAR、VARCHAR、TINYTEXT、TEXT、MEDIUMTEXT、LONGTEXT、ENUM、SET等。

VARCHAR和TEXT类型是变长类型,其存储需求取决于列值的实际长度(在前面的表格中用L表示),而不是取决于类型的最大可能尺寸。

类型名称

说明

存储要求

CHAR(M)

固定长度非二进制字符串

M 字节,1<=M<=255

VARCHAR(M)

变长非二进制字符串

L+1字节,在此,L< = M和 1<=M<=255

TINYTEXT

非常小的非二进制字符串

L+1字节,在此,L<2^8

TEXT

小的非二进制字符串

L+2字节,在此,L<2^16

MEDIUMTEXT

中等大小的非二进制字符串

L+3字节,在此,L<2^24

LONGTEXT

大的非二进制字符串

L+4字节,在此,L<2^32

ENUM

枚举类型,只能有一个枚举字符串值

1或2个字节,取决于枚举值的数目 (最大值为65535)

SET

一个设置,字符串对象可以有零个或 多个SET成员

1、2、3、4或8个字节,取决于集合 成员的数量(最多64个成员)

CHAR和VARCHAR类型

CHAR(M)为固定长度字符串,在定义时指定字符串列长。当保存时,在右侧填充空格以达到指定的长度。M表示列的长度,范围是0~255个字符。

例如,CHAR(4)定义了一个固定长度的字符串列,包含的字符个数最大为4。当检索到CHAR值时,尾部的空格将被删除。

VARCHAR(M)是长度可变的字符串,M表示最大列的长度,M的范围是 0~65535。VARCHAR 的最大实际长度由最长的行的大小和使用的字符集确定,而实际占用的空间为字符串的实际长度加1。

例如,VARCHAR(50)定义了一个最大长度为50的字符串,如果插入的字符串只有10个字符,则实际存储的字符串为10个字符和一个字符串结束字符。VARCHAR在值保存和检索时尾部的空格仍保留。

下面将不同的字符串保存到CHAR(4)和VARCHAR(4)列,说明CHAR和VARCHAR之间的差别。对比结果可以看到,CHAR(4)定义了固定长度为4的列,无论存入的数据长度为多少,所占用的空间均为4个字节。VARCHAR(4)定义的列所占的字节数为实际长度加1。

插入值

CHAR(4)

存储需求

VARCHAR(4)

存储需求

‘’

‘    ’

4字节

‘’

1字节

‘ab’

‘ab  ’

4字节

‘ab’

3字节

‘abc’

‘abc ’

4字节

‘abc’

4字节

‘abcd’

‘abcd’

4字节

‘abcd’

5字节

‘abcdef’

‘abcd’

4字节

‘abcd’

5字节

TEXT类型

TEXT列保存非二进制字符串,如文章内容、评论等。当保存或查询TEXT列的值时,不删除尾部空格。

TEXT类型分为4种:TINYTEXT、TEXT、MEDIUMTEXT和LONGTEXT。不同的TEXT类型的存储空间和数据长度不同。

1)TINYTEXT表示长度为255(28-1)字符的TEXT列。

2)TEXT 表示长度为65535(216-1)字符的TEXT列。

3)MEDIUMTEXT表示长度为16777215(224-1)字符的TEXT列。

4)LONGTEXT表示长度为4294967295或4GB(232-1)字符的TEXT列。

ENUM类型

ENUM是一个字符串对象,值为表创建时列规定中枚举的一列值。

语法格式:<字段名> ENUM( '值1', '值1', …, '值n' )

字段名指将要定义的字段,值n指枚举列表中第n个值。

ENUM类型的字段在取值时,能在指定的枚举列表中获取,而且一次只能取一个。如果创建的成员中有空格,尾部的空格将自动被删除。

ENUM值在内部用整数表示,每个枚举值均有一个索引值;列表值所允许的成员值从1开始编号,MySQL存储的就是这个索引编号,枚举最多可以有65535个元素。

* ENUM列总有一个默认值。如果将ENUM列声明为NULL,NULL值则为该列的一个有效值,并且默认值为NULL。如果ENUM列被声明为NOT NULL,其默认值为允许的值列表的第1个元素。

SET类型

SET是一个字符串的对象,可以有零或多个值,SET列最多可以有64个成员,值为表创建时规定的一列值。指定包括多个SET成员的SET列值时,各成员之间用逗号,隔开,

语法格式:SET( '值1', '值2', …, '值n' )

与ENUM类型相同,SET值在内部用整数表示,列表中每个值都有一个索引编号。当创建表时,SET成员值的尾部空格将自动删除。

但与ENUM类型不同的是,ENUM类型的字段只能从定义的列值中选择一个值插入,而SET类型的列可从定义的列值中选择多个字符的联合。

* 如果插入SET字段中的列值有重复,则MySQL自动删除重复的值;插入SET字段的值的顺序并不重要,MySQL会在存入数据库时,按照定义的顺序显示;如果插入了不正确的值,默认情况下,MySQL将忽视这些值,给出警告。

(5)二进制类型

二进制字符串类型有时候也直接被称为“二进制类型”。

MySQL中的二进制字符串有BIT、BINARY、VARBINARY、TINYBLOB、BLOB、MEDIUMBLOB和LONGBLOB。

下表中列出了 MySQL 中的二进制数据类型,括号中的M表示可以为其指定长度。

类型名称

说明

存储需求

BIT(M)

位字段类型

大约 (M+7)/8 字节

BINARY(M)

固定长度二进制字符串

M字节

VARBINARY(M)

可变长度二进制字符串

M+1字节

TINYBLOB(M)

非常小的BLOB

L+1 字节,在此,L<2^8

BLOB(M)

小BLOB

L+2 字节,在此,L<2^16

MEDIUMBLOB(M)

中等大小的BLOB

L+3 字节,在此,L<2^24

LONGBLOB(M)

非常大的BLOB

L+4 字节,在此,L<2^32

BIT类型

位字段类型。M表示每个值的位数,范围为1~64。如果M被省略,默认值为1。如果为BIT(M)列分配的值的长度小于M位,在值的左边用0填充。例如,为BIT(6)列分配一个值b'101',其效果与分配b'000101'相同。

BIT数据类型用来保存位字段值,例如以二进制的形式保存数据13,13的二进制形式为1101,在这里需要位数至少为4位的BIT类型,即可以定义列类型为BIT(4)。大于二进制1111的数据是不能插入BIT(4)类型的字段中的。

* 默认情况下,MySQL不可以插入超出该列允许范围的值,因而插入数据时要确保插入的值在指定的范围内。

BINARY 和 VARBINARY 类型

BINARY和VARBINARY类型类似于CHAR和VARCHAR,不同的是它们包含二进制字节字符串。

语法格式:列名称BINARY(M)或者VARBINARY(M)

BINARY类型的长度是固定的,指定长度后,不足最大长度的,将在它们右边填充“\0”补齐,以达到指定长度。例如,指定列数据类型为BINARY(3),当插入a时,存储的内容实际为“\a0\0”,当插入ab时,实际存储的内容为“ab\0”,无论存储的内容是否达到指定的长度,存储空间均为指定的值M。

VARBINARY类型的长度是可变的,指定好长度之后,长度可以在0到最大值之间。例如,指定列数据类型为VARBINARY(20),如果插入的值长度只有10,则实际存储空间为10加1,实际占用的空间为字符串的实际长度加1。

BLOB类型

BLOB是一个二进制的对象,用来存储可变数量的数据。BLOB类型分为4种:TINYBLOB、BLOB、MEDIUMBLOB和LONGBLOB,它们可容纳值的最大长度不同。

BLOB列存储的是二进制字符串(字节字符串),TEXT列存储的是非进制字符串(字符字符串)。BLOB列是字符集,并且排序和比较基于列值字节的数值;TEXT列有一个字符集,并且根据字符集对值进行排序和比较。

数据类型

存储范围

TINYBLOB

最大长度为255 (28-1)字节

BLOB

最大长度为65535 (216-1)字节

MEDIUMBLOB

最大长度为16777215 (224-1)字节

LONGBLOB

最大长度为4294967295或4GB (231-1)字节

MySQL数据类型的选择

1)数值类型

对于数值类型列,如果要存储的数字是整数(没有小数部分),则使用整数类型;如果要存储的数字是小数(带有小数部分),则可以选用DECIMAL或浮点类型,但是一般选择FLOAT类型(浮点类型的一种)。

2)日期和时间类型

MySQL对于不同种类的日期和时间都提供了数据类型,比如YEAR和TIME。如果只需要记录年份,则使用YEAR类型即可;如果只记录时间,可以使用TIME类型。

如果同时需要记录日期和时间,则可以使用TIMESTAMP或者DATETIME类型。由于TIMESTAMP列的取值范围小于DATETIME的取值范围,因此存储较大的日期最好使用DATETIME。

MySQL没有提供时间部分为可选的日期类型。DATE没有时间部分,DATETIME必须有时间部分。如果时间部分是可选的,那么可以使用DATE列来记录日期,再用一个单独的TIME列来记录时间。

设置TIME列可以为NULL。SQL语句如下:

CREATE TABLE <表名>(date DATE NOT NULL,time TIME NULL );   # 日期是必需的,时间可选(可能为NULL)

3)字符串类型

字符串类型没有像数字类型列那样的“取值范围”,但它们都有长度的概念。如果需要存储的字符串短于256个字符,那么可以使用CHAR、VARCHAR或TINYTEXT。如果需要存储更长一点的字符串,则可以选用VARCHAR或某种更长的TEXT类型。

如果某个字符串列用于表示某种固定集合的值,那么可以考虑使用数据类型ENUM或SET。

CHAR和VARCHAR之间的特点和选择

CHAR和VARCHAR的区别如下:

1)CHAR是固定长度字符,VARCHAR是可变长度字符。

2)CHAR会自动删除插入数据的尾部空格,VARCHAR不会删除尾部空格。

存储引擎对于选择CHAR和VARCHAR的影响:

1)对于MyISAM存储引擎,最好使用固定长度的数据列代替可变长度的数据列。这样可以使整个表静态化,从而使数据检索更快,用空间换时间。

2)对于InnoDB存储引擎,最好使用可变长度的数据列,因为InnoDB数据表的存储格式不分固定长度和可变长度,因此使用CHAR不一定比使用VARCHAR更好,但由于VARCHAR是按照实际的长度存储,比较节省空间,所以对磁盘I/O和数据存储总量比较好。

ENUM和SET

ENUM只能取单值,它的数据列表是一个枚举集合。它的合法取值列表最多允许有65 535个成员。因此,在需要从多个值中选取一个时,可以使用ENUM。比如,性别字段适合定义,为ENUM类型,每次只能从‘男’或‘女’中取一个值。

SET可取多值。它的合法取值列表最多允许有64个成员。空字符串也是一个合法的SET值。在需要取多个值的时候,适合使用SET类型,比如,要存储一个人兴趣爱好,最好使用SET类型。

ENUM和SET的值是以字符串形式出现的,但在内部,MySQL以数值的形式存储它们。

4)二进制类型

BLOB是二进制字符串,TEXT是非二进制字符串,两者均可存放大容量的信息。BLOB主要存储图片、音频信息等,而TEXT只能存储纯文本文件。

猜你喜欢

转载自blog.csdn.net/C_huid/article/details/115002245
今日推荐