目录
- [1 ~> 库操作](#1 ~> 库操作)
-
- [1.1 字符集和校验规则](#1.1 字符集和校验规则)
- [1.2 创建数据库](#1.2 创建数据库)
- [1.3 操纵数据库](#1.3 操纵数据库)
- [2 ~> 表操作](#2 ~> 表操作)
-
- [2.1 创建表](#2.1 创建表)
- [2.2 查看表](#2.2 查看表)
- [2.3 修改表](#2.3 修改表)
- [2.4 删除表](#2.4 删除表)
- [3 ~> MySQL 数据类型](#3 ~> MySQL 数据类型)
-
- [3.1 数值类型](#3.1 数值类型)
-
- [3.1.1 整数类型](#3.1.1 整数类型)
- [3.1.2 浮点数类型](#3.1.2 浮点数类型)
- [3.1.3 BIT 类型](#3.1.3 BIT 类型)
- [3.2 字符串类型](#3.2 字符串类型)
-
- [3.2.1 文本字符类型](#3.2.1 文本字符类型)
- [3.2.2 二进制类型:enum & set](#3.2.2 二进制类型:enum & set)
- [3.3 日期和时间类型](#3.3 日期和时间类型)
1 ~> 库操作
1.1 字符集和校验规则
字符集:决定数据在底层的存储和编码方式。
比如使用utf8mb4 字符集:
c
A --> 0x41
中 --> 对应一组 UTF-8 编码
😀 --> 对应一组 UTF-8 编码
MySQL 中默认的字符集为
utf8,可以通过vim /etc/my.cnf在配置文件中查看。
校验规则:两个字符串进行比较的时候,应该按照什么规则比较。
例如:
c
'a' = 'A'
到底是 true 还是 false ? 就由校验规则决定。
MySQL 中默认字符集
utf8对应的校验规则为utf8_general_ci。
- 查看 MySQL 支持的字符集
sql
show charset;
- 查看 MySQL 支持的校验规则
sql
show collation;
- 查看默认字符集和校验规则
sql
# 字符集
show variables like 'character_set_database';
# 校验规则
show variables like 'collation_database';
1.2 创建数据库
语法:
sql
create database [if not exist] db_name;
create database:关键字- :可选项
db_name:数据库名字
此时,采用默认的字符集和校验规则。
- 指定字符集和校验规则
sql
# 指定字符集
charset = charset_name
charset charset_name
character set charset_name
# 指定校验规则
collate collate_name
collate = collate_name
想要指定字符集和校验规则,只需要在创建数据库的时候在后面加上对应的选项。对于每个字符集,MySQL 中都有对应默认的校验规则。
例如指定字符集为utf8mb4:
sql
CREATE DATABASE t1 charset=utf8mb4 collate=utf8mb4_general_ci;
- 查看数据库的字符集和校验规则
sql
show create database db_name;
实验:验证"校验规则"对数据库的影响
- 按照默认字符集与校验规则创建一个数据库
db1:
sql
CREATE DATABASE if not exists db1;
- 在数据库
db1中建表t1:
sql
create table t1(
str varchar(8)
);
- 在
t1中分别插入大小写的字符串:
sql
# 插入 'a'
insert into t1 (str) values ('a');
# 插入 'A'
insert into t1 (str) values ('A');
- 进行查询
sql
select * from t1 where str = 'a';

我们根据 a 查询,同时查到了 a 和 A,即 MySQL 默认的校验规则不区分大小写。
- 指定校验规则为:
utf8_bin
sql
create database db2 charset=utf8 collate=utf8_bin;
- 建表并插入后查询
sql
select * from t1 where str = 'a';

1.3 操纵数据库
(1)查看数据库
sql
show databases;
(2)查看创建语句
sql
show create database db_name;
示例:
sql
mysql> show create database db1;
+----------+--------------------------------------------------------------+
| Database | Create Database |
+----------+--------------------------------------------------------------+
| db1 | CREATE DATABASE `db1` /*!40100 DEFAULT CHARACTER SET utf8 */ |
+----------+--------------------------------------------------------------+
说明:
- MySQL 建议我们关键字使用大写,但是不是必须的。
- 数据库名字的反引号 ``,是为了防止使用的数据库名刚好是关键字。
/*!40100 default.... */这个不是注释,表示当前mysql版本大于4.01版本,就执行这句话。
(3)修改数据库
修改数据库主要是指修改"字符集"和"校验规则"。
语法:
sql
ALTER DATABASE db_name [];
# 修改字符集
charset = charset_name
character set charset_name
# 修改校验规则
collate = collate_name
实例:
sql
mysql> show create database db2;
+----------+--------------------------------------------------------------+
| Database | Create Database |
+----------+--------------------------------------------------------------+
| db2 | CREATE DATABASE `db2` /*!40100 DEFAULT CHARACTER SET utf8 */ |
+----------+--------------------------------------------------------------+
1 row in set (0.00 sec)
mysql> alter database db2 charset = gbk;
Query OK, 1 row affected (0.00 sec)
mysql> show create database db2;
+----------+-------------------------------------------------------------+
| Database | Create Database |
+----------+-------------------------------------------------------------+
| db2 | CREATE DATABASE `db2` /*!40100 DEFAULT CHARACTER SET gbk */ |
+----------+-------------------------------------------------------------+
(4)删除数据库
sql
DROP DATABASE db_name;
注意:删除后其中数据表全部被删,所以删除时应该非常谨慎!!!
(5)备份和还原
- 备份:
sql
mysqldump -P3306 -u root -p密码 -B 数据库名 > 数据库备份存储的文件路径
- 还原
sql
mysql -u root -p school < ./school.sql;
实例:例如有一个数据库 school
备份:
sql
mysqldump -u root -p school > ./school.sql
执行后输入 MySQL 密码,就会生成:school.sql
还原:
sql
# 先创建数据库:
create database school;
# 退出 MySQL,在 Liunx 终端执行:
mysql -u root -p school < school.sql
(6)查看连接情况
sql
show processlist;
实例:
sql
mysql> show processlist;
+----+------+-----------+------+---------+------+----------+------------------+
| Id | User | Host | db | Command | Time | State | Info |
+----+------+-----------+------+---------+------+----------+------------------+
| 10 | root | localhost | db2 | Query | 0 | starting | show processlist |
+----+------+-----------+------+---------+------+----------+------------------+
2 ~> 表操作
2.1 创建表
语法:
sql
CREATE TABLE table_name(
field1 datatype1,
field2 datatype2,
field3 datatype3,
...
)charset 字符集 collate 校验规则 engine 存储引擎;
CREATE TABLE:关键字(不区分大小写)field:表示列名(列名在前类型在后)datatype:列的类型charset:指定字符集collate:指定校验规则engine:指定存储引擎
例如我们描述一个学生:
sql
CREATE TABLE students(
id int,
name varchar(8),
age int unsigned,
gender char(1)
)charset utf8 collate utf8_general_ci engine InnoDB;
2.2 查看表
- 方式一:
sql
desc table_name;
实例:
sql
mysql> desc student;
+--------+------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------+------------------+------+-----+---------+-------+
| id | int(11) | YES | | NULL | |
| name | varchar(8) | YES | | NULL | |
| age | int(10) unsigned | YES | | NULL | |
| gender | char(1) | YES | | NULL | |
+--------+------------------+------+-----+---------+-------+
- 方式二:查看表的创建语句
sql
show create table table_name;
- 方式三(简化方式二的查询结果)
sql
show create table table_name \G
- 查看表中数据
sql
select * from table_name;
2.3 修改表
在项目中,可能经常想要修改表中某个字段的名字,大小,类型,以及字符集和校验规则,存储引擎。
就以上面的 student 为例:
- 插入数据
sql
insert into student (id, name, age, gender) values (1, '张三', 18, '男');
# 默认也是全列插入
insert into student values (2, '李四', 19, '女');
sql
mysql> select * from student;
+------+--------+------+--------+
| id | name | age | gender |
+------+--------+------+--------+
| 1 | 张三 | 18 | 男 |
| 2 | 李四 | 19 | 女 |
+------+--------+------+--------+
- 添加字段:号码
sql
ALTER table student ADD num varchar(12) AFTER gender;
实例:
sql
mysql> ALTER table student ADD num varchar(12);
Query OK, 0 rows affected (0.04 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> desc student;
+--------+------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------+------------------+------+-----+---------+-------+
| id | int(11) | YES | | NULL | |
| name | varchar(8) | YES | | NULL | |
| age | int(10) unsigned | YES | | NULL | |
| gender | char(1) | YES | | NULL | |
| num | varchar(12) | YES | | NULL | |
+--------+------------------+------+-----+---------+-------+
- 修改类型:将 name 长度修改为20
sql
alter table student name varchar(20);
- 修改列名:gender 修改为"性别"
sql
alter table student change gender 性别 char(1);
注意:后面需要带上类型!
- 修改表名为person
sql
alter table student rename person;
注意:轻易不要修改表名,可能会导致业务代码报错。
- 删除一列:年龄
sql
alter table person drop age;
2.4 删除表
sql
DROP table [if exists] table_name;
3 ~> MySQL 数据类型

3.1 数值类型
3.1.1 整数类型
| 类型 | 存储空间 | 有符号取值范围 | 无符号取值范围 |
|---|---|---|---|
| TINYINT | 1字节 | -128~127 | 0~255 |
| SMALLINT | 2字节 | -32768~32767 | 0~65536 |
| MEDIUMINT | 3字节 | -8388608~8388607 | 0~16777215 |
| INT | 4字节 | *** | *** |
| BIGINT | 8字节 | *** | *** |
说明:没有指明 unsigned,默认为有符号整数。
以 tinyint 为例:
当我们在一个定义一个表,表中某个值的类型为 tinyint,如果要插入数据,那么该整数的大小必须在 -128 ~ 127的范围之中(约束),否则就会报错。
即 MySQL 的数据类型决定了你必须插入合法的值,所以,只要是在表中的数据就一定是合法的,符合我们预期的。
实例:
sql
mysql> insert into t2 (id) values (123);
Query OK, 1 row affected (0.00 sec)
# 超过 tinyint范围:报错
mysql> insert into t2 (id) values (128);
ERROR 1264 (22003): Out of range value for column 'id' at row 1
3.1.2 浮点数类型
| 类型 | 存储空间 | 精度 | 语法格式 |
|---|---|---|---|
FLOAT |
4字节 | 单精度浮点数(约7位有效数字) | FLOAT(M, D) |
DOUBLE |
8字节 | 双精度浮点数(约15有效数字) | DOUBLE(M, D) |
DECIMAL |
变长(计算决定) | 高精度定点数 | DECIMAL(M, D) |
(1)单精度浮点数类型:float
语法:
sql
float [(M, D)] [unsigned]
- M:表示指定显示长度
- D:表示小数位数
实例:
sql
create table (id int, score float(4, 2));
sql
mysql> insert into t3 (id, score) values (1, 90.50);
mysql> insert into t3 (id, score) values (1, 90.508);
mysql> insert into t3 (id, score) values (1, 90.504);
mysql> insert into t3 (id, score) values (1, 9.504);
# ---------------------------报错------------------------------------------
mysql> insert into t3 (id, score) values (1, 123.50);
ERROR 1264 (22003): Out of range value for column 'score' at row 1
mysql> select * from t3;
+------+-------+
| id | score |
+------+-------+
| 1 | 90.50 |
| 1 | 90.51 |
| 1 | 90.50 |
| 1 | 9.50 |
+------+-------+
- 整数部分长度不能超过M - D,否则小数部分长度不够,报错。
- 如果小数部分超过 D 位,MySQL float 类型自动进行"四舍五入"处理。
float(4, 2)取值范围:-99.99 ~ 99.99。
(2)高精度定点数类型:decimal
语法:
sql
decimal [(M, D)] [unsigned]
实例:
sql
create table t4(
id int,
salary decimal(12, 8),
salary float(10, 6)
);
sql
mysql> insert into t4 values (2, 1234.123456789, 1234.1234567);
mysql> select * from t4;
+------+---------------+-------------+
| id | salary | salary2 |
+------+---------------+-------------+
| 2 | 1234.12345679 | 1234.123413 |
+------+---------------+-------------+
- 同样,
decimal也会四舍五入。 decimal的精度明显高于float。
当我们需要用高精度表示时,建议选择
decimal!
3.1.3 BIT 类型
MySQL 中的 BIT 类型用于直接存储二进制位(0 和 1)。
语法:
sql
BIT(M)
- M:表示位的个数,取值范围
1 ~ 64。
实例:
sql
create table t5(
id int,
a bit(8)
);
sql
mysql> insert into t5 values (1, 10);
mysql> insert into t5 values (1, b'1010011');
mysql> insert into t5 values (1, 65);
mysql> select * from t5;
+------+------+
| id | a |
+------+------+
| 1 | |
| 1 | S |
| 1 | A |
+------+------+
- 第一个
10没有显示出来,因为 bit 字段在显示时,按照 ASCII 码显示。 bit字段赋值时,可以直接使用 "十进制整数" 或者使用b'数值'(例如b'111')。- 如果某个数据只需要存储
0/1,使用bit可以节省空间。
3.2 字符串类型
3.2.1 文本字符类型
(1)char 类型
语法:
sql
char(L)
- L:可以存储的字符长度 ,单位为字符个数 (而不是字节),最大长度为255。
实例:
sql
create table t6(
id int,
str char(8)
);
sql
mysql> insert into t6 values (1, 'hello');
mysql> insert into t6 values (1, '你吃饭了吗');
mysql> select * from t6;
+------+-----------------+
| id | str |
+------+-----------------+
| 1 | hello |
| 1 | 你吃饭了吗 |
+------+-----------------+
(2)varchar 类型
语法:
sql
varchar(L)
- L:同
char,都表示字符个数,但最大值受编码规则的影响。 - L 最大值:
varchar表示的字符串最大字节数为65535(所占空间)。utf8编码:单个字符所占最大字节为 3 字节,则varchar最大字符个数为65535 / 3 = 21844。
实例:
sql
create table t7(
id int,
str varchar(6)
);
sql
mysql> insert into t7 values (1, 'hello');
mysql> insert into t7 values (2, '我爱你,中国');
mysql> select * from t7;
+------+--------------------+
| id | str |
+------+--------------------+
| 1 | hello |
| 2 | 我爱你,中国 |
+------+--------------------+
(3)char 和 varchar 比较
通过上面的例子,感觉 char 和 varchar 没什么区别!
char(8)和varchar(8)
char(8):所占空间为 单个字符字节数 * 8;
varchar(8):所占空间为当前实际存储的字符串的大小 + 长度前缀,即 varchar 是在不超过自定义范围的情况下,用多大空间开多大空间。
长度前缀 用于存储当前实际存储的字节数。
- size <= 255:前缀占 1字节
- size > 255:前缀占 2 字节
3.2.2 二进制类型:enum & set
enum:枚举,"单选" 类型。
语法:
sql
enum ('选项1', '选项2', '选项3', ...)
set:集合,"多选" 类型。
语法:
sql
set ('选项1', '选项2', '选项3', ...)
对于
enum和set的选项和数组相似,对应下标1、2、3... 。
实例:
sql
mysql> create table votes (
-> name varchar(20),
-> gender enum('男', '女'),
-> hobby set('足球', '羽毛球', '游泳', '登山')
-> );
sql
mysql> insert into votes values ('张三','男','足球,游泳');
mysql> insert into votes values ('李四', 2, '游泳');
mysql> insert into votes values ('王五', 1, 6);
mysql> select * from votes;
+--------+--------+------------------+
| name | gender | hobby |
+--------+--------+------------------+
| 张三 | 男 | 足球,游泳 |
| 李四 | 女 | 游泳 |
| 王五 | 男 | 羽毛球,游泳 |
+--------+--------+------------------+
- 注意:插入时,SET 类型多个选项之间,分隔符是逗号,不能加空格。
- SET 实际就是位图,比特位的 0/1 表示不选该选项还是选。
如果想要查找喜欢游泳的人:
sql
mysql> select * from votes where hobby = '游泳';
+--------+--------+--------+
| name | gender | hobby |
+--------+--------+--------+
| 李四 | 女 | 游泳 |
+--------+--------+--------+
并不能查到所有 hobby 中包含 '游泳' 的人,可以借助 find_in_set。
find_in_set(sub, str_list):如果 sub 在str_list 中返回下标,否则返回 0。
sql
mysql> select * from votes where find_in_set('游泳', hobby);
+--------+--------+------------------+
| name | gender | hobby |
+--------+--------+------------------+
| 张三 | 男 | 足球,游泳 |
| 李四 | 女 | 游泳 |
| 王五 | 男 | 羽毛球,游泳 |
+--------+--------+------------------+
3.3 日期和时间类型
常见的有三种类型:
- date :格式为
yyyy-mm-dd,占 3 字节。例如:2026-8-26。 - datetime :时间日期格式
yyyy-mm-dd HH:ii:ss,占用 8 字节。例如:2026-8-26 17:26:30。 - timestamp :时间戳,格式与
datetime相同,占用 4 字节,但该字段会随时间变化而改变。
实例:
sql
mysql> create table time(
-> t1 date,
-> t2 datatime,
-> t3 timestamp
-> );
# 插入两种时间,时间戳会自动补上
mysql> insert into time (t1, t2) values ('1997-7-1','2008-8-8 12:1:1');
mysql> insert into time (t1, t2) values ('1997-7-1','2008-8-8 12:1:1');
# 两次插入存在时间差。所以,看到时间戳不同
mysql> select * from time;
+------------+---------------------+---------------------+
| t1 | t2 | t3 |
+------------+---------------------+---------------------+
| 1997-07-01 | 2008-08-08 12:01:01 | 2026-08-26 17:33:59 |
| 1997-07-01 | 2008-08-08 12:01:01 | 2026-08-26 17:34:17 |
+------------+---------------------+---------------------+