MySQL支持的数据类型

---恢复内容开始---

  每个常量、变量和参数都有数据类型,它用来指定一定的存储格式,约束和有效范围。MySQL提供了多种数据类型,主要包括数值型、字符串类型、日期和时间类型,不同的MySQL版本支持的数据类型可能会稍有不同。这里一MySQL5.0版本为例。

  1:数值类型

  MySQL支持所有标准SQL中的数值类型,其中包括严格数值类型(INTEGER、SMALLINT(短整型)、DECIMAL(十进制)和NUMERIC(数值)),以及近似数值类型(FLOAT、REAL(实数)和DOUBLE PRECISION),并在此基础上做了扩展,扩展后增加了TINYINT、MEDIUMINT和BIGINT这3种长度不同的整型,并增加了BIT类型。用来存放位数据,其中INT是INTEGER的同名词,DEC是DECIMAL的同名词、

  

  在整数类型中,按照取值范围和存储方式不同,分为tinyint、smallint、mediumint、int和bigint这5个类型。如果超出类型范围的操作,会发生“out of range”错误提示。为了避免此类问题发生,在选择数据类型时要根据应用的实际情况确定其取值范围,最后根据确定的结果慎重选择数据类型。

   对于整数类型,MySQL还支持在类型名称后面的小括号内指定显示宽度,例如int(5)表示数值宽度小于5位的时候在数字前面填满宽度,如果不显示指定宽度则默认是int(11),一般配合zerofill使用,顾名思义,zerofill就是用“0”填充的意思,也就是在数字位不够的空间用字符“0”填满,一下几个例子分别描述了填充前后的区别。

  (1)创建表t1,有id1和id2两个字段,指定其数值宽度分别为int和int(5);

  
在id1和id2中都插入数值1,可以发现格式没有异常;

 

 分别修改id1和id2的字段类型,加入zerofill参数:

 可以发现,在数值前面用字符“0”填充了剩余的宽度。大家可能有所疑问,设置了宽度限制后,如果插入大于宽度限制的值,会不会截断或者插不进去报错?答案是肯定的:不会对插入的数据有任何影响,还是按照类型的实际精度进行保存,这时,宽度格式实际已经没有意义,,左边不会再填充任何的“0”字符,下面在表t1的字段id1中插入数值1,id2中插入数值1111111,位数为7,大于id2显示位数5,再观察一下测试结果:

  

很显然,如上面所说的,id2中显示了正确的数值,并没有受宽度限制影响,

  所有的整数类型都有一个可选属性UNSIGNED(无符号),如果需要在字段里面保存非负数或者需要较大的上限值时,可以用此选项,它的取值范围是正常值的下限取0,上限取原值的2倍,例如,tinyint的有符号的范围是-128~+127.而无符号的范围是0~255.如果一个列指定为zerofill,则MySQL自动为该列添加UNSIGNED属性。

   另外,整数类型还有一个属性:AUTO_INCREMENT。在需要产生唯一标识符或顺序值时,可利用此属性,这个属性只用于整数类型。AUTO_INCREMENT值一般从1开始,每行增加1.在插入NULL到一个AUTO_INCREMENT时,MySQL插入一个比该列中当前最大值大1的值。一个表中最多只能有一个AUTO_INCREMENT列。对于任何想要使用AUTO_INCREMENT的列。应该定义为NOT NULL,并定义为PRIMARY KEY或定义为UNIQUE键。例如,可按下列任何一种方式定义AUTO_INCREMENT列:

  CREATE TABLE AI(ID INT AUTO_INCREMENT NOT NULL PRIMARY KEY);

  CREATE TABLE AI(ID INT AUTO_INCREMENT NOT NULL,PRIMARY KEY(ID));

  CREATE TABLE AI(ID INT AUTO_INCREMENT NOT NULL,UNIQUE(ID));

   对于小数的表示。MySQL分为两种方式:浮点数和定点数,浮点数包括float(单精度)和double(双精度),而定点数则只有decimal一种表示,定点数在MySQL内部以字符串形式存放,比浮点数更精确,适合用来表示货币等精度高的数据。

  浮点数和定点数都可以用类型名称后加“(M,D)”的方式来进行表示,"(M,D)"表示该值一共显示M位数字(整数位+小数位),其中D位位于小数点后面,M和D又称为精度金和标度。例如,定义为float(7,4)的一个序列可以显示为-999.9999.MySQL保存值时进行四舍五入,因此,如果在float(7,4)列内插入999.00009,近似结果是999.0001.值得注意的是,浮点数后面跟“(M,D)”的用法是非标准用法, 如果要用于数据库的迁移,则最好不要这么使用,float和double在不指定精度使,默认会按照实际的精度(由实际的硬件和操作系统决定)来显示,而decimal在不指定精度时,默认的整数位10,默认的小数位0.

  下面通过一个例子来比较float、double和decimal三者之间的不同。

  (1):创建测试表,分别将id1、id2、id3字段设置为float(5,2)、double(5,2)、decimal(5,2):

  

可以发现,数据都正确的插入了表t2.

  再向id1和id2字段中插入数据1.234,而id3字段仍插入1.23

 

 可以发现,id1,id2,id3都插入了表t2,但是id1和id2由于标度的限制,舍去了最后一位,数据变为了1.23.

  (4):同时向id1,id2,id3字段都插入数据1.234;

 此时发现,虽然数据都插入进去,但是系统出现了一个warning,报告id3被

 (5):将id1,id2,id3字段的精度和标度全部去掉,再次插入数据1.23;

   这个时候,可以发现id1,id2字段中可以正常插入数据,而id3字段的小数位被截断。

  上面的例子验证了上面提到的浮点数如果不写精度和标度,则会按照实际精度值显示,如果有精度和标度,则会自动将四舍五入后的结果插入,系统不会报错;定点数如果不写精度和标度,则按照默认值decimal(10,0)来进行操作,并且如果数据超越了精度和标度值,系统则会报错。

  对于BIT(位)类型,用于存放位字段值,BIT(M)可以用来存放多位二进制,M范围从1~64,如果不写则默认为1位,对于位字段,直接使用select命令将看不到结果,可以用bin()(显示二进制格式)或者hex()(显示十六进制格式)函数进行读取。

  下面的例子中,对于测试表t3中的bit类型字段id做insert和select操作,这里重点观察一下select的结果:

可以发现,直接select*的结果为NULL,改用bin()和hex()函数再试试:

结果可以正常显示为二进制和十六进制数字。

  数据插入bit类型字段时,首先转换为二进制,如果位数允许,将成功插入,如果位数小于实际的位数,则插入失败,下面的例子中,在t3表插入数字2,因为它的二进制码是"10",而id的定义是bit(1),将无法插入成功。

  

将ID定义修改为bit(2)后,重新插入,插入成功:

2:日期时间类型

  MySQL中有多种数据类型可以用于日期和时间的表示,不同的版本可能有所差异.

  这些数据类型的主要区别如下:

  .如果要用来表示年月日,通常用DATE来表示,

  .如果要用来表示年月日时分秒,通常要用DATETIME表示

  .如果只用来表示时分秒,通常用TIME来表示。

 

  DATE、TIME和DATETIME是最使用的3种日期类型,以下例子在3种类型字段插入了相同的日期值,看看它们的显示结果:

  显而易见,DATETIME是DATE和TIME的组合,我们可以根据不同的需要,来选择不同的日期和时间类型以满足不同的应用。

  TIMESTAMP也用来表示日期,但是和DATETIME有所不同.我们先做个测试:

  

可以发现,系统给tm自动创建了默认值CURRENT_TIMESTAMP(系统日期),插入一个NULL值试试:

  果然,t5中正确地插入了系统日期,注意,MySQL只给表中的第一个TIMESTAMP字段设置默认值为系统日期,如果有第二个TIMESTAMP类型,则默认值为0值。测试如下:

