1.为什么要定义MySQL数据类型
定义MySQL数据类型其实就是为了对数据进行分类,实现对不同的分类进行不同的处理
1、使系统能够根据数据类型来操作数据。
2、预防数据运算时出错。例如,通过强大的数据分类把每个类型不特定的行为联系在一起,执行这些行为时,数据分类可以预防错误。最长见的错误是字符不数字相加。
3、更有效的利用空间。数据分类,可以使用最少的存储,来存放数据,同时提高了性能。 例如,把12345678901234567 识别为一个(8字节)数字,而不是一个17字节的字符串,1个字符占用一个字节。
定义数据类型的本质上是在定义列
2.mysql数据类型分类
mysql的数据类型大致分为:数值,字符串,enum枚举,set集合,时间
2.1 数值类型
bit[(m)]
二进制位,m表示二进制的长度(1-64),默认m=1
tinyint[(m)][unsigned][zerofill]
小整数,数据类型用于保存一些范围内的整数数值范围
有符号:-128~127
无符号:0~255
特别的:MySQL中无布尔值,使用tinyint(1)构造
int[(m)][unsigned][zerofill]
整数,数据类型用于保存一些范围的整数数值范围
有符号:-2147483648~2147483647(2的31次方)
无符号:0~4294967295(2的32次方)
特别的:整数类型中的m仅用于显示,对存储范围无限制
例如:int(5),表示插入数据时,数据的长度为5位
bigint[(m)][unsigned][zerofill]
大整数,数据类型用于保存一些范围的整数数值范围
有符号:-2**63 ~ 2**63
无符号:0~2**64
decimal[(m[,d])][unsigned][zerofill]
准确的小数值,m是数字的个数,d是小数点后个数,m最大值为65,d最大值为30.
特别的:
对于精确数值计算时需要用此类型
decimal能够存储精确值的原因在于其内部按照字符串存储
用来存储精确的小数,消耗空间,运算慢,一般想办法使用bigint替代它
float[(m,d)][unsigned][zerofill]
单精度浮点数(非准确小数值),m是数字总个数,d是小数点后个数
无符号:
-3.402823466E+38 to -1.175494351E-38
0
1.175494351E-38 to 3.02823466E+38
有符号:
0
1.175494351E-38 to 3.402823466E+38
需要注意的是,数值越大,表示的数值越不准确
double[(m,d)][unsigned][serofill]
双精度浮点数(非准确小数值),m是数字总个数,d是小数点后个数
数值越大,越不准确
在MySQL中支持的5个主要整数类型是TINYINT,SMALLINT,MEDIUMINT,INT和BIGINT。
这些类型在很大程度是相同的,只有他们存储的值的大小是不同的
整型属性<修饰符>:
unsigned 无符号整数,修饰符: 规定字段只能保存正的数据。它可以增大这个字段的正数支持的范围。
比如:tinyint unsigned 可以存储的范围是0-255,而tinyint的存储范围是-128-127
zerofill 修饰符: 规定0(不是空格 ) 填补输出的值。 使用这个值可以防止 mysql存储负值。
2.2 字符串:
char(m)
char表示固定长度的字符串,可以包含最多达255个字符,其中m代表字符串的长度
即使数据小于m长度,存储后也会占用m长度
varchar(m)
varchar用于变长的字符串,可以包含最多255个字符,其中m代表该数据类型所允许保存的字符串的最大长度
只要长度小于该最大值的字符串都可以被保存在该数据类型中
需要注意的是,虽然varchar使用起来较为灵活,但是从整个系统的性能角度来说,char数据类型的处理速度比varchar类型更快
text
text数据类型用于保存变长的大字符串,可以组到65535(2**16-1)个字符
text类型及其子类型用于存储比较长的非二进制字符串
可以把text类型理解为VARCHAR的加长增强版
text类型不区分大小写
mediumtext
mediumtext类型数据也是用来保存变长的大字符串,最长可以表示
(2**24-1)个字符
longtext
longtext数据类型也是用来保存变长的大字符串,最长可以表示(2**32-1)个字符
字符串类型修饰符:
binary 修饰符: 区分字符大小。比较char类型以一个二进制方式起作用。
char和varchar区别:
-
空间:char(m)定义的列的长度为固定的,m取值可以为0~255之间,当保存char值时,在它们的右边填充空格以达到指定的长度。当检索到char值时,尾部的空格被删除掉。
varchar(m)定义的列的长度为可变长字符串,m取值可以为0~65535之间,(varchar的最大有效长度由最大行大小和使用的字符集确定。整体最大长度是65,532字节)。
varchar值保存时只保存需要的字符数,另加一个字节来记录长度(如果列声明的长度超过255,则使用两个字节)。varchar值保存时不进行填充。当值保存和检索时尾部的空格仍保留,符合标准SQL。
例:
varchar(10),实际长度是它的值的实际长度+1。为什么"+1"呢?这一个字节用于保存实际使用了多大的长度。如果列声明的长度超过255,则使用两个字节。 从效率上考虑,用char合适。
-
对于不同存储引擎有不同的说法:
对于MyISAM表,尽量使用Char,对于那些经常需要修改而容易形成碎片的myisam和isam数据表就更是如此,它的缺点就是占用磁盘空间;对于InnoDB表,因为它的数据行内部存储格式对固定长度的数据行和可变长度的数据行不加区分(所有数据行共用一个表头部分,这个表头部分存放着指向各有关数据列的指针),所以使用char类型不见得会比使用varchar类型好。事实上,因为char类型通常要比varchar类型占用更多的空间,所以从减少空间占用量和减少磁盘i/o的角度,使用varchar类型反而更有利.
2.3 enum
枚举类型,其最大可以包含65535个不重复的成员,但是实际被限制小于3000个成员
enum类型存储的数据好比是单项选择题里的选项。其存储的值为表创建时在列规定中枚举的一列值,只能取一个,用于互斥。
2.4 set
集合类型,其最大可以包含64个不重复的成员,能选取多个
在set中,相关的元素不能同时存在。
2.5 时间类型:
date
YYYY-MM-DD,支持的范围是从 '1000-01-01' 到 '9999-12-31'
例如:2017-07-24
time
HH:MM:SS
例如:14:35:33
year
YYYY,1970 Unix诞生。这一年称为: 计算机元年
例如:2017
datetime
YYYY-MM-DD HH:MM:SS
例如:2017-07-25 15:55:22
timestamp
YYYYMMDD HHMMSS
例如:20170725 15:55:20
datetime类型与timestamp类型的区别
datetime类型能保存大范围的值,从1001年到9999年,精度为秒,它把日期和时间封装到格式为`YYYY-MM-DD HH:MM:SS`的整数中,与时区无关,使用8个字节的存储空间
timestamp类型保存了从1970年1月1日午夜(格林尼治时间) 以来的秒数
它和linux时间戳相同,timestamp只使用了4个字节的存储空间,因此它的范围比datetime小的多,只能表示从1970-2038,通常我们还是用它的,提高空间利用率
如果要查询时间戳SELECT unix_timestamp('1999-11-12 23:23:45');
3.扩展:linux时间戳
[root@mysql ~]# date +%s // 显示系统当前时间戳
1535272562
[root@mysql ~]# date -d "2017-10-06 17:48:23" +%s // 把指定时间转换为时间戳
1507326503
[root@mysql ~]# date -d "1970-01-01 08:00:00" +%s // 把指定时间转换为时间戳
46800
[root@mysql ~]# date -d"@1455455465" // 把时间戳转换为日期
Sun Feb 14 08:11:05 EST 2016
[root@mysql ~]# date -d"@1455455465" "+%Y/%m/%d %H:%M:%S" // 把时间戳转换为日期
2016/02/14 08:11:05
[root@mysql ~]# date -d"@1455455465" "+%Y-%m-%d %H:%M:%S" // 把时间戳转换为日期
2016-02-14 08:11:05