一.库的操作
在MySQL里操作数据库,本质上就是在管理文件系统上的目录和文件。理解了这一点,后面很多行为就都说得通了。
1.1 创建数据库
创建数据库:
create database db_name;本质就是在/var/lib/mysql创建一个目录。
CREATE DATABASE [IF NOT EXISTS] db_name [create_specification [,create_specification] ...] create_specification: [DEFAULT] CHARACTER SET charset_name [DEFAULT] COLLATE collation_name
说明:
- 大写的表示关键字
- [] 是可选项
- CHARACTER SET: 指定数据库采用的字符集
- COLLATE: 指定数据库字符集的校验规则
创建数据库案例的指令
创建名为 db1 的数据库:
create database db1;当不指定字符集和校验规则时,系统使用默认字符集 utf8,校验规则是 utf8_general_ci。
创建一个使用 utf8 字符集的 db2 数据库:
create database db2 charset=utf8;创建一个使用 utf8 字符集并带校对规则的 db3 数据库:
create database db3 charset=utf8 collate utf8_general_ci;
最初创建的例子

1.2 删除数据库
DROP DATABASE [IF EXISTS] db_ name;
执行删除之后的结果:
数据库内部看不到对应的数据库
对应的数据库文件夹被删除,级联删除,里面的数据表全部被删
注意:不要随意删除数据库

1.3 认识 MySQL 的编码
创建数据库时,有两个编码集:
数据库编码集 —— 数据库未来存储数据
数据库校验集 —— 支持数据库进行字段比较使用的编码,本质也是一种读取数据库中数据所采用的编码格式
数据库无论对数据做任何操作,都必须保证操作和编码是一致的。
1.3.1 字符集和校验规则
查看系统默认字符集以及校验规则
show variables like 'character_set_database'; show variables like 'collation_database';

collation_connection | 当前连接使用的校验规则 |
collation_database | 当前数据库的默认校验规则 |
collation_server | 服务器级别的默认校验规则 |
utf8mb4_0900_ai_ci的含义:
utf8mb4:编码集(支持完整Unicode,包括emoji)
0900:基于Unicode 9.0标准
ai:口音不敏感(accent insensitive)
ci:大小写不敏感(case insensitive)
show variables like 'collation_database';– 查看当前数据库的校验规则。show variables like 'collation_%';– 查看所有以collation开头的系统变量,其中%是通配符,会显示连接、数据库、服务器等各级别的校验规则。
1.3.2 查看数据库支持的字符集
show charset;
字符集主要控制用什么语言。比如 utf8 就可以使用中文。

1.3.3 查看数据库支持的字符集校验规则
show collation;

1.4 创建数据库时的编码设置
1. 默认创建(不指定编码)
create database d1;
当不指定字符集和校验规则时:
系统使用默认字符集:
utf8校验规则是:
utf8_general_ci
在 Linux 底层,MySQL 会在 /var/lib/mysql/ 目录下创建对应的数据库文件夹,里面会生成一个 db.opt 文件记录编码信息。
CentOS 7
[root@VM-8-5-centos mysql]# cat d1/db.opt default-character-set=utf8 default-collation=utf8_general_ci
2. 指定字符集创建数据库
create database d2 charset=utf8; create database d3 charset=utf8;
两种写法效果相同。查看底层文件:
[root@VM-0-3-centos mysql]# cat d2/db.opt default-character-set=utf8 default-collation=utf8_general_ci
3. 指定字符集和校验规则创建数据库
create database d4 charset=utf8 collate utf8_general_ci;
4. 使用 GBK 字符集创建数据库
create database d5 charset=gbk collate gbk_chinese_ci;
查看 GBK 编码的数据库配置:
[root@VM-0-3-centos mysql]# cat d5/db.opt default-character-set=gbk default-collation=gbk_chinese_ci
Ubuntu 22.04



Ubuntu 22.04 不能进行 cat 操作,所以选用 MySQL 操作来查看。

MySQL 数据库 db.opt 文件缺失问题排查(CentOS 7 vs Ubuntu 22.04)
问题背景
在 Ubuntu 22.04 中执行
CREATE DATABASE d1;后,想查看/var/lib/mysql/d1/db.opt文件确认字符集和校验规则,发现:
- MySQL 中
SHOW DATABASES能看到 d1,且数据库正常可用- Bash 中
/var/lib/mysql/下存在 d1 目录,但目录内没有 db.opt 文件- 修改目录权限也无法解决,而 CentOS 7 中可正常看到该文件
环境差异说明
环境 MySQL版本 系统特性 db.opt 文件表现 CentOS 7 MySQL 5.7 传统发行版,数据目录权限严格 创建数据库后自动生成 db.opt Ubuntu 22.04 MySQL 5.7(或8.0+) Debian系发行版,默认配置有差异 可能出现 db.opt 未生成的情况 补充:MySQL 8.0+ 彻底取消了 db.opt 文件,字符集配置统一存储在系统表 mysql.schemata 中,这是 Ubuntu 22.04 默认安装 MySQL 8.0 时的常见情况。
原因分析
核心原因:db.opt 是 MySQL 5.7 及之前版本创建数据库时自动生成的物理文件,用于记录该数据库的默认字符集和校验规则。CentOS 7 中的 MySQL 5.7 安装完整,会正常生成该文件;Ubuntu 22.04 可能因安装配置差异、权限初始化问题或创建时异常中断导致 db.opt 未生成。缺失该文件不影响数据库正常使用,因为 SHOW DATABASES 从系统表读取数据。
解决方案
方案1:用SQL命令直接查看字符集(无需依赖 db.opt)
这是最稳妥、跨版本通用的方法,无论是否有 db.opt 都能生效。
SHOW CREATE DATABASE d1;

方案2:手动创建 db.opt 文件(MySQL 5.7 适用)
如果需要恢复 db.opt 文件,可以手动创建并配置权限:
# 进入d1数据库目录 cd /var/lib/mysql/d1 # 写入字符集配置 echo "default-character-set=utf8" > db.opt echo "default-collation=utf8_general_ci" >> db.opt # 修正文件权限(必须为mysql:mysql,否则MySQL无法读取) chown mysql:mysql db.opt chmod 660 db.opt # 重启MySQL服务生效 systemctl restart mysql
方案3:重建数据库(适合有数据备份的情况)
# 1. 备份d1数据库数据 mysqldump -u root -p d1 > d1_backup.sql # 2. 登录MySQL删除d1 mysql -u root -p DROP DATABASE d1; # 3. 重新创建d1(指定字符集,确保生成db.opt) CREATE DATABASE d1 CHARACTER SET utf8 COLLATE utf8_general_ci; # 4. 恢复数据 mysql -u root -p d1 < d1_backup.sql
总结:
1. 版本差异:MySQL 8.0+ 不再生成 db.opt,字符集查看请用
SHOW CREATE DATABASE2. 环境差异:CentOS 和 Ubuntu 的 MySQL 安装配置不同,可能导致 db.opt 生成异常
3. 最佳实践:优先使用 SQL 命令查看字符集,避免依赖物理文件;db.opt 缺失不影响数据库正常使用
4. 解决思路:先确认数据库逻辑存在 → 再查物理目录 → 最后针对性解决
1.5 校验规则对数据库的影响
- 不区分大小写
创建一个数据库,校验规则使用 utf8_general_ci(不区分大小写):
create database test1 collate utf8_general_ci;
use test1;
create table person(name varchar(20));
insert into person values('a');
insert into person values('A');
insert into person values('b');
insert into person values('B');


不区分大小写的查询以及结果:
mysql> use test1; mysql> select * from person where name='a';

- 插入数据并查询数据


- 结果排序
不区分大小写排序以及结果:
mysql> use test1; mysql> select * from person order by name;

select是从表里查询数据,通配符*代表将表里的所有列数据都显示出来。插入的本质是存储数据,采用
default-character-set=utf8,即插入数据时所用的编码格式。查询的本质是按照校验集的要求来查找和比较数据。具体来说:
插入数据时:使用编码集将数据编码后存入磁盘
查询数据时:使用校验集的规则来比较字段(如
where条件、order by排序、group by分组等)两者必须匹配:如果插入时用的编码集和查询时用的校验集不兼容,就会导致比较结果出错,甚至查不到本该存在的数据。
- 区分大小写
创建一个数据库,校验规则使用 utf8_bin(区分大小写):
create database test2 collate utf8_bin;
use test2
create table person(name varchar(20));
insert into person values('a');
insert into person values('A');
insert into person values('b');
insert into person values('B');
- 进行查询
区分大小写的查询以及结果:
mysql> use test2; mysql> select * from person where name='a';

- 结果排序
区分大小写排序以及结果:
mysql> use test2; mysql> select * from person order by name;

注意:这里一般默认是升序排序。
1.6 数据库的删改查
数据库删除
DROP DATABASE [IF EXISTS] db_ name;


执行删除之后的结果:
数据库内部看不到对应的数据库
对应的数据库文件夹被删除,级联删除,里面的数据表全部被删
注意:不要随意删除数据库
显示创建语句
show create database 数据库名;

说明:
MySQL 建议关键字使用大写,但非必须。
数据库名字的反引号
``是为了防止使用的数据库名刚好是关键字。有些低版本会出现
/*!40100 default.... */,这不是注释,表示当前 MySQL 版本大于 4.01 版本就执行这句话。
修改数据库
ALTER DATABASE db_name [alter_spacification [,alter_spacification]...] alter_spacification: [DEFAULT] CHARACTER SET charset_name [DEFAULT] COLLATE collation_name
将 test2 数据库字符集改成 gbk:
在 CentOS 5.7 下运行(可以用 cat 查到):
mysql> alter database test2 charset=gbk collate gbk_chinese_ci; Query OK, 1 row affected (0.00 sec)
[root@VM-0-3-centos mysql]# cat test2/db.opt default-character-set=utf8 default-collation=utf8_bin [root@VM-0-3-centos mysql]# cat test2/db.opt default-character-set=gbk default-collation=gbk_chinese_ci
Ubuntu 22.04 直接在 MySQL 上查询:
-- 查看当前数据库的字符集和校验规则 show variables like 'character_set_database'; show variables like 'collation_database'; -- 或者查看数据库的创建语句(会显示编码信息) show create database test2;

说明:对数据库的修改主要指的是修改数据库的字符集、校验规则。
查看数据库
show databases;

查询当前所在数据库:
select database();

1.7 数据库备份和恢复
1. 备份
语法:
# mysqldump -P3306 -u root -p 密码 -B 数据库名 > 数据库备份存储的文件路径;
# -P 端口号(大写P,默认3306可省略) # -p 密码(小写p,直接跟密码,中间没有空格) mysqldump -P3306 -u root -p123456 -B test1 > test1.sql # 更安全的做法(避免密码暴露): mysqldump -P3306 -u root -p -B test1 > D:/test1.sql # 然后系统会提示:Enter password: 你输入密码(不显示)
将 test1 进行备份:


这个文件实际上就是把数据库相关的所有数据以及表等放到这个文件中,也可以称为物理文件。
2. 还原
语法:
mysql> source /root/MySQL/test1.sql

如果直接输入指令显示文件不存在,可以先检查文件路径。恢复时需确保没有数据库占用冲突,否则
source可能会报错或跳过。
两种恢复方式的区别
情况一:备份时带了 -B
mysqldump -u root -p -B test1 > test1.sql;
恢复时直接:
source /root/MySQL/mytest.sql;
不需要先建库、不需要 use,因为文件里已经有 CREATE DATABASE 和 USE 语句。
情况二:备份时没带 -B
mysqldump -u root -p test1 > test1.sql;
恢复时必须先手动创建数据库:
create database mytest; use mytest; source /root/MySQL/mytest.sql;
如果直接 source 而没有先建库和 use,就会出问题。
3. 注意事项
如果备份的不是整个数据库,而是其中的一张表,怎么做?
mysqldump -u root -p 数据库名 表名1 表名2 > test1.sql;
同时备份多个数据库
mysqldump -u root -p -B 数据库名1 数据库名2 ... > 数据库存放路径;
如果备份一个数据库时没有带上
-B参数,恢复时需先创建空数据库,然后使用该数据库,再使用source还原。
4. 查看连接情况
语法:
show processlist;

| 列名 | 含义 | 示例中的具体值解读 |
|---|---|---|
| Id | 连接的线程ID,唯一标识一个客户端连接 | 5、23、27 |
| User | 连接所用的用户名 | event_scheduler(系统内部事件调度器)、root(你的管理员账户) |
| Host | 客户端连接来源 | localhost 本机连接;localhost:57982 本机的某个端口 |
| Db | 当前连接正在使用的数据库(如果已选中) | test1 正在使用 test1 库;NULL 没有选中任何库 |
| Command | 当前连接正在执行的命令类型 | Daemon(后台守护进程)、Sleep(空闲)、Query(正在执行查询) |
| Time | 当前状态持续的时间(秒) | 5 秒、5545 秒(约1.5小时)、0 秒 |
| State | 线程当前的状态 | Waiting on empty queue(等待任务)、NULL、init(初始化) |
| Info | 正在执行的SQL语句(如果Command是Query) | show processlist 就是你刚执行的这条命令 |
二. 表的操作
数据库创建完之后,接下来就是操作表了。表是实际存放数据的地方,掌握创建、查看、修改和删除表的操作,是日常开发的基础。
2.1 创建表
语法:
CREATE TABLE table_name ( field1 datatype, field2 datatype, field3 datatype ) character set 字符集 collate 校验规则 engine 存储引擎;
说明:
field 表示列名
datatype 表示列的类型
character set 字符集,如未指定则以所在数据库的字符集为准
collate 校验规则,如未指定则以所在数据库的校验规则为准

说明:不同的存储引擎,创建表的文件不一样。
users 表存储引擎是 MyISAM,在数据目录中有三个不同的文件:
- users.frm:表结构
- users.MYD:表数据
- users.MYI:表索引
示例(MySQL 5.7)
(1) user1 表存储引擎是 MyISAM
在数据目录中有三个不同的文件:
[root@VM-0-3-centos user_db]# ll total 128 -rw-r--r-- 1 mysql mysql 61 May 19 9:00 db.opt -rw-r--r-- 1 mysql mysql 8645 May 19 9:02 user1.frm -rw-r--r-- 1 mysql mysql 0 May 19 9:02 user1.MYD -rw-r--r-- 1 mysql mysql 1024 May 19 9:02 user1.MYI
user1.frm:表结构user1.MYD:表数据user1.MYI:表索引
(2) user2 表存储引擎是 InnoDB
在数据目录中有两个不同的文件:
[root@VM-0-3-centos user_db]# ll total 128 -rw-r--r-- 1 mysql mysql 61 May 19 9:00 db.opt -rw-r--r-- 1 mysql mysql 8645 May 19 9:02 user1.frm -rw-r--r-- 1 mysql mysql 0 May 19 9:02 user1.MYD -rw-r--r-- 1 mysql mysql 1024 May 19 9:02 user1.MYI -rw-r--r-- 1 mysql mysql 8645 May 19 9:02 user2.frm -rw-r--r-- 1 mysql mysql 98304 May 19 9:02 user2.ibd
user2.frm:表结构user2.ibd:表数据和索引
创建 user3 表(默认存储引擎)
mysql> create table if not exists user3(name char(32)); Query OK, 0 rows affected (0.02 sec)
查看文件:
[root@VM-0-3-centos user_db]# ll total 236 -rw-r--r-- 1 mysql mysql 61 May 19 9:02 db.opt -rw-r--r-- 1 mysql mysql 8645 May 19 9:02 user1.frm -rw-r--r-- 1 mysql mysql 0 May 19 9:02 user1.MYD -rw-r--r-- 1 mysql mysql 1024 May 19 9:02 user1.MYI -rw-r--r-- 1 mysql mysql 8645 May 19 9:02 user2.frm -rw-r--r-- 1 mysql mysql 98304 May 19 9:02 user2.ibd -rw-r--r-- 1 mysql mysql 8560 May 19 9:03 user3.frm -rw-r--r-- 1 mysql mysql 98304 May 19 9:03 user3.ibd
表默认的存储引擎是 InnoDB。
Ubuntu 环境

Ubuntu 输出可以看到:
user1表同时存在user1.MYD、user1.MYI和user1_369.sdi文件user2表只有user2.ibd文件
这说明:在 MySQL 8.0 中,即使指定 engine=MyISAM 创建表,它依然会生成一个 .sdi 文件(替代旧版的 .frm),同时也会生成 .MYD 和 .MYI 文件。但默认存储引擎是 InnoDB,所以不指定引擎时创建的表(如 user3、person)只会生成 .ibd 文件。
实际看到的文件对应关系
| 表名 | 存储引擎 | 生成的文件 |
|---|---|---|
| user1 | MyISAM | user1.MYD + user1.MYI + user1_369.sdi |
| user2 | InnoDB | user2.ibd |
| person | InnoDB(默认) | person.ibd |
为什么 user1 没有 .frm 而是 .sdi?
Ubuntu 装的是 MySQL 8.0,而笔记里的 CentOS 是 MySQL 5.7。
- MySQL 5.7 及之前:表结构存在
.frm文件- MySQL 8.0:表结构存在数据字典中,同时导出为
.sdi(序列化字典信息)文件所以找不到
user1.frm是正常的,8.0 里对应的是user1_369.sdi。

备注:创建一个 engine 为 InnoDB 的数据库,观察存储目录。
2.2 查看表
查看表结构
desc 表名;

显示表的详细信息
show create table user1; show create table user1\G; (\G:格式化显示,去掉不需要的符号)

\G:格式化显示,去掉不需要的符号。
2.3 修改表
在项目实际开发中,经常需要修改某个表的结构,比如字段名字、字段大小、字段类型、表的字符集类型、表的存储引擎等。也可能需要添加字段、删除字段。这时就需要修改表。
语法:
ALTER TABLE tablename ADD (column datatype [DEFAULT expr][,column datatype]...); ALTER TABLE tablename MODIFY (column datatype [DEFAULT expr][,column datatype]...); ALTER TABLE tablename DROP (column);
- 将 user1 改为 user(to 可以省略)


- 在表中添加记录
insert into tablename values (插入各项内容);

- 在表中添加一个字段
alter table tablename add (column datatype [DEFAULT expr][,column datatype]...);

插入新字段后,对原来表中的数据没有影响。
2.4 修改属性
alter table tablename modify (column datatype [DEFAULT expr][,column datatype]...);

注意:不是指定进行修改,要将所修改属性后面的内容也加上,否则将直接覆盖原有内容。
2.5 删除 password 列
注意:删除字段一定要小心,删除字段及其对应的列数据都没了。
alter table tablename drop (column);

2.6 修改列名
alter table tablename change (column newcolumn datatype [DEFAULT expr][,column datatype]...);

新字段需要完整定义,属性也要带上。
2.7 删除表
语法格式:
DROP [TEMPORARY] TABLE [IF EXISTS] tbl_name [, tbl_name] ...

总结
MySQL 中库和表的基本操作其实就是在和文件系统打交道,但加上编码、校验规则、存储引擎这些概念后,细节就丰富起来了。记住几个关键点:字符集和校验规则要匹配;备份时带 -B 参数能省掉重建库的步骤;修改字段属性时要写全定义;不同存储引擎生成的文件不同,MySQL 8.0 不再有 frm 文件而是用 sdi 替代。掌握了这些,日常开发中操作数据库就会更加得心应手。