id2的默认值不是当前的系统时间。而是0000-00-00 00:00:00,不过,也可以修改id2的默认值为其它常量日期,但是不能再修改为current_timestamp,因为MySQL规定TIMESTAMP类型字段只能有一列的默认值为current_timestamp;如果强制修改,系统会报如下的错误:

  TIMESTAMP还有一个重要的特点是:就是和时区相关,当插入日期时,会先转换为本地时区后存放;而从数据库里面取出来的时候,也同样需要将日期转换为本地时区后显示,这样,两个不同时区的用户看到的同一个日期可能是不一样的,下面的例子演示这个差别:

结果显示id1和id2的值完全相同。

修改时区为东九区,再次查看表中日期:

结果可以发现,id1的值要比id2的值快了1小时,也就是说,东九区的人看到的时间是“2017-02-27 19:20:43”是当地时区的实际日期,也就是东八区的“2017-02-27 18:20:43”,如果还是以“2017-02-27 18:20:43”理解时间必然导致误差。

  

  

  YEAR类型主要用来表示年份。当应用只需要记录年份时,用YEAR比DATE将更节省空间。

最后通过一个例子,说明如何采用不同格式将日期“2017-02-27 19:01:10”插入到DATETIME列中

3:字符串类型

  MySQL中提供了多种对字符类型的存储类型,不同的版本可能有所差异,以5.0版本为例。MySQL包括了CHAR,VARCHAR,BINARY,VARBINARY,BLOB,TEXT,ENUM和SET等多种字符串类。

  

 (1)CHAR和VARCHAR类型

  char和varchar类型很类似,都用来保存MySQL中较短的字符串,二者的主要区别在于存储方式的不同:CHAR列的长度固定为创建表时

 声明的长度,长度可以从0~255的任何值;而VARCHAR列中的值为可变长的字符串,长度可以指定为0~255(MySQL5.0.3版本之前)或者65535(MySQL5.0.3版本之后)之间的值,在检索的时候,CHAR列删除了尾部的空格,而VARCHAR则保留了这些空格,下面的例子通过给表vc中的VARCHAR(4)和char(4)字段插入相同的字符串来描述这个区别、

  

可以发现,c字段的length只有2,给两个字段分别追加一个“+”字符看得更清楚。

显然,CHAR列最后的空格在做操作的时候都已经被删除了,为VARCHAR依然保留了空格。

 (2)BINARY和VARBINARY类型

  BINARY和VARBINARY类似于CHAR和VARCHAR,不同的是它们包含了二进制字符串。举个例子看字符是怎么样存储的。

分别用以下几种模式来查看c列的内容。

可以发现,当保存BINARY值时,在值的最后通过填充“0x00”(零字节)以达到指定的字段定义长度,从上例中看出,对于一个BINARY(3)列,当插入“a”变为“a”

  3:ENUM类型

  ENUM中文名称叫枚举类型,它的取值范围需要在创建表时通过枚举方式显示指定,对1~255个成员的枚举需要1个字节存储,对于255~65535个成员,需要两个字节存储,最多允许有65535个成员,下面往测试表t9插入几条记录来看看ENUM的使用方法。

  

从上面的例子中,可以看出ENUM类型是忽略大小写的,在存储‘M’,‘f’ 时将他们都转成了大写,还可以看出对于插入不在ENUM指定范围内的值时,并没有返回警告,而是插入了enum('M','F')的第一个值‘M’,这点用户在使用时要特别注意。

  另外,ENUM类型只允许从值集合中选取单个值,而不能一次取多个值。

4:SET类型

  SET和ENUM类型非常类似,也是一个字符串对象,里面可以包含0~64个成员,根据成员的不同,存储上也有所不同。

  

SET和ENUM除了存储外,最主要的区别在于SET类型一次可以选取多个成员,而ENUM则只能选一个

SET类型可以从允许的值集合中选择任意1个或多个元素进行组合,所以对于输入的值只要是在允许值的组合范围内,都可以正确地注入到SET类型的列中,对于超出允许值范围的值例如('a,d,f')将不允许注入到上面的例子中设置的SET类型中,而对于('a,d,a')

这样包含重复的成员的集合将只取一次,写入的结果是'a,d'这一点请注意、

 

原文地址:https://www.cnblogs.com/cxq0017/p/6439371.html