文章目录
- 数据类型分类
- 数值类型
- 文本、二进制类型
- 日期和时间类型
- String 类型
数据类型分类
MySQL 支持多种数据类型,大致可分为数值类型,文本、二进制类型,时间日期,String类型。
数值类型
类型 | 字节 | 有符号范围 | 无符号范围 |
---|---|---|---|
TINYINT | 1 | -128~127 | 0~255 |
SMALLINT | 2 | -32,768~32,767 | 0~65,535 |
MEDIUMINT | 3 | -8,388,608~8,388,607 | 0~16,777,215 |
INT | 4 | -2,147,483,648~2,147,483,647 | 0~4,294,967,295 |
BIGINT | 8 | -9,223,372,036,854,775,808~9,223,372,036,854,775,807 | 0~18,446,744,073,709,551,615 |
以TINYINT为例:
创建一个表 t1,其中包含一个有符号 TINYINT 类型的 num 列
create table t1(
num tinyint
);
创建一个表 t2,其中包含一个无符号 TINYINT 类型的 num 列
create table t2(
num tinyint unsigned
);
如果插入的数据超范围了,会报错:
BIT类型:
BIT 是一种位数据类型,用于存储比特值(即 0 或 1)。BIT 数据类型在存储和检索单独的位序列时非常有用。它支持 BIT(M) 的形式,其中 M 指定要存储的位数。例如,BIT(1) 数据类型可以存储单个比特,而 BIT(8) 数据类型可以存储 8 个比特的位序列。BIT 类型还可以用于存储 IP 地址和网络地址等。
例1:
创建一个表,其中包含一个bit(8)类型的字段a
10,255这样的数都可以插入,超过255的就不允许了
检索数据,发现显示有误
这是因为bit类型是以 ASCII 字符形式显示,10和255对应的都是特殊字符。
例2:
如果你想存储一个二进制位的状态(例如是否已经完成某个任务),你可以使用bit类型来节省存储空间。例如,一个8位bit类型的列可以存储8个不同的状态,而需要一个tinyint类型的列来存储相同的8个状态需要更多的存储空间。同时,使用bit类型可以更方便地进行位运算操作,例如检查某一位是否为1。
float类型
例:
float(4,2)
表示的范围是 -99.99~99.99,MySQL 在保存值时会进行四舍五入。
下面创建一个包含字段类型 float(4,2)
的表。
我们发现,99.99、99.994 都可以正常插入,插入后显示的值都是99.99,因为99.994四舍五入后也是99.99,而99.995无法插入,因为它四舍五入后是100.00,位数超过4。
文本、二进制类型
char类型
固定长度字符串
char(size)
size 表示字符个数,一个汉字也算一个字符。
varchar类型
说明:
关于 varchar(len)
,len
到底是多大,这个 len 值和表的编码密切相关:
- varchar 长度可以指定为 0~65535 之间的值,但是有 1~3 个字节用于记录数据大小,所以有效字节数是 65532.
- 当我们的表的编码是 utf8 时,varchar 的参数 n 最大值是 65532/3=21844(因为 utf8 中,一个字符占 3 个字节),如果编码是 gbk,varchar(n) 的参数 n 最大是 65532/2= 32766(因为 gbk 中,一个字符占 2 个字节)。
例如,这里默认是 utf8 编码,要创建长度 21845 的 varchar 是不行的。
char 和 varchar 的区别
- 存储方式不同:
varchar
存储可变长度的字符串,只占用必要的存储空间;而char
存储固定长度的字符串,占用固定的存储空间,无论实际存储内容的长度是多少。 - 查询性能不同:由于
char
存储的字符串长度固定,所以在进行查询时,查询性能更高;而varchar
在存储可变长度字符串时,由于要计算每行数据的实际长度,因此在查询时会比char
略慢一些。 - 默认长度不同:对于
char
类型,如果在创建表时没有指定长度,MySQL 默认长度为1;而对于varchar
类型,如果在创建表时没有指定长度,MySQL 默认长度为255。
char(m)
中的m
表示固定长度的字符数,如果存储的字符串不足 m 长度,会用空格字符进行填充,占用空间为 m 个字符的存储空间varchar(m)
中的m
表示可变长度的字符数,即最多能存储多少个字符,如果存储的字符串长度小于等于 m,只会占用实际存储的长度空间,而不会占用 m 个字符的存储空间。
总的来说,如果存储的字符串长度固定,且数据表中的字段经常被用于查询,那么可以使用 char
类型;如果存储的字符串长度可变,或者数据表中的字段不经常用于查询,那么可以使用 varchar
类型。
日期和时间类型
date
:日期,格式yyyy-mm-dd
,占用 3 字节datetime
:日期时间,格式yyyy-mm-dd HH:ii:ss
表示范围从 1000 到 9999,占用 8 字节timestamp
:时间戳,占用 4 字节
例:
创建一个表,包含 3 个字段,分别为 date
datetime
timestamp
类型。
我们发现,timestamp 的 Default 是 CURRENT_TIMESTAMP
,Extra 是 on update CURRENT_TIMESTAMP
-
CURRENT_TIMESTAMP
是MySQL中的一个函数,用于返回当前的时间戳(即当前日期和时间)。它可以用于创建表的时候指定一个默认值,也可以用于更新表的时候赋值。 -
on update CURRENT_TIMESTAMP
是在一个DATETIME
或TIMESTAMP
类型的字段上定义的属性,用于在这个字段所在的行被更新时,自动将该字段的值设置为当前时间戳。它可以用于确保每次更新这个行时,该字段都会被更新为当前时间戳。这个属性只能用于DATETIME
或TIMESTAMP
类型的字段。
所以我们插入数据的时候,不需要指定 timestamp 类型的列的值。
String 类型
enum 和 set 的区别就是,enum 是单选,set 是多选。
语法:
-- enum
enum('选项1','选项2','选项3',...);
-- set
set('选项1','选项2','选项3',...);
在 MySQL 中,ENUM 和 SET 类型的字段实际上是整数类型的字段,只不过这些整数是对应特定的字符串值的。对于 ENUM 类型,每个字符串值都对应一个整数值,整数值的范围是 1 1 1 到 N N N,其中 N N N 是 ENUM 中字符串值的数量;对于 SET 类型,每个字符串值也都对应一个整数值,但整数值是一个二进制位标志,范围是 0 0 0 到 2 N − 1 2^N-1 2N−1,其中 N N N 是 SET 中字符串值的数量,选项从左到右代表二进制位从低位到高位。
例:
创建一个名为 t1 的表,包含三个字段:id、gender 和 hobbies,gender 字段的取值只能是 ‘male’ 或 ‘female’,hobbies 字段的取值可以是 ‘reading’、‘music’、‘sports’ 中的任意组合,例如 ‘reading,music’、‘sports’、‘reading,music,sports’ 等。
CREATE TABLE t1 (
id INT,
gender ENUM('male', 'female'),
hobbies SET('reading', 'music', 'sports')
);
向表中插入信息:
INSERT INTO t1 (id, gender, hobbies) VALUES
(1, 'male', 'reading,music'),
(2, 'female', 'music,sports'),
(3, 'male', 'reading,sports');
genter 和 hobbies 字段也可以使用数字来插入
INSERT INTO t1 (id, gender, hobbies) VALUES
(4, 2, 7), -- 'female', 'reading,music,sports'
(5, 1, 1), -- 'male', 'reading'
(6, 2, 2); -- 'female', 'music'
插入结果:
MariaDB [test_db]> select * from t1;
+------+--------+----------------------+
| id | gender | hobbies |
+------+--------+----------------------+
| 1 | male | reading,music |
| 2 | female | music,sports |
| 3 | male | reading,sports |
| 4 | female | reading,music,sports |
| 5 | male | reading |
| 6 | female | music |
+------+--------+----------------------+
6 rows in set (0.00 sec)
我们可以使用数字或选项筛选 gender 为 male 的信息
MariaDB [test_db]> select * from t1 where gender='male';
+------+--------+----------------+
| id | gender | hobbies |
+------+--------+----------------+
| 1 | male | reading,music |
| 3 | male | reading,sports |
| 5 | male | reading |
+------+--------+----------------+
3 rows in set (0.00 sec)
MariaDB [test_db]> select * from t1 where gender=1;
+------+--------+----------------+
| id | gender | hobbies |
+------+--------+----------------+
| 1 | male | reading,music |
| 3 | male | reading,sports |
| 5 | male | reading |
+------+--------+----------------+
3 rows in set (0.00 sec)
我们也可以使用 were 对 hobbies 进行筛选
MariaDB [test_db]> select * from t1 where hobbies='music';
+------+--------+---------+
| id | gender | hobbies |
+------+--------+---------+
| 6 | female | music |
+------+--------+---------+
1 row in set (0.00 sec)
由于 =
是严格匹配,所以筛选出的是“hobbies 仅为 ‘music’ 的信息”。
要筛选出所有包含 ‘music’ 的信息,需要用到函数
集合查询使用 find_in_set 函数:
语法:
FIND_IN_SET(str, strlist)
str
是要查找的字符串
strlist
是逗号分隔的字符串列表。
返回 str
在 strlist
中的位置(下标从 1 开始),如果 str
不在 strlist
中,则返回 0
例如,以下查询返回值为2,因为"apple"在字符串列表"orange,apple,banana"中的第二个位置:
SELECT FIND_IN_SET('apple', 'orange,apple,banana');
注意:FIND_IN_SET()
函数区分大小写。如果在不区分大小写的情况下查找字符串,则应使用LOWER()
或UPPER()
函数将查询字符串和列表字符串都转换为相同的大小写格式,以避免大小写造成的误匹配。
例:
查询 hobbies 有 music 的人: