MySQL数据类型
- 一、数据类型分类
- 二、详解
一、数据类型分类
| 大类 | 具体类型 | 字节数 | 范围/用途 | 使用场景 |
|---|---|---|---|---|
| 整数类型 | TINYINT(tinyint) | 1 | 0~255(UNSIGNED)或 -128~127 | 状态标识、布尔值(0/1)、小枚举 |
| SMALLINT(smallint) | 2 | 0~65535 或 -32768~32767 | 较小范围数值,如商品库存 | |
| INT(int) | 4 | 0~42.9亿 或 -21亿~21亿 | 主键ID、用户数量、订单号(最常用) | |
| BIGINT(bigint) | 8 | 极大整数 | 超大ID、时间戳(毫秒级)、流水号 | |
| 浮点/定点数 | FLOAT(float) | 4 | 单精度,约7位小数 | 科学计算、不太精确的小数 |
| DOUBLE(double) | 8 | 双精度,约15位小数 | 普通小数计算(比FLOAT更常用) | |
| DECIMAL(M,D)(decimal) | 变长 | 精确小数,M总位数,D小数位 | 金额、价格、财务数据(必用) | |
| 位类型 | BIT(M)(bit) | 根据M位决定 | 1~64 | 简单的开关标志:性别,是否在线,是否通过 |
| 字符串类型 | CHAR(M)(char) | M | 固定长度,最多255字符 | 长度固定的字段:MD5密码、手机号、身份证 |
| VARCHAR(M)(varchar) | 变长 | 可变长度,最多65535字符 | 绝大多数字符串:用户名、标题、地址 | |
| TEXT(text) | 变长 | 最多65535字符 | 长文本:文章内容、留言、产品描述 | |
| LONGTEXT(longtext) | 变长 | 最多4GB | 超长内容:日志、JSON字符串 | |
| 日期时间 | DATE(date) | 3 | '1000-01-01' ~ '9999-12-31' | 生日、入职日期、报表日期 |
| TIME(time) | 3 | '-838:59:59' ~ '838:59:59' | 时间段、时长、营业时间 | |
| DATETIME(datetime) | 8 | '1000-01-01 00:00:00' ~ '9999-12-31 23:59:59' | 常规时间存储:订单时间、创建时间 | |
| TIMESTAMP(timestamp) | 4 | '1970-01-01 00:00:01' UTC ~ '2038-01-19 03:14:07' UTC | 自动更新、时区敏感场景 | |
| String类型 | ENUM(enum) | 1-2 | 在你设置的枚举参数中单项选择其中之一 | 性别 |
| SET(set) | 1-8 | 在你设置的集合参数中选择任意个 | 爱好 |
二、详解
2.1整数类型
整数类型的使用基本上是差不多的,都有[ unsigned ]无符号的设置选项,只是存储范围有区别,所以下面介绍整数类型的使用只介绍其中之一,另外的数据类型的使用也是如此。
tinyint类型
语法:tinyint [unsigned]
tinyint类型在无符号情况下表示 0 ~ 255,有符号情况下表示 -128 ~ 127,演示如下:
在一个数据库中创建表t1:

查看表t1的信息:

插入边界值-128,0,127:

查询表t1中的数据:

尝试插入-129,128:

如上图所示,如果我们向表中插入不合法的数据时,MySQL都是会进行拦截的,不让我们进行对应的操作,所有已经插入到表中的数据就一定是合法的。
所以在mysql中数据类型本身就是一种 "约束",约束这个概念在mysql中是一个非常核心的重要的概念,后面的博客中会详细介绍约束。
2.2浮点数类型
浮点数类型中有三类:float,double,decimal,三者语法上都极为相似,除开decimal必须指定总位数和小数位数,下面将介绍float和decimal,而double和float的唯一区别是double的精确度比float更好。
2.2.1float
语法:float[(M,D)] [unsigned]
M:此浮点数的总位数,包含小数位
D:此浮点数的小数位
unsigned:与整数的不同,浮点数是直接去掉负数的小数表示范围只剩0 ~ 上限
假设一个属性列的数据类型是float(4,2),代表存储范围是 -99.99 ~ 99.99,带有unsigned存储范围则是0 ~ 99.99,MySQL在保存时会进行四舍五入。
演示如下:
创建t2表(id和薪资)并查看t2表的信息:

向t2表中插入边界数据并查询表中内容:

向t2表中插入非法数据:

验证四舍五入并查询表中内容:

观察发现存储99.994时可以存储,说明进行了四舍,而99.995不能存储,五入之后就变成了100.00,成为了非法数据了,同时观察发现,我们存入99时,查询表的内容默认带有两位小数00。
在学习编程语言的时候,我们都知道浮点数是存在精度损失的,在存储大数据浮点数时,会有一定的数据损失,在MySQL中也是如此:
先将salary列修改为float类型,不加位数限制,再插入大数据:

观察到数据损失是非常多的,所以为了减少数据损失,更加精确的保存小数,需要使用到decimal类型。(double类型精度比float类型大,但是仍然存在数据损失的)
2.2.2decimal
语法:decimal(M,D) [unsigned]
M:此浮点数的总位数,包含小数位
D:此浮点数的小数位
unsigned:与整数的不同,浮点数是直接去掉负数的小数表示范围只剩0 ~ 上限
decimal类型和float类型的区别就是decimal类型精度更大。
演示如下:
创建表t3(salary,salary2),并插入数据:

查询表中数据:

观察到decimal类型是把所有小数位精准的存储下来了,float类型最后两位小数由12变为了95,这也变相说明了float类型的小数精度大约在7位左右。
decimal整数最大位数M为65。支持小数最大位数D是30。如果D被省略,默认为0,如果M被省略,默认是10。
2.3位类型
2.3.1bit
语法:bit(M)
M:代表实际位数
最简单的bit类型的使用,查看用户是否是登录状态,可以使用bit(1),0代表没有登录,1代表已登录。
演示如下:
创建表t4(id,登录状态),并查看表结构:

向表中插入数据,并查询数据:

当然可以将二进制比特位在查询时用十进制查询(hex):

插入比特位大于1位的数据时MySQL会拒接插入:

2.4字符串类型
字符串类型主要分为定长类型char和变长类型varchar,定长和变长的定义在使用后面介绍,而text和longtext只是更大的varchar类型而已,所以下面介绍char和varchar。
2.4.1char
语法:char(L)
L:表示可以存储的长度,最大长度值是255
演示如下:
创建表t5,并且向表中插入一定量的合法数据:

char类型的存储逻辑是,你设定多长的存储长度,就相当于开了一个多长的数组,你可以在这个数组里任意使用,但是不能超过最大长度。
所以像电话号码,身份证号等等固定长度的数据就可以使用char类型存储。
2.4.2varchar
语法:varchar(L)
L:表示可以最大存储的长度,最大长度65535个字节
varchar和char唯一的不同就是一个是变长,一个是固长,变长可以理解成为你插入了一个多大字节的字符串,MySQL就给你开辟多少大小的一个数组,不会像char一个那么直接就将大小固定下来,所以像name,地址这类长度变化的数据使用varchar存储最佳。
演示就不演示了,使用和char是保持一致的。
2.5日期时间类型
语法:date
插入时日期形式:'yyyy-mm-dd'
语法:time
插入时时间形式:'HH:ii:ss'
语法:datetime
插入时数据形式:'yyyy-mm-dd HH:ii:ss'
date,time,datetime可以看作是一类,由程序员自己存入的对应日期,时间数据,而timestamp其实就是时间戳,不用程序员自己插入数据,自动存入当前的日期时间,同时若修改刚刚的date,time,datetime中任意数据,timestamp都会自动更新的,由于我们的MySQL版本是8.0以上,所以要实现自动设置时间,插入时更新时间的操作需要自己声明。
补充:在旧版本中时间戳是会自动存入日期时间的,但是从8.0开始,需要程序员自己声明,才会自动存入并更新日期时间数据。
声明语句:timestamp default current_timestamp on update current_timestamp,意思是在插入新记录时,将该字段自动设为当前时间;在更新该记录的任何字段时,该字段也会自动更新为当前时间。
演示如下:
创建表t6(创建时没有声明时间戳),并插入一定量的合法数据:

没有声明时间戳时,tm4的数据默认为NULL,下面声明一下:

一旦声明成功,时间戳直接自动存入当前声明完成的日期时间:

更新时其他数据时也会自动更新日期时间:

2.5枚举集合类型
在MySQL中也支持枚举,集合类型。
2.5.1enum and set
语法:enum('选项1','选项2','选项3',...)
枚举,"单选"类型
语法:set('选项值1','选项值2','选项值3', ...)
集合,"多选"类型
演示如下:
创建表t7:

向表t7中插入数据:

set类型不仅仅可以插入一个数据,可以在集合中选择任意多个插入:

我们不仅可以直接使用枚举或者集合中指定的数据进行插入,使用数字也是可以进行插入的,具体规则如下:
enum:选项从左向右开始以1命名,以此类推。
set:选项使用位图进行描述,
例如上面set中敲代码 --> 00001 --> 1;羽毛球 --> 00010 --> 2;
篮球 --> 00100 --> 4;足球 --> 01000 --> 8;看书 --> 10000 --> 16。
若set需要多选,则将需要的选项位图置为1,再转换成10进制即可,例如全选就是11111 --> 31。
演示如下:

2.5.1enum and set的查询
这个板块是补充的,具体的查询会在后面的博客中介绍。
查询所有性别为男的人物(查询女也是如此):


查询爱好中包含羽毛球的人物信息:
需要使用一个find_in_set函数,功能是sub子串在set集合中是否存在,存在则返回真,配合where可以实现包含某一选项的查询效果。
