在mysql数据库中,数据类型是定义表中列(column)可以存储的数据的类型和格式的关键元素。正确选择和使用数据类型对于数据库的性能、存储效率和数据的完整性至关重要。mysql支持多种数据类型,包括数值类型、日期和时间类型、字符串类型等。下面将详细介绍一些常见的数据类型及其应用。
本篇目标:
认识mysql的多种不同的数据类型。
一.数值类型
1.tinyint类型
在mysql 中 tinyint 占用 1 字节(8 bit)。
- tinyint:范围是 -128~127
tinyint unsigned:范围是 0~255
下面以一个实例来举例:
首先创建一个数据库,并使用它:

然后创建一张表,表中存在一个类型为tinyint的num,如图:

然后我们插入数据,并验证一下超过tinyint的取值范围会咋样?如图:

可以看出,这个mysql的数据范围溢出和编程语言的数据范围溢出是不同的,区别:
- mysql字段更看重数据合法性,越界通常拒绝写入。
- 编程语言变量更接近底层整数运算,无符号数会回绕,有符号数溢出则可能出现未定义行为。
- 数据库需要保证长期保存的数据可靠,所以默认处理通常更加严格。
无符号类型tinyint的演示:

2.int类型
基本信息:
字段名 int
int 占用 4字节(32 bit)。
默认是有符号类型:
num int
取值范围为:−2^31∼2^31−1
也就是:
-2147483648 ~ 2147483647
使用无符号类型:
num int unsigned
取值范围为:
也就是:
0 ~ 4294967295
3.bit类型
基本语法:
字段名 bit(m)
其中:
m表示存储多少个二进制位m的范围为1~64- 不写
m时默认为 bit(1)
例如:
id1 bit(1); id2 bit(8);
bit(m) 取值范围是:0-2^m-1;
| 类型 | 位数 | 数值范围 |
|---|---|---|
bit(1) | 1 | 0~1 |
bit(2) | 2 | 0~3 |
bit(4) | 4 | 0~15 |
bit(8) | 8 | 0~255 |
bit(16) | 16 | 0~65535 |
bit(64) | 64 | 0~2^64-1 |
代码演示:

但是我们可能会发现一个奇怪的现象,这个a在数据库中居然不显示或者显示的是字符?如图:

这是因为bit字段在显示时,可能会按照ascii码对应的值显示,如果我们希望以10进制来查看可以进行一下的操作:

二.小数类型
1.float类型
语法:
float[(m, d)] [unsigned] : m指定显示长度,d指定小数位数,占用空间4个字节
案例:
小数:float(4,2)表示的范围是-99.99 ~ 99.99,mysql在保存值时会进行四舍五入。
操作如图:

其实我们自己操作的时候,会发现例如99.991,99.994都是被四舍五入为99.99的,但是如果是
99.995则会四舍五入为100,明显超出了这个取值范围,如图:

注意:
没有指定总位数和小数位数,那么它使用标准的单精度浮点数,通常占 4 字节。
可表示的非零范围大致为:
负数:-3.402823466e+38 ~ -1.175494351e-38 零: 0 正数: 1.175494351e-38 ~ 3.402823466e+38
不过,范围很大不代表能精确保存这么多位。float 通常只能保证约 6~7位有效数字。
2.decimal类型
基本格式:
decimal(m, d)
其中:
m:总有效位数,包括整数和小数部分d:小数位数- 整数部分最多有
m - d位 m最大为65d最大为30,并且不能大于m
例如:
price decimal(5, 2)
表示:
总共最多5位 小数部分占2位 整数部分最多3位
取值范围为:
-999.99 ~ 999.99
代码实例:

其实,我们会发现这个decimal和float的使用差不多,但是decimal更精确,区别如图:

注意:如果d被省略,默认为0.如果m被省略, 默认是10。所以如果希望小数的精度高,推荐使用decimal
三.字符串类型
1.char类型
基本格式:
char(n)
其中 n 表示最多保存的字符数,不是字节数,范围一般是:0~255
例如:
name char(5)
最多保存5个字符,在 mysql 的 utf8(即 utf8mb3)字符集中,每个字符最多占3字节
不同字符占用的字节数不同:
| 字符 | utf8占用字节 |
|---|---|
英文字母 a | 1字节 |
数字 1 | 1字节 |
常见中文 中 | 3字节 |
| 部分符号 | 2~3字节 |
emoji 😀 | 无法保存 |
例如:
abc → 3字节 中国 → 6字节 abc中国 → 9字节
实例演示:

2.varchar类型
基本格式:
varchar(l): 可变长度字符串,l表示字符长度
其中,n表示最多可以保存的字符数,不是字节数,,最大为65535个字节
例如:
name varchar(20)
表示最多保存20个字符,无论是英文还是中文。
如图:

其实当我们将最大长度修改为65535时,就发现会有问题,如图:

其实我们一直要明白一个问题:l是字符数,而非字节数
关于varchar(len),len到底是多大?这个len值,和表的编码密切相关: varchar字节数可以指定为0到65535之间的值,但是有1 - 3 个字节用于记录数据大小,所以说有效字节数是65532。 当我们的表的编码是utf8时,varchar(n)的参数n最大值是65532/3=21844(因为utf中,一个字符占 用3个字节],如果编码是gbk,varchar(n)的参数n最大是65532/2=32766(因为gbk中,一个字符 占用2字节)。
然后我们将字符数修改为最大,如图:

原因:varchar(21844)的理论最大值,是在utf8mb3下几乎把整行空间全部分给这一个字段计算出来的:21844×3=65532字节
但是你的表中不只有name,还有:
id
假设id是int,它还要占4字节。此外还需要长度信息和null标记:
name最大内容:21844 × 3 = 65532字节 varchar长度信息:约2字节 id字段:4字节 null标记等:至少还需要一些空间
总大小已经超过:
65535字节
因此创建失败。
3.两者区别
varchar的“变长”指:
字段实际占用的空间,会随着存入字符串的长度发生变化。
varchar为什么叫变长字符串?
假设定义:
name varchar(10)
它表示最多保存10个字符,但不会始终占用10个字符的空间。
分别插入:
insert into test values ('abc');
insert into test values ('abcdefgh');大致存储情况为:
abc → 保存3个字符的数据 abcdefgh → 保存8个字符的数据
此外,varchar需要使用1或2字节记录字符串的实际长度:
实际字符串内容 + 长度信息
所以它叫可变长度字符串类型。
char为什么叫定长字符串?
假设定义:
name char(10)
无论实际字符串有多长,字段都按照固定的10字符长度进行处理。
插入:
insert into test values ('abc');逻辑上相当于在后面补充空格:
'abc '
查询时,mysql通常会把末尾补充的空格去掉,所以看到的仍然是:
abc
四.日期和时间类型
1.date类型
date用于保存日期,不保存具体时间。
基本格式:
yyyy-mm-dd
取值范围:
1000-01-01 ~ 9999-12-31
占用空间:
3字节
代码演示:
2.datetime类型
datetime用于保存日期和具体时间。
基本格式:
yyyy-mm-dd hh:mm:ss
取值范围:
1000-01-01 00:00:00 ~ 9999-12-31 23:59:59
基础占用空间:
5字节
3.timestamp类型
timestamp也用于保存日期和具体时间。
基本格式:
yyyy-mm-dd hh:mm:ss
基础占用空间:
4字节
常见取值范围:
1970-01-01 00:00:01 utc ~ 2038-01-19 03:14:07 utc
4.代码演示

可以看出当我们添加数据时,时间戳自动补 上当前时间。
然后,我们更新一下数据,如图:

所以更新数据时,时间戳也会更新成当前时间
五.enum和set
语法:
enum:枚举,“单选”类型;
enum('选项1','选项2','选项3',...);该设定只是提供了若干个选项的值,最终一个单元格中,实际只存储了其中一个值;而且出于效率考 虑,这些值实际存储的是“数字”,因为这些选项的每个选项值依次对应如下数字:1,2,3,....最多65535 个;当我们添加枚举值时,也可以添加对应的数字编号。
set:集合,“多选”类型; set('选项值1','选项值2','选项值3', ...);该设定只是提供了若干个选项的值,最终一个单元格中,设计可存储了其中任意多个值;而且出于效率 考虑,这些值实际存储的是“数字”,因为这些选项的每个选项值依次对应如下数字:1,2,4,8,16,32,.... 最多64个。
实例:

我们也可以使用数字插入,如图:

解释:我们使用数字即下标(从1开始)时,可以看出gender是很好的匹配的,但是为什么hobby时,用5,3的时候会出现其他的hobby呢?说明set类型的集合的数字并不可以当成下标,其实这是位图,一个是0101,一个是0011。
hobby中每个选项对应一个二进制位:
| 爱好 | 二进制位 | 十进制权值 |
|---|---|---|
登山 | 0001 | 1 |
游泳 | 0010 | 2 |
篮球 | 0100 | 4 |
武术 | 1000 | 8 |
有如下数据,想查找所有喜欢登山的人:

使用如下查询语句:

但是我们发现查询这个登山的人时,仅查询了lilei的,但是其他带有登山的去不显示出来,那咋办?
所以我们可以使用集合查询使用find_ in_ set函数: find_in_set(sub,str_list);
规则:如果sub在str_list中,则返回下标;如果不在,返回0; str_list用逗号分隔的字符串。
操作如图:

用find_in_set来查询爱好登山的人:

到此这篇关于mysql数据库原理与实践记录:表的约束的文章就介绍到这了,更多相关mysql表的约束内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论