开篇介绍:
hello 大家,那么在上篇博客中,我们初步的接触了MySQL,并知道了什么是数据库,什么是表,也安装了MySQL,那么接下来,我们就要进入实操部分了,我们根据从大到小的顺序来进行,本篇博客中就先来解析对数据库的操作。
引言:为什么数据库操作是 MySQL 入门的 "第一块基石"?
在数字化时代,数据已成为所有应用的核心资产 ------ 小到个人博客的文章列表,大到电商平台的亿万订单,再到企业内部的人事档案,都需要一个可靠的 "容器" 来存储、组织和管理。这个 "容器",就是数据库。而 MySQL 作为全球使用最广泛的开源关系型数据库,凭借免费、高效、易部署、社区活跃的特点,成为了 Web 开发、后端开发、数据分析等领域的首选工具。
对于初学者而言,MySQL 的学习往往从 "数据库的基本操作" 开始 ------ 这是因为数据库是承载所有数据的顶层结构,就像盖房子必须先打好地基一样,只有掌握了数据库的创建、查看、修改、删除、备份、恢复等核心操作,才能后续学习数据表设计、数据记录增删改查、索引优化等高级内容。
更重要的是,数据库操作看似简单,却暗藏诸多影响系统稳定性的细节:比如字符集选择错误会导致中文乱码,排序规则设置不当会引发查询结果异常,随意删除数据库可能造成不可逆的数据丢失,备份策略缺失会让企业面临巨大风险。而对于中级开发者,规范的数据库操作习惯(如命名规范、权限控制、备份策略)更是保障生产环境稳定运行的核心前提。
一、核心概念澄清:彻底搞懂 "数据库" 到底是什么?
在深入操作之前,我们必须先扫清概念上的迷雾 ------ 很多初学者之所以学不好数据库操作,根源在于混淆了 "数据库服务器""数据库""数据表" 这三个核心概念。
1.1 数据库的本质:数据的 "分类文件夹"
MySQL 中的 "数据库"(Database),本质是一个由 MySQL 服务器管理的、带有特定配置(字符集、排序规则)的物理目录。它的核心作用有三个:
- 按业务场景隔离数据:比如电商业务的 "ecommerce" 数据库和博客业务的 "blog" 数据库完全独立,避免数据表命名冲突(比如两个业务都有 "user" 表,但分属不同数据库,不会冲突);
- 统一配置数据属性:同一数据库下的所有数据表,默认会继承数据库的字符集和排序规则,无需重复配置,减少冗余;
- 简化权限管理:可以针对数据库粒度分配权限(比如 "开发人员仅能操作测试库 test_db,无法访问生产库 prod_db"),提升数据安全性。
类比理解:数据库 = 电脑硬盘中的 "分类文件夹"
我们可以把电脑的硬盘比作 "MySQL 服务器",硬盘中的 "分类文件夹"(如 "工作文件""个人照片""项目代码")比作 "数据库",文件夹中的 "具体文件"(如 Word 文档、Excel 表格)比作 "数据表"。这样一来:
- 你不会把工作文档和个人照片放在同一个文件夹里(对应 "不同业务数据放在不同数据库");
- 同一个文件夹里的文件通常有相似的用途(对应 "同一数据库下的表对应同一业务实体");
- 你可以给不同文件夹设置不同的访问权限(对应 "数据库级别的权限控制")。
1.2 数据库与数据库服务器、数据表的三层关系
很多初学者会把 "数据库服务器""数据库""数据表" 混为一谈,这里用 "图书馆管理系统" 做一个更精准的类比,帮你彻底理清三者的关系:
| 层级 | 类比对象 | 核心作用 | 具体示例 |
|---|---|---|---|
| 数据库服务器 | 图书馆整体(含管理员) | 运行 MySQL 程序的进程,负责接收用户请求、分配系统资源(CPU / 内存 / 硬盘)、保障数据安全,管理所有数据库 | 一台运行 MySQL 8.0 的 Linux 服务器,可同时管理电商库、博客库、人事库等多个数据库 |
| 数据库 | 图书馆的 "分类书架" | 按业务场景分类,隔离不同类型的数据表,统一配置字符集、排序规则 | 电商书架(ecommerce 库)、博客书架(blog 库)、人事书架(hr 库) |
| 数据表 | 书架上的 "结构化书籍" | 存储具体数据的结构化文件,每个表对应一个业务实体(如用户、订单、商品) | 电商书架上的 "用户信息书"(user 表)、"订单记录书"(order 表)、"商品清单书"(goods 表) |
关键结论(必须牢记):
- 一个数据库服务器可以管理多个数据库(数量仅受硬盘空间和服务器性能限制);
- 一个数据库可以包含多个数据表(通常对应同一业务的不同实体);
- 一个数据表只能属于一个数据库(不能跨数据库存储);
- 操作数据表之前,必须先 "进入" 对应的数据库(就像拿书之前必须走到对应的书架前)。
1.3 存储引擎对数据库操作的影响(重要澄清)
很多初学者会有一个疑问:"创建数据库时需要指定存储引擎吗?比如 InnoDB 或 MyISAM?"
答案是:不需要。
原因很简单:存储引擎是 "数据表级别的配置",决定了数据表的存储方式(如数据如何存储在硬盘上、是否支持事务、是否支持索引),而数据库仅负责 "容器管理"------ 它的作用是隔离和组织数据表,与存储引擎无关。
举个例子:你创建一个 "ecommerce" 数据库后,既可以在里面创建 InnoDB 引擎的 "order" 表(支持事务,适合订单这类核心业务),也可以创建 MyISAM 引擎的 "goods_category" 表(查询速度快,适合商品分类这类读多写少的数据)。数据库本身的创建、修改、删除操作,不会因为存储引擎的不同而有任何差异。
再类比:数据库是 "文件夹",存储引擎是 "文件格式"(如 Word 文档、Excel 表格、PDF 文件)。文件夹的创建、删除操作,和里面文件的格式没有任何关系 ------ 你可以在同一个文件夹里放 Word 和 Excel 文件,就像在同一个数据库里放 InnoDB 和 MyISAM 引擎的表。
1.4 数据库的物理存储形式(帮你理解本质)
为了让你更直观地理解数据库,我们可以看看数据库在硬盘上的物理存储形式(以 Linux 系统为例):
- MySQL 的默认数据存储目录是
/var/lib/mysql/(可通过show variables like 'datadir';查询); - 当你创建一个名为 "ecommerce" 的数据库后,MySQL 会在
/var/lib/mysql/目录下创建一个名为 "ecommerce" 的子目录; - 这个子目录中会存储该数据库的所有元数据(如字符集、排序规则配置)和数据表文件(如 InnoDB 引擎的
.ibd文件、MyISAM 引擎的.frm和.MYD文件)。

简单说:数据库在物理上就是一个 "带配置文件的文件夹",数据表就是这个文件夹里的 "具体文件"。
二、前置操作:连接 MySQL 服务器(从入门到精通)
所有数据库操作都必须在 "连接到 MySQL 服务器" 的前提下执行。本节将详细讲解不同场景下的连接方法、连接失败的排查步骤,以及相关注意事项,确保你能顺利进入 MySQL 的操作环境。
2.1 连接 MySQL 服务器的核心原理
MySQL 服务器运行在某个主机(本地或远程)上,监听默认端口 3306(可修改)。用户通过 MySQL 客户端(命令行、图形化工具)向服务器发送连接请求,服务器验证用户的 "用户名 + 密码 + 主机权限" 后,建立会话连接。后续所有操作(创建数据库、查询数据等)都在这个会话中执行,直到用户退出或连接超时。
2.2 命令行连接(Linux/Windows 通用)
命令行是最基础、最通用的连接方式,适合所有开发者,尤其是服务器环境(通常没有图形化界面)。
2.2.1 本地连接(主机与服务器在同一台电脑)
语法
# 完整语法
mysql -u 用户名 -p -P 端口号 -h 主机地址
# 简化语法(本地连接,默认端口3306)
mysql -u 用户名 -p
参数详解
| 参数 | 作用说明 | 可选 / 必选 | 默认值 |
|---|---|---|---|
| -u | 指定连接 MySQL 的用户名(如 root、test_user) | 必选 | 无 |
| -p | 提示输入用户密码(推荐这种方式,安全性高);也可直接写密码(如 - p123456,不推荐) | 必选 | 无 |
| -P | 指定 MySQL 服务器的端口号(注意是大写 P) | 可选 | 3306 |
| -h | 指定 MySQL 服务器的主机地址(本地连接为localhost或 127.0.0.1) | 可选 | localhost |
示例 1:使用 root 用户本地连接(默认端口)
mysql -uroot -p
执行流程
- 输入命令后,按回车,系统会提示 "Enter password:",输入 root 用户的密码(输入时密码不显示,正常现象);
- 密码正确后,进入 MySQL 交互终端,显示
mysql>提示符,表示连接成功; - 若密码错误,会提示
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)。
示例 2:指定端口本地连接(若端口被修改)
# 假设MySQL服务器端口改为3307
mysql -uroot -p -P3307 -hlocalhost
2.2.2 远程连接(主机与服务器在不同电脑)
语法
mysql -u 用户名 -p -h 服务器IP地址 -P 端口号
示例
# 连接IP为192.168.1.100、端口3306的MySQL服务器
mysql -uroot -p -h192.168.1.100 -P3306
远程连接的前提条件
- 服务器上的 MySQL 服务已启动;
- 服务器的防火墙已开放 3306 端口(或自定义端口);
- 连接用户已被授权远程访问(如
root@'%',表示允许从任何 IP 访问); - 服务器 IP 地址可被客户端访问(无网络隔离)。
2.3 图形化工具连接
对于不熟悉命令行的初学者,图形化工具(如 Navicat、DBeaver、MySQL Workbench)是更好的选择,操作更直观、更便捷。
以 Navicat 为例,连接步骤:
- 打开 Navicat,点击 "连接"→"MySQL";
- 在弹出的窗口中填写连接信息:
- 连接名:自定义(如 "本地 MySQL""远程电商数据库");
- 主机:localhost(本地)或服务器 IP(远程);
- 端口:3306(默认)或自定义端口;
- 用户名:MySQL 用户名(如 root);
- 密码:用户密码;
- 点击 "测试连接",显示 "连接成功" 后,点击 "确定";
- 双击左侧连接名,即可打开连接,查看所有数据库。
图形化工具的优势
- 可视化操作,无需记忆命令;
- 支持批量操作(如批量备份数据库、批量执行 SQL 脚本);
- 自带 SQL 编辑器,语法高亮、自动补全,降低写错概率;
- 可直观查看数据库结构、表结构、数据记录。
2.4 连接失败的详细排查步骤(新手必看)
连接 MySQL 服务器时,新手常遇到 "连接失败" 的问题,这里提供一套完整的排查流程,帮你快速定位问题:
步骤 1:检查 MySQL 服务是否启动
-
Linux 系统:
# 查看服务状态 sudo systemctl status mysql # 若未启动,启动服务 sudo systemctl start mysql -
Windows 系统:
- 按 Win+R,输入
services.msc,打开服务管理器; - 找到 "MySQL" 服务,查看状态是否为 "正在运行";
- 若未运行,右键点击 "启动"。
- 按 Win+R,输入
步骤 2:检查连接参数是否正确
- 用户名是否正确(如 root 是否拼写错误);
- 密码是否正确(注意大小写,MySQL 密码默认区分大小写);
- 主机地址是否正确(本地连接用localhost,远程连接用服务器 IP);
- 端口号是否正确(默认 3306,若修改过需填写新端口)。
步骤 3:检查防火墙是否开放端口
-
Linux 系统(ufw 防火墙):
# 查看3306端口是否开放 sudo ufw status # 若未开放,开放3306端口 sudo ufw allow 3306/tcp # 重启防火墙 sudo ufw reload -
Windows 系统(防火墙):
- 打开 "控制面板"→"系统和安全"→"Windows Defender 防火墙"→"高级设置";
- 点击 "入站规则"→"新建规则";
- 选择 "端口"→"TCP"→"特定本地端口",输入 3306;
- 选择 "允许连接"→"下一步"→"完成"。
步骤 4:检查用户是否有连接权限
-
登录 MySQL 服务器(本地连接),查看用户权限:
-- 查看root用户的访问权限 SELECT user, host FROM mysql.user WHERE user='root'; -
若用户的 host 字段为
localhost,表示仅允许本地连接,无法远程连接; -
若需远程连接,需授权:
-- 授予root用户从任何IP访问的权限 CREATE USER 'root'@'%' IDENTIFIED BY '你的密码'; GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION; FLUSH PRIVILEGES;
步骤 5:检查 MySQL 配置是否限制连接
- 查看 MySQL 配置文件(Linux:
/etc/mysql/mysql.conf.d/mysqld.cnf); - 找到
bind-address参数,若值为127.0.0.1,表示仅允许本地连接,远程连接需改为0.0.0.0; - 修改后重启 MySQL 服务:
sudo systemctl restart mysql。
2.5 退出 MySQL 连接
命令行退出(两种方式,效果一致)
exit;
quit;
图形化工具退出
- 右键点击连接名,选择 "断开连接";
- 直接关闭工具窗口(工具会自动断开连接)。
注意事项
- 连接仅在当前会话中有效,退出后需重新连接才能执行操作;
- 若长时间不操作,连接可能会超时断开(默认超时时间由
wait_timeout参数控制,默认 8 小时); - 生产环境中,建议避免长时间空闲的连接,以免占用服务器资源。
三、创建数据库:CREATE DATABASE
创建数据库是所有操作的起点,也是最容易忽略细节的环节。一个规范的数据库创建操作,需要考虑 "是否重复创建""字符集选择""排序规则配置""命名规范""权限控制" 等多个维度。
3.1 完整语法拆解(MySQL 5.7/8.0 通用)
MySQL 中创建数据库的完整语法如下,每个关键字和选项都有其特定作用,缺一不可:
sql
CREATE DATABASE [IF NOT EXISTS] db_name
[create_specification [, create_specification] ...];
# 其中 create_specification 是可选配置项,可同时指定多个
create_specification:
[DEFAULT] CHARACTER SET charset_name # 指定数据库默认字符集
[DEFAULT] COLLATE collation_name # 指定数据库默认排序规则
[DEFAULT] ENCRYPTION = {'Y' | 'N'} # MySQL 8.0+ 新增,是否启用数据库加密
COMMENT '数据库注释' # MySQL 8.0+ 新增,给数据库添加注释
语法关键字逐字解析
| 关键字 / 选项 | 作用说明 | 是否可选 | 核心价值 |
|---|---|---|---|
| CREATE DATABASE | 核心关键字组合,明确声明 "执行创建数据库的操作" | 必选 | 告诉 MySQL 服务器,当前要做的是创建数据库,而非查询或修改数据 |
| IF NOT EXISTS | 条件判断:仅当数据库不存在时才创建,若已存在则不执行操作,也不报错 | 可选 | 避免 "数据库已存在" 导致的脚本执行中断,是生产环境的推荐写法 |
| db_name | 数据库名称,是数据库的唯一标识(在同一服务器中) | 必选 | 给数据库起一个符合规范的名字,便于后续识别和管理 |
| DEFAULT | 显式声明 "这是默认配置",无实际功能,仅用于提升语法可读性,可写可不写 | 可选 | 比如DEFAULT CHARACTER SET utf8mb4和CHARACTER SET utf8mb4效果一致,前者更易读 |
| CHARACTER SET | 指定数据库的默认字符集(如 utf8mb4、gbk) | 可选 | 决定数据库能存储哪些语言的字符(如 utf8mb4 支持中文和 emoji),避免乱码 |
| COLLATE | 指定数据库的默认排序规则(如 utf8mb4_general_ci) | 可选 | 决定字符的比较方式(如是否区分大小写),影响查询结果排序和匹配,注意默认字符集和默认排序规则要互相匹配才行 |
| ENCRYPTION | MySQL 8.0+ 新增选项,控制数据库是否加密存储(Y = 加密,N = 不加密) | 可选 | 提升数据安全性,防止硬盘被窃取后数据泄露(需服务器支持加密功能) |
| COMMENT | MySQL 8.0+ 新增选项,给数据库添加描述性注释(如 "电商生产库,存储订单、用户数据") | 可选 | 便于团队协作和后期维护,快速了解数据库的用途 |

3.2 数据库命名规范(避坑核心,必须严格遵守)
数据库名称是数据库的 "身份证",命名不规范会导致后续维护困难、跨平台兼容问题、甚至语法错误。以下是企业级的命名规范,适用于所有场景:
3.2.1 基础命名规则(不可违反)
-
允许使用的字符 :
- 字母:a-z、A-Z(推荐全小写,避免大小写敏感问题);
- 数字:0-9(不能作为名称的第一个字符,如 "123db" 是非法的);
- 特殊字符:仅允许下划线(_),禁止使用空格、中文、@、#、$、& 等其他特殊字符;
-
大小写敏感规则 :
- Linux 系统中,MySQL 默认区分数据库名大小写(如 "ecommerce" 和 "Ecommerce" 是两个不同数据库);
- Windows 系统中,MySQL 默认不区分大小写(上述两个名称视为同一个数据库);
- 为保证跨平台兼容性(如开发环境是 Windows,生产环境是 Linux),强制要求数据库名全小写;
-
长度限制:数据库名最大长度为 64 个字符(MySQL 官方限制),建议控制在 16 个字符以内,避免过长导致记忆和输入困难;
-
禁止使用保留字 :不可使用 MySQL 的关键字(如 SELECT、DATABASE、TABLE、ORDER、USER 等)作为数据库名,否则会抛出语法错误。若必须使用(极不推荐),需用反引号(`)包裹,例如:
sql# 不推荐:使用ORDER(关键字)作为数据库名 CREATE DATABASE IF NOT EXISTS `ORDER`;
3.2.2 企业级命名规范
- 命名格式 :按 "业务场景_用途_环境" 的格式命名,清晰易懂,示例如下:
- 电商生产库:
ecommerce_prod(ecommerce = 电商业务,prod = 生产环境); - 电商测试库:
ecommerce_test(test = 测试环境); - 博客开发库:
blog_dev(dev = 开发环境); - 人事管理库:
hr_manage_prod(hr = 人事业务,manage = 管理用途);
- 电商生产库:
- 禁止使用无意义名称 :避免使用
test、db1、data等无意义名称,否则后期无法快速识别数据库用途; - 统一前缀 :同一业务线的数据库使用相同前缀,便于分类管理,例如电商业务的所有数据库都以
ecommerce_开头。
3.3 字符集与排序规则:创建数据库的核心配置(避免乱码和查询异常)
字符集(CHARACTER SET)和排序规则(COLLATE)是创建数据库时最关键的配置,直接影响数据存储(是否支持中文、emoji)和查询结果(是否区分大小写、排序是否正确)。很多新手的中文乱码、查询结果不符合预期等问题,都源于这两个配置的选择不当。
3.3.1 什么是字符集?------ 数据的 "语言字典"
字符集是 "字符的编码规则",相当于一本 "语言字典",告诉 MySQL 如何存储和解析不同语言的字符。不同字符集支持的语言、存储占用的字节数都不同,常见字符集对比如下:
| 字符集 | 支持语言 | 单个字符最大字节数 | 适用场景 | 优缺点分析 |
|---|---|---|---|---|
| latin1 | 英文、数字、部分西欧符号 | 1 | 仅英文场景(如早期英文网站) | 优点:存储效率高;缺点:不支持中文、中文符号,已基本淘汰 |
| gbk | 中文、英文、数字 | 2 | 仅中文场景(如旧版中文系统) | 优点:中文存储效率高(1 个中文占 2 字节);缺点:不支持 emoji,兼容性不如 utf8mb4 |
| utf8 | 中文、英文、数字、常用符号 | 3 | 早期中文场景 | 优点:支持大部分中文;缺点:不支持 emoji,且 MySQL 中的 "utf8" 实际是 "utf8mb3",非标准 UTF-8 |
| utf8mb4 | 所有 Unicode 字符(中文、emoji、多国语言) | 4 | 所有场景(推荐) | 优点:兼容性最好,支持中文、emoji、日文、韩文等所有 Unicode 字符;缺点:中文存储占用 3-4 字节,略低于 gbk |
关键结论:推荐优先使用 utf8mb4
- utf8mb4 是 MySQL 中真正的 UTF-8 编码,支持所有 Unicode 字符,包括中文、emoji 表情(如😊、🎉)、特殊符号(如 ©、®),是目前最推荐的字符集;
- 虽然 utf8mb4 存储中文时比 gbk 多占用 1 字节,但在硬盘容量廉价的今天,兼容性和功能性远比存储效率重要;
- MySQL 8.0 已将 utf8mb4 设为默认字符集,MySQL 5.7 默认字符集为 latin1,因此 MySQL 5.7 创建数据库时必须显式指定 utf8mb4,避免中文乱码。
3.3.2 什么是排序规则?------ 字符的 "比较规则"
排序规则是 "字符的比较和排序规则",相当于 "字典的排序方式",告诉 MySQL 如何比较两个字符的大小、是否相等,以及如何对查询结果排序。每个字符集对应多个排序规则,核心差异体现在以下几个维度:
| 排序规则维度 | 具体差异示例 |
|---|---|
| 是否区分大小写 | 如 "a" 和 "A" 是否视为同一个字符(utf8mb4_general_ci 不区分,utf8mb4_bin 区分) |
| 是否区分重音 | 如 "é" 和 "e" 是否视为同一个字符(utf8mb4_general_ci 不区分,utf8mb4_unicode_ci 区分) |
| 是否区分字符宽度 | 如 "a"(全角小写 a)和 "a"(半角小写 a)是否视为同一个字符(utf8mb4_general_ci 不区分) |
| 排序效率与精准度 | 如 utf8mb4_general_ci 效率高但精准度一般,utf8mb4_unicode_ci 精准度高但效率略低 |
常见 utf8mb4 字符集对应的排序规则(重点关注)
| 排序规则 | 是否区分大小写 | 是否区分重音 | 适用场景 | 特点分析 |
|---|---|---|---|---|
| utf8mb4_general_ci | 否 | 否 | 普通业务场景(如电商、博客) | 效率高,查询时不区分大小写和重音,用户体验好(如搜索 "苹果" 能找到 "苹果""APPLE") |
| utf8mb4_bin | 是 | 是 | 精准匹配场景(如用户名验证) | 严格区分大小写、重音、字符宽度(如 "user123" 和 "User123" 视为不同用户名),安全性高 |
| utf8mb4_unicode_ci | 否 | 是 | 多语言场景(如国际化网站) | 支持重音区分(如 "école" 和 "ecole" 视为不同),排序更符合 Unicode 标准 |
| utf8mb4_0900_ai_ci | 否 | 否 | MySQL 8.0 默认排序规则 | 基于 Unicode 9.0,效率和精准度平衡,支持更多字符的正确排序 |
3.3.3 字符集与排序规则的匹配关系(不可违反)
- 一个字符集可以对应多个排序规则,但一个排序规则只能属于一个字符集;
- 创建数据库时,若仅指定字符集,MySQL 会自动匹配该字符集的 "默认排序规则"(如 utf8mb4 的默认排序规则是 utf8mb4_0900_ai_ci(MySQL 8.0)或 utf8mb4_general_ci(MySQL 5.7));
- 若同时指定字符集和排序规则,必须确保二者匹配 ------ 即排序规则必须是该字符集支持的,否则会抛出错误,即要一对一,不能一个字符集去用随意一个排序规则,这样子就会报错,要一对一,当然一般来说像字符集和排序规则的使用,是不用我们操心的,MySQL自己就会默认解决。
错误示例:排序规则与字符集不匹配
# 错误:utf8_general_ci是utf8字符集的排序规则,不能用于utf8mb4
CREATE DATABASE IF NOT EXISTS db_error
CHARACTER SET utf8mb4
COLLATE utf8_general_ci;
报错信息:
ERROR 1273 (HY000): Unknown collation: 'utf8_general_ci'
正确示例:排序规则与字符集匹配
# 正确:utf8mb4_general_ci是utf8mb4字符集支持的排序规则
CREATE DATABASE IF NOT EXISTS db_correct
CHARACTER SET utf8mb4
COLLATE utf8mb4_general_ci;
3.4 MySQL 8.0+ 新增配置:ENCRYPTION 与 COMMENT
MySQL 8.0 版本新增了两个实用配置项:ENCRYPTION(数据库加密)和 COMMENT(数据库注释),进一步提升了数据库的安全性和可维护性。
3.4.1 ENCRYPTION:数据库加密存储
启用加密后,MySQL 会将数据库中的数据加密后存储在硬盘上,即使硬盘被物理窃取,没有解密密钥也无法读取数据,适用于存储敏感信息(如用户手机号、支付信息)的场景,使用ENCRYPTION = 'Y'去表明启用加密服务,要是没有写这一句的话,就默认不起用加密服务。
示例
sql
# 创建加密的电商生产库
CREATE DATABASE IF NOT EXISTS ecommerce_prod
CHARACTER SET utf8mb4
COLLATE utf8mb4_general_ci
ENCRYPTION = 'Y'
COMMENT '电商生产库,存储用户、订单、商品等核心数据,已加密';
注意事项
- 加密功能仅 MySQL 8.0 及以上版本支持;
- 启用加密后,会略微增加服务器的 CPU 开销(加密和解密需要计算),非敏感数据场景可不用启用;
- 加密密钥由 MySQL 服务器管理,需定期备份密钥,避免密钥丢失导致数据无法解密。
3.4.2 COMMENT:数据库注释
作用
给数据库添加描述性注释,说明数据库的用途、业务场景、负责人等信息,便于团队协作和后期维护(尤其是服务器上有多个数据库时)。
示例
# 给博客测试库添加注释
CREATE DATABASE IF NOT EXISTS blog_test
CHARACTER SET utf8mb4
COLLATE utf8mb4_general_ci
COMMENT '博客项目测试库,用于开发环境测试,负责人:张三,版本:V1.0';
查看注释
# 方式1:通过SHOW CREATE DATABASE查看
SHOW CREATE DATABASE blog_test;
# 方式2:通过information_schema查询(更详细)
SELECT SCHEMA_NAME, DEFAULT_CHARACTER_SET_NAME, DEFAULT_COLLATION_NAME, COMMENT
FROM information_schema.SCHEMATA
WHERE SCHEMA_NAME = 'blog_test';
3.5 创建数据库的常见场景示例
场景 1:创建基础数据库(默认字符集和排序规则,MySQL 8.0)
# 适用场景:快速测试、临时使用,依赖MySQL 8.0默认配置(utf8mb4)
CREATE DATABASE IF NOT EXISTS db_basic;
说明:
- MySQL 8.0 默认字符集为 utf8mb4,默认排序规则为 utf8mb4_0900_ai_ci,支持中文和 emoji;
- 无需额外配置,简单快捷,适合临时测试场景;
- 不推荐生产环境使用(未添加注释、未明确配置,后期维护困难)。
场景 2:创建支持中文的数据库(显式指定 utf8mb4,兼容 MySQL 5.7/8.0)
# 适用场景:所有需要存储中文的场景(电商、博客、管理系统),兼容MySQL 5.7和8.0
CREATE DATABASE IF NOT EXISTS db_chinese
CHARACTER SET utf8mb4
COLLATE utf8mb4_general_ci;
说明:
- 显式指定字符集和排序规则,避免 MySQL 5.7 默认 latin1 导致的中文乱码;
- utf8mb4_general_ci 不区分大小写,适合普通业务场景(如商品搜索、用户查询);
- 这是最常用的生产环境基础配置。
场景 3:创建区分大小写的数据库(精准匹配场景)
# 适用场景:用户名验证、密码存储等需要精准匹配的场景
CREATE DATABASE IF NOT EXISTS db_case_sensitive
CHARACTER SET utf8mb4
COLLATE utf8mb4_bin
COMMENT '精准匹配库,用户名、密码等数据区分大小写';
说明:
- utf8mb4_bin 是二进制排序规则,严格区分大小写(如 "User001" 和 "user001" 视为不同);
- 适合存储需要精准匹配的数据(如用户名、API 密钥),提升安全性;
- 查询时需注意大小写一致(如查询 "User001" 不能写成 "user001")。
场景 4:创建加密的生产环境数据库(MySQL 8.0+)
# 适用场景:存储敏感信息的生产环境(如用户手机号、支付记录)
CREATE DATABASE IF NOT EXISTS ecommerce_prod
CHARACTER SET utf8mb4
COLLATE utf8mb4_general_ci
ENCRYPTION = 'Y'
COMMENT '电商生产库,存储订单、用户、支付等敏感数据,已加密,负责人:李四';
说明:
- 启用加密功能,防止数据泄露;
- 添加详细注释,便于团队维护;
- 生产环境推荐配置,需确保服务器支持加密功能。
场景 5:创建兼容旧系统的 GBK 字符集数据库
# 适用场景:对接仅支持GBK编码的旧系统(如 legacy 管理系统)
CREATE DATABASE IF NOT EXISTS db_gbk
CHARACTER SET gbk
COLLATE gbk_chinese_ci
COMMENT '兼容旧系统的GBK库,对接 legacy 系统数据';
说明:
- gbk 字符集仅支持中文和英文,不支持 emoji;
- gbk_chinese_ci 不区分大小写,适合中文旧系统;
- 非必要不推荐使用,优先选择 utf8mb4。
场景 6:创建多语言支持的数据库(国际化场景)
# 适用场景:支持中文、英文、日文、韩文等多语言的国际化网站
CREATE DATABASE IF NOT EXISTS db_i18n
CHARACTER SET utf8mb4
COLLATE utf8mb4_unicode_ci
COMMENT '国际化多语言库,支持中日韩等多国语言,区分重音';
说明:
- utf8mb4_unicode_ci 支持重音区分(如 "école" 和 "ecole" 视为不同),排序更符合 Unicode 标准;
- 适合国际化网站、跨国企业系统等场景;
- 效率略低于 utf8mb4_general_ci,但精准度更高。
3.6 避免重复创建:IF NOT EXISTS 的重要性
很多新手会忽略IF NOT EXISTS选项,直接写CREATE DATABASE db_name;,这在生产环境中是极其危险的,可能导致脚本执行中断。
错误示例:未加 IF NOT EXISTS,创建已存在的数据库
# 错误:db_exist已存在,执行后会报错
CREATE DATABASE db_exist;
报错信息:
ERROR 1007 (HY000): Can't create database 'db_exist'; database exists
后果
- 若该命令在自动化部署脚本中,报错会导致后续所有操作中断,影响系统上线;
- 手动执行时,需要先判断数据库是否存在,增加操作步骤。
正确示例:添加 IF NOT EXISTS,安全创建
# 正确:无论db_exist是否存在,都不会报错,脚本可正常执行
CREATE DATABASE IF NOT EXISTS db_exist;
执行结果:
- 若数据库不存在:创建成功,返回
Query OK, 1 row affected (0.01 sec); - 若数据库已存在:不执行创建操作,返回
Query OK, 0 rows affected, 1 warning (0.00 sec)(警告信息可忽略,不影响后续操作)。
生产环境建议
-
所有 CREATE DATABASE 语句必须添加
IF NOT EXISTS选项,确保脚本的健壮性; -
若需强制重新创建数据库(如测试环境重置数据),需先删除旧数据库,再创建新数据库(注意:生产环境禁止这么做):
# 测试环境专用:删除旧数据库,重新创建(高危操作,生产环境禁用) DROP DATABASE IF EXISTS db_test; CREATE DATABASE IF NOT EXISTS db_test CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
3.7 创建数据库的常见错误与解决方案
错误 1:中文乱码(MySQL 5.7 未指定字符集)
现象
创建数据库后,插入中文数据显示为 "???` 或乱码。
原因
MySQL 5.7 默认字符集为 latin1,不支持中文,未显式指定 utf8mb4。
解决方案
# 1. 删除旧数据库(若已创建)
DROP DATABASE IF EXISTS db_gbk_error;
# 2. 重新创建,显式指定utf8mb4字符集
CREATE DATABASE IF NOT EXISTS db_gbk_correct
CHARACTER SET utf8mb4
COLLATE utf8mb4_general_ci;
# 3. 验证字符集
SHOW CREATE DATABASE db_gbk_correct;
错误 2:数据库名包含特殊字符
现象
创建数据库时使用中文或空格,抛出语法错误。
错误示例
# 错误:数据库名包含中文和空格
CREATE DATABASE IF NOT EXISTS 电商 数据库;
报错信息:
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '电商 数据库' at line 1
解决方案
-
遵循命名规范,使用 "小写字母 + 下划线" 命名,避免特殊字符和中文;
-
若必须使用特殊字符(极不推荐),用反引号包裹:
# 不推荐:使用反引号包裹特殊字符名称 CREATE DATABASE IF NOT EXISTS `电商_数据库`;
错误 3:权限不足,无法创建数据库
现象
执行 CREATE DATABASE 时,抛出权限不足错误。
报错信息:
ERROR 1044 (42000): Access denied for user 'test_user'@'localhost' to database 'db_new'
原因
当前用户没有CREATE DATABASE权限(如普通测试用户)。
解决方案
-
使用 root 用户登录 MySQL;
-
给当前用户授予创建数据库的权限:
授予test_user创建数据库的全局权限
GRANT CREATE ON . TO 'test_user'@'localhost';
刷新权限,使修改生效
FLUSH PRIVILEGES;
-
切换回 test_user,重新执行创建命令。
四、查看数据库:掌握 SHOW 系列命令(全方位了解数据库信息)
创建数据库后,你需要通过查看命令确认数据库是否创建成功、配置是否正确、当前连接的是哪个数据库等。MySQL 提供了SHOW DATABASES、SHOW CREATE DATABASE、SELECT DATABASE()等多个命令,覆盖从 "查看所有数据库" 到 "查看单个数据库详情" 的所有需求。
4.1 查看所有数据库:SHOW DATABASES
语法
# 查看所有数据库(包括系统库和用户创建的库)
SHOW DATABASES;
# 过滤查询:只查看符合条件的数据库(支持通配符%和_)
SHOW DATABASES LIKE '匹配模式';
通配符说明
%:匹配任意个字符(包括 0 个),如'ecommerce%'匹配所有以 "ecommerce" 开头的数据库;_:匹配单个字符,如'db_'匹配所有以 "db" 开头且后面跟 1 个字符的数据库(如 db1、db2)。- 关于通配符我们后面会说,大家这里先做了解,有一点想要强调的就是,在MySQL中,中文字符或者是其他字符,如果要是字符串的话,是要用单引号包含起来,使用双引号是不被许可的哦。
示例 1:查看所有数据库
SHOW DATABASES;
注意是复数,要加s。
执行结果(MySQL 8.0):
+--------------------+
| Database |
+--------------------+
| information_schema |
| blog_test |
| db_basic |
| db_chinese |
| ecommerce_prod |
| mysql |
| performance_schema |
| sys |
+--------------------+
8 rows in set (0.00 sec)
结果解读
- 列表中包含两类数据库:
- 系统默认数据库(不可随意修改或删除):
information_schema:存储 MySQL 元数据(如数据库、表、字段信息),只读;mysql:存储用户账号、权限、密码等核心信息,修改可能导致登录失败;performance_schema:存储数据库性能监控数据,用于性能分析;sys:基于 performance_schema 的简化视图,便于普通用户查看系统状态;
- 用户创建的数据库(如 blog_test、ecommerce_prod):可根据业务需求操作。
- 系统默认数据库(不可随意修改或删除):
这里提醒一下大家,用小写大写都可以,只是要记得最后加上分号表示该语句结束哦。
示例 2:过滤查看以 "ecommerce" 开头的数据库
SHOW DATABASES LIKE 'ecommerce%';
执行结果:
+-------------------+
| Database (ecommerce%) |
+-------------------+
| ecommerce_prod |
+-------------------+
1 row in set (0.00 sec)

示例 3:过滤查看包含 "test" 的数据库
SHOW DATABASES LIKE '%test%';
执行结果:
+----------------+
| Database (%test%) |
+----------------+
| blog_test |
| db_test |
+----------------+
2 rows in set (0.00 sec)
4.2 查看单个数据库详情:SHOW CREATE DATABASE 名字
SHOW DATABASES仅能查看数据库名称,若需确认字符集、排序规则、加密状态、注释等详细配置,需使用SHOW CREATE DATABASE命令,那么说白了就是使用该语句能够显示出当时你创建该数据库时是怎么配置的,添加哪些内容,使用什么字符集,什么排序规则,是否加密,注释是什么,这里也需要知道的是,我们想要查看我们创建数据库、表等等的注释时,也是都只有使用shoe create database xxx(数据库/表名字) 的时候才能看到,希望注意哦。
语法
sql
SHOW CREATE DATABASE db_name;
示例 1:查看基础数据库详情
SHOW CREATE DATABASE db_basic;
执行结果(MySQL 8.0):
+----------+----------------------------------------------------------------------------------------------------------------------------------+
| Database | Create Database |
+----------+----------------------------------------------------------------------------------------------------------------------------------+
| db_basic | CREATE DATABASE `db_basic` /*!40100 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci */ /*!80016 DEFAULT ENCRYPTION='N' */ |
+----------+----------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

示例 2:查看加密且带注释的数据库详情
SHOW CREATE DATABASE ecommerce_prod;
执行结果(MySQL 8.0):
+----------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Database | Create Database |
+----------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ecommerce_prod | CREATE DATABASE `ecommerce_prod` /*!40100 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci */ /*!80016 DEFAULT ENCRYPTION='Y' */ COMMENT '电商生产库,存储订单、用户、支付等敏感数据,已加密,负责人:李四' |
+----------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
结果字段详细解读(新手必懂)
- Database:数据库名称(与输入的 db_name 一致);
- Create Database :创建该数据库的完整 SQL 语句,包含所有配置信息:
- 反引号(`):包裹数据库名称,避免名称与关键字冲突(即使名称无冲突,MySQL 也会自动添加);
/*!40100 ... */:条件执行语法,格式为/*!版本号 语句 */,表示 "若当前 MySQL 版本≥指定版本,就执行语句",确保语法兼容性(如/*!40100 DEFAULT CHARACTER SET utf8mb4 */表示版本≥4.0.10 时执行该配置);DEFAULT CHARACTER SET和COLLATE:数据库的字符集和排序规则,确认配置是否生效;DEFAULT ENCRYPTION='Y':数据库加密状态(Y = 加密,N = 不加密);COMMENT:数据库注释,说明数据库用途。
那么大家这里只使用上面的语句的话,会发现说,显示结果是杂糅在一起的,看的压根不清楚明了,有木有什么办法去将输出内容格式化呢??
诶有的有的,那就是将语句末尾的分号替换为\G,即可,就是这样子:
sql
SHOW CREATE DATABASE db_name\G
这样子就可以格式化输出了,执行后会以垂直键值对的形式展示,每个字段单独一行,长内容会自动换行,注意是将分号进行替换。

4.3 查看当前连接的数据库:SELECT DATABASE ()
当你连接到 MySQL 服务器后,可能会操作多个数据库,需要确认当前正在操作的是哪个数据库,避免操作错误,注意这个一般是在use数据库之后,再使用该语句去进行查看我们当前是在操作哪一个数据库哦,这个其实就是select语句,后面我们也会说到。
语法
SELECT DATABASE();
示例 1:未选择数据库时查询
# 刚连接到MySQL,未执行USE命令
SELECT DATABASE();
执行结果:
+------------+
| DATABASE() |
+------------+
| NULL |
+------------+
1 row in set (0.00 sec)

示例 2:选择数据库后查询
# 选择db_chinese数据库
USE db_chinese;
# 查看当前数据库
SELECT DATABASE();
执行结果:
+------------+
| DATABASE() |
+------------+
| db_chinese |
+------------+
1 row in set (0.00 sec)

应用场景
- 执行重要操作(如删除表、修改数据)前,确认当前数据库是否正确,避免误操作其他数据库;
- 脚本执行过程中,通过该命令判断是否已成功选择数据库。
4.4 查看系统默认字符集和排序规则
若需确认 MySQL 服务器的全局默认字符集(影响未指定字符集的数据库创建),可使用SHOW VARIABLES命令查询。
语法
# 查看全局默认字符集
SHOW VARIABLES LIKE 'character_set_server';
# 查看全局默认排序规则
SHOW VARIABLES LIKE 'collation_server';
# 查看当前会话的字符集(影响当前连接的数据操作)
SHOW VARIABLES LIKE 'character_set_client';
SHOW VARIABLES LIKE 'character_set_connection';
执行结果(MySQL 8.0)
+----------------------+---------+
| Variable_name | Value |
+----------------------+---------+
| character_set_server | utf8mb4 |
+----------------------+---------+
1 row in set (0.01 sec)
+--------------------+--------------------+
| Variable_name | Value |
+--------------------+--------------------+
| collation_server | utf8mb4_0900_ai_ci |
+--------------------+--------------------+
1 row in set (0.00 sec)
结果解读
character_set_server:MySQL 服务器的全局默认字符集,新数据库未指定字符集时会继承该值;collation_server:全局默认排序规则,新数据库未指定排序规则时会继承该值;character_set_client和character_set_connection:当前会话的字符集,影响数据的发送和接收(若与数据库字符集不一致,可能导致乱码)。
这个咱们仅作了解,需要的时候copy一下即可,不用记忆。
如何修改全局默认字符集(可选)
若需修改全局默认字符集(如 MySQL 5.7 默认 latin1 改为 utf8mb4),需修改 MySQL 配置文件:
-
编辑配置文件(Linux:
/etc/mysql/mysql.conf.d/mysqld.cnf); -
添加以下配置:
[mysqld] character-set-server=utf8mb4 collation-server=utf8mb4_general_ci -
重启 MySQL 服务:
sudo systemctl restart mysql; -
验证修改结果:
SHOW VARIABLES LIKE 'character_set_server';。
4.5 查看 MySQL 支持的所有字符集和排序规则
若需了解 MySQL 支持的所有字符集(如确认是否支持某特殊编码),或某字符集对应的所有排序规则,可使用SHOW CHARSET和SHOW COLLATION命令。
4.5.1 查看所有支持的字符集
SHOW CHARSET;
执行结果片段:
+----------+---------------------------------+---------------------+--------+
| Charset | Description | Default collation | Maxlen |
+----------+---------------------------------+---------------------+--------+
| latin1 | cp1252 West European | latin1_swedish_ci | 1 |
| gbk | GBK Simplified Chinese | gbk_chinese_ci | 2 |
| utf8 | UTF-8 Unicode | utf8_general_ci | 3 |
| utf8mb4 | UTF-8 Unicode | utf8mb4_0900_ai_ci | 4 |
| gb2312 | GB2312 Simplified Chinese | gb2312_chinese_ci | 2 |
| big5 | Big5 Traditional Chinese | big5_chinese_ci | 2 |
+----------+---------------------------------+---------------------+--------+

字段解读
Charset:字符集名称;Description:字符集描述(支持的语言、编码标准);Default collation:该字符集的默认排序规则;Maxlen:该字符集下单个字符的最大字节数(如 utf8mb4 最大 4 字节,支持 emoji)。
4.5.2 查看所有支持的排序规则(过滤查询)
# 查看所有排序规则(数量较多,不推荐直接执行)
# SHOW COLLATION;
# 过滤查询:只查看utf8mb4字符集对应的排序规则
SHOW COLLATION LIKE 'utf8mb4%';
执行结果片段:
+------------------------------+---------+-----+---------+----------+---------+
| Collation | Charset | Id | Default | Compiled | Sortlen |
+------------------------------+---------+-----+---------+----------+---------+
| utf8mb4_general_ci | utf8mb4 | 45 | | Yes | 1 |
| utf8mb4_bin | utf8mb4 | 46 | | Yes | 1 |
| utf8mb4_unicode_ci | utf8mb4 | 224 | | Yes | 8 |
| utf8mb4_0900_ai_ci | utf8mb4 | 255 | Yes | Yes | 1 |
| utf8mb4_0900_bin | utf8mb4 | 309 | | Yes | 1 |
+------------------------------+---------+-----+---------+----------+---------+
字段解读
Collation:排序规则名称;Charset:该排序规则所属的字符集;Id:排序规则的唯一 ID;Default:是否为对应字符集的默认排序规则(Yes = 是);Compiled:是否已编译(Yes = 是,执行效率更高);Sortlen:排序时的比较长度(数值越大,排序越精准,但效率越低)。
4.6 通过 information_schema 查询数据库元数据(高级用法)
information_schema是 MySQL 的系统数据库,存储了所有数据库、表、字段的元数据(描述数据的数据)。通过查询该数据库的SCHEMATA表,可获取更详细的数据库信息(如创建时间、字符集、注释等)。
语法
SELECT 字段名 FROM information_schema.SCHEMATA WHERE 条件;
示例 1:查询所有用户创建的数据库(排除系统库)
SELECT
SCHEMA_NAME AS '数据库名称',
DEFAULT_CHARACTER_SET_NAME AS '字符集',
DEFAULT_COLLATION_NAME AS '排序规则',
COMMENT AS '注释',
CREATION_TIME AS '创建时间'
FROM information_schema.SCHEMATA
WHERE SCHEMA_NAME NOT IN ('information_schema', 'mysql', 'performance_schema', 'sys');
执行结果:
+----------------+----------+--------------------+--------------------------------------------------+---------------------+
| 数据库名称 | 字符集 | 排序规则 | 注释 | 创建时间 |
+----------------+----------+--------------------+--------------------------------------------------+---------------------+
| blog_test | utf8mb4 | utf8mb4_unicode_ci | 国际化多语言库,支持中日韩等多国语言,区分重音 | 2025-01-15 10:30:00 |
| db_chinese | utf8mb4 | utf8mb4_general_ci | 普通中文库,不区分大小写 | 2025-01-15 10:35:00 |
| ecommerce_prod | utf8mb4 | utf8mb4_general_ci | 电商生产库,存储订单、用户、支付等敏感数据,已加密 | 2025-01-15 11:00:00 |
+----------------+----------+--------------------+--------------------------------------------------+---------------------+
示例 2:查询指定数据库的详细信息
SELECT * FROM information_schema.SCHEMATA WHERE SCHEMA_NAME = 'ecommerce_prod';
说明:
information_schema.SCHEMATA表包含数据库的所有元数据,字段丰富(如DEFAULT_ENCRYPTION、SQL_PATH等);- 适合需要批量获取数据库信息、自动化脚本开发等场景;
- 普通用户仅能查询,无法修改该表数据。
这一个操作,在我们后面学习了表的操作之后,就知道了。
五、选择数据库:USE 语句的使用与细节(操作数据表的前提)
创建并查看数据库后,若要对数据库进行后续操作(如创建表、插入数据、查询数据),必须先 "进入" 该数据库 ------ 这就是USE语句的核心作用。USE语句看似简单,但有很多细节需要注意,避免操作错误。
5.1 语法
USE db_name;
语法说明
db_name:要进入的数据库名称(必须是已存在的数据库,否则会报错);- 执行成功后,MySQL 会返回
Database changed提示,表示当前数据库已切换; - 后续所有 SQL 操作(如 CREATE TABLE、INSERT、SELECT)都会默认作用于该数据库,直到再次执行
USE语句切换数据库或退出连接。
5.2 示例
示例 1:切换到已存在的数据库
# 切换到db_chinese数据库
USE db_chinese;
执行结果:
Database changed
示例 2:切换到不存在的数据库(错误示例)
# 错误:db_not_exist不存在
USE db_not_exist;
报错信息:
ERROR 1049 (42000): Unknown database 'db_not_exist'
示例 3:切换数据库后执行操作
# 切换到db_chinese
USE db_chinese;
# 创建表(默认创建在db_chinese数据库中)
CREATE TABLE IF NOT EXISTS user (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(50) NOT NULL
);
# 插入数据(默认插入到db_chinese.user表中)
INSERT INTO user (name) VALUES ('张三'), ('李四');
# 查询数据(默认查询db_chinese.user表)
SELECT * FROM user;
执行结果:
+----+------+
| id | name |
+----+------+
| 1 | 张三 |
| 2 | 李四 |
+----+------+
2 rows in set (0.00 sec)

这一些操作都是比较简单的,就是
sql
use+database+数据库名字;
即可
5.3 查看当前数据库的表:SHOW TABLES(USE 后的常用操作)
切换到数据库后,通常需要查看该数据库中有哪些表,可使用SHOW TABLES命令,这个和show databases;类似,一样的用法一样的作用,只不过一个是看数据库,一个是看表罢了。
语法
# 查看当前数据库的所有表
SHOW TABLES;
# 过滤查询:只查看符合条件的表
SHOW TABLES LIKE '匹配模式';
示例
# 切换到db_chinese
USE db_chinese;
# 查看所有表
SHOW TABLES;
# 过滤查看以"u"开头的表
SHOW TABLES LIKE 'u%';
执行结果:
+---------------------+
| Tables_in_db_chinese |
+---------------------+
| user |
+---------------------+
1 row in set (0.00 sec)
+---------------------+
| Tables_in_db_chinese (u%) |
+---------------------+
| user |
+---------------------+
1 row in set (0.00 sec)

5.4 USE 语句的常见误区与注意事项
误区 1:"USE 语句会持久化生效"------ 错!
USE语句仅在当前连接会话中生效,退出连接或重新连接后,当前数据库会重置为NULL,需重新执行USE语句选择数据库。
示例验证
- 连接 MySQL,执行
USE db_chinese;,切换到 db_chinese; - 执行
exit;退出连接; - 重新连接 MySQL,执行
SELECT DATABASE();,结果为NULL(未选择数据库)。
解决方案
- 手动操作时,重新连接后需再次执行
USE语句; - 自动化脚本中,每次连接后都需显式执行
USE语句,避免依赖之前的连接状态。
误区 2:"创建表时必须先 USE 数据库"------ 不完全对!
虽然推荐先USE数据库再创建表,但也可以在创建表时直接指定数据库名,无需提前USE。
示例:不 USE 数据库,直接创建表
# 未执行USE语句,直接创建db_chinese.user表
CREATE TABLE IF NOT EXISTS db_chinese.product (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(100) NOT NULL,
price DECIMAL(10,2) DEFAULT 0
);
# 未执行USE语句,直接查询db_chinese.product表
SELECT * FROM db_chinese.product;
说明:
- 语法格式为
数据库名.表名,适用于需要操作多个数据库的表的场景; - 缺点是每次操作都需写数据库名,繁琐且易出错,推荐仅在特殊场景使用。
误区 3:"切换数据库后,之前的变量和会话配置会丢失"------ 对!
USE语句切换数据库后,当前会话的部分配置(如用户变量、会话级变量)不会丢失,但与数据库相关的配置(如character_set_database)会切换为新数据库的配置。
示例验证
# 切换到db_chinese(字符集utf8mb4)
USE db_chinese;
SET @user_name = '张三'; # 创建会话变量
SELECT @user_name; # 输出:张三
# 切换到db_gbk(字符集gbk)
USE db_gbk;
SELECT @user_name; # 输出:张三(会话变量未丢失)
SELECT @@character_set_database; # 输出:gbk(切换为新数据库的字符集)
注意事项
- 会话变量(如
@user_name)在整个连接会话中有效,切换数据库不影响; - 系统变量(如
character_set_database)会随数据库切换而变化,需注意字符集一致性。
误区 4:"可以切换到系统库并修改数据"------ 不推荐!
虽然USE mysql;可以切换到 mysql 系统库,但系统库存储的是 MySQL 的核心配置(如用户权限、密码),随意修改可能导致 MySQL 无法正常运行。
安全建议
- 禁止在生产环境中修改系统库的表数据(如 mysql.user、mysql.db);
- 若需修改用户权限,使用
GRANT、REVOKE等专用命令,而非直接修改表数据。
六、修改数据库:ALTER DATABASE 详解(配置变更的正确方式)
数据库创建后,若需调整字符集、排序规则、加密状态等配置,可使用ALTER DATABASE语句。需要注意的是:数据库的修改操作仅影响 "后续创建的表",已存在的表不会自动继承新配置(需单独修改表的配置)。
6.1 完整语法
sql
ALTER DATABASE db_name
[alter_specification [, alter_specification] ...];
# 其中 alter_specification 是可选配置项,可同时修改多个配置
alter_specification:
[DEFAULT] CHARACTER SET charset_name # 修改默认字符集
[DEFAULT] COLLATE collation_name # 修改默认排序规则
[DEFAULT] ENCRYPTION = {'Y' | 'N'} # 修改加密状态(MySQL 8.0+)
COMMENT '新注释' # 修改数据库注释(MySQL 8.0+)
其实就是alter database 数据库名字 +要修改的东西以及内容,说起来,其实就是类似去把create 数据库的create换成alter罢了,后面的一模一样,大家自己观察一下就知道了。
语法说明
db_name:要修改的数据库名称(必须已存在);- 可同时修改多个配置项(如同时修改字符集和排序规则);
- 修改后的配置仅对 "修改后创建的表" 生效,已存在的表需单独修改。
6.2 常见修改场景示例
场景 1:修改数据库字符集和排序规则
# 原配置:字符集utf8,排序规则utf8_general_ci
# 目标:修改为utf8mb4字符集,utf8mb4_general_ci排序规则
ALTER DATABASE db_old
CHARACTER SET utf8mb4
COLLATE utf8mb4_general_ci;
# 验证修改结果
SHOW CREATE DATABASE db_old;
执行结果:
+----------+----------------------------------------------------------------------------------------------------------------------------------+
| Database | Create Database |
+----------+----------------------------------------------------------------------------------------------------------------------------------+
| db_old | CREATE DATABASE `db_old` /*!40100 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci */ /*!80016 DEFAULT ENCRYPTION='N' */ |
+----------+----------------------------------------------------------------------------------------------------------------------------------+
场景 2:修改数据库注释
# 原注释:"旧注释"
# 目标:修改为详细注释
ALTER DATABASE db_old
COMMENT '旧系统迁移库,已修改为utf8mb4字符集,支持中文和emoji';
# 验证修改结果
SELECT SCHEMA_NAME, COMMENT FROM information_schema.SCHEMATA WHERE SCHEMA_NAME = 'db_old';
执行结果:
+-------------+----------------------------------------------------------------------+
| SCHEMA_NAME | COMMENT |
+-------------+----------------------------------------------------------------------+
| db_old | 旧系统迁移库,已修改为utf8mb4字符集,支持中文和emoji |
+-------------+----------------------------------------------------------------------+
场景 3:MySQL 8.0+ 修改数据库加密状态
# 原状态:未加密(ENCRYPTION='N')
# 目标:启用加密
ALTER DATABASE ecommerce_prod
ENCRYPTION = 'Y';
# 验证修改结果
SHOW CREATE DATABASE ecommerce_prod;
执行结果:
+----------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Database | Create Database |
+----------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ecommerce_prod | CREATE DATABASE `ecommerce_prod` /*!40100 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci */ /*!80016 DEFAULT ENCRYPTION='Y' */ COMMENT '电商生产库,存储订单、用户、支付等敏感数据,已加密,负责人:李四' |
+----------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
场景 4:同时修改多个配置项
# 同时修改字符集、排序规则、注释
ALTER DATABASE db_multi
CHARACTER SET utf8mb4
COLLATE utf8mb4_unicode_ci
COMMENT '多语言库,支持中日韩,区分重音';
# 验证修改结果
SHOW CREATE DATABASE db_multi;
那么修改数据库的示例我就不展示了,还是比较简单的。
6.3 关键注意事项
注意 1:字符集修改的兼容性风险
修改数据库字符集时,需注意 "窄字符集" 和 "宽字符集" 的兼容性:
- 从 "窄字符集" 改为 "宽字符集"(如 latin1→utf8mb4、utf8→utf8mb4):兼容性好,不会丢失数据(宽字符集包含窄字符集的所有字符);
- 从 "宽字符集" 改为 "窄字符集"(如 utf8mb4→latin1、utf8mb4→gbk):风险高,可能导致数据丢失(窄字符集不支持宽字符集的部分字符,如 emoji、特殊符号)。
错误示例:从 utf8mb4 改为 latin1(风险高)
# 错误:latin1不支持中文和emoji,会导致已有中文数据乱码或丢失
ALTER DATABASE db_chinese
CHARACTER SET latin1
COLLATE latin1_swedish_ci;
解决方案
- 生产环境中,禁止从宽字符集改为窄字符集;
- 若必须修改,需先备份数据库,然后检查数据中是否包含窄字符集不支持的字符,确保无风险后再执行。
注意 2:已创建的表不会继承新配置
这是最容易被新手忽略的点:修改数据库的字符集、排序规则后,该数据库中已存在的表,其字符集和排序规则不会自动同步修改,仅对修改后创建的新表生效。
示例验证
-
创建数据库并创建表:
sql# 创建数据库,字符集utf8 CREATE DATABASE IF NOT EXISTS db_test_alter CHARACTER SET utf8; # 切换到数据库,创建表(继承数据库的utf8字符集) USE db_test_alter; CREATE TABLE IF NOT EXISTS user (name VARCHAR(50)); # 查看表的字符集(utf8) SHOW CREATE TABLE user; -
修改数据库字符集为 utf8mb4:
ALTER DATABASE db_test_alter CHARACTER SET utf8mb4; -
查看已存在的表的字符集(仍为 utf8,未同步修改):
SHOW CREATE TABLE user;
执行结果:
+-------+-------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+-------+-------------------------------------------------------------------------------------------------------------------+
| user | CREATE TABLE `user` (
`name` varchar(50) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
+-------+-------------------------------------------------------------------------------------------------------------------+
-
创建新表(继承新的 utf8mb4 字符集):
# 在修改后的数据库中创建新表 CREATE TABLE IF NOT EXISTS product (name VARCHAR(100)); # 查看新表的字符集(utf8mb4,继承了数据库的新配置) SHOW CREATE TABLE product;
执行结果:
+---------+----------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+---------+----------------------------------------------------------------------------------------------------------------------+
| product | CREATE TABLE `product` (
`name` varchar(100) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 |
+---------+----------------------------------------------------------------------------------------------------------------------+
-
修改已存在表的字符集(手动同步):若需让已存在的表同步数据库的新字符集,需单独执行
ALTER TABLE语句:# 修改user表的字符集为utf8mb4 ALTER TABLE user CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; # 验证修改结果 SHOW CREATE TABLE user;
执行结果:
+-------+----------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+-------+----------------------------------------------------------------------------------------------------------------------+
| user | CREATE TABLE `user` (
`name` varchar(50) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 |
+-------+----------------------------------------------------------------------------------------------------------------------+
注意 3:排序规则必须与字符集匹配
修改排序规则时,必须选择当前字符集支持的排序规则,否则会抛出错误。
错误示例:排序规则与字符集不匹配
# 错误:utf8mb4字符集不支持utf8_general_ci排序规则
ALTER DATABASE db_test_alter
CHARACTER SET utf8mb4
COLLATE utf8_general_ci;
报错信息:
ERROR 1273 (HY000): Unknown collation: 'utf8_general_ci'
解决方案
-
先通过
SHOW COLLATION LIKE '字符集%'查询该字符集支持的排序规则; -
选择匹配的排序规则进行修改:
# 正确:选择utf8mb4支持的utf8mb4_general_ci ALTER DATABASE db_test_alter CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
注意 4:修改加密状态的限制(MySQL 8.0+)
- 加密状态仅支持在
Y(加密)和N(不加密)之间切换; - 切换加密状态后,已存在的表会自动同步加密状态(与字符集修改不同);
- 加密功能依赖 MySQL 的密钥管理系统(KMS),若服务器未配置密钥,无法启用加密。
示例:切换加密状态后同步表加密
# 启用数据库加密
ALTER DATABASE ecommerce_prod ENCRYPTION = 'Y';
# 查看已存在表的加密状态(自动同步为加密)
SELECT TABLE_SCHEMA, TABLE_NAME, CREATE_OPTIONS
FROM information_schema.TABLES
WHERE TABLE_SCHEMA = 'ecommerce_prod' AND TABLE_NAME = 'order';
执行结果:
+--------------+------------+----------------+
| TABLE_SCHEMA | TABLE_NAME | CREATE_OPTIONS |
+--------------+------------+----------------+
| ecommerce_prod | order | ENCRYPTION='Y' |
+--------------+------------+----------------+
6.4 ALTER DATABASE 的适用场景与不适用场景
适用场景
- 数据库创建时字符集配置错误,需修改为 utf8mb4;
- 业务需求变更,需从 "不区分大小写" 改为 "区分大小写"(修改排序规则);
- 存储敏感数据,需启用数据库加密;
- 团队协作中,需补充或修改数据库注释,提升可维护性。
不适用场景
- 需修改数据库名称(ALTER DATABASE 不支持修改名称,需通过重命名或备份恢复实现);
- 需迁移数据库存储目录(需修改 MySQL 配置文件,而非 ALTER DATABASE);
- 需批量修改已存在表的字符集(ALTER DATABASE 仅影响新表,已存在表需单独处理)。
七、删除数据库:DROP DATABASE 终极指南(高危操作,谨慎执行)
删除数据库是 MySQL 中最危险的操作之一 ------ 执行后,数据库对应的物理目录会被彻底删除,包含的所有数据表、数据记录、索引等都会永久丢失,且无法通过 MySQL 自身功能恢复(除非有备份)。
7.1 完整语法
DROP DATABASE [IF EXISTS] db_name;
语法关键字解读
| 关键字 / 选项 | 作用说明 | 是否可选 | 核心价值 |
|---|---|---|---|
| DROP DATABASE | 核心关键字组合,声明 "执行删除数据库的操作" | 必选 | 告诉 MySQL 服务器,当前要彻底删除数据库及其所有内容 |
| IF EXISTS | 条件判断:仅当数据库存在时才执行删除,若不存在则不执行操作,也不报错 | 可选 | 避免 "数据库不存在" 导致的脚本执行中断,是安全删除的基础 |
| db_name | 要删除的数据库名称 | 必选 | 明确指定目标数据库,避免误删其他数据库 |
7.2 示例:安全删除数据库
示例 1:添加 IF EXISTS,安全删除已存在的数据库
# 推荐写法:删除电商测试库,添加IF EXISTS避免报错
DROP DATABASE IF EXISTS ecommerce_test;
执行结果(删除成功):
Query OK, 0 rows affected (0.03 sec)

执行结果(数据库不存在):
Query OK, 0 rows affected, 1 warning (0.00 sec)
示例 2:未添加 IF EXISTS,删除不存在的数据库(错误示例)
# 错误:删除不存在的数据库,抛出错误
DROP DATABASE db_not_exist;
报错信息:
ERROR 1008 (HY000): Can't drop database 'db_not_exist'; database doesn't exist
示例 3:生产环境删除前的验证流程(推荐)
sql
# 步骤1:查看数据库是否存在(避免拼写错误)
SHOW DATABASES LIKE 'ecommerce_old';
# 步骤2:若存在,备份数据库(生产环境必做)
# mysqldump -uroot -p -B ecommerce_old > /home/backup/ecommerce_old_backup.sql
# 步骤3:安全删除数据库
DROP DATABASE IF EXISTS ecommerce_old;
那么一样的,删除数据库也是很简单的操作,所以我这里也就不多余演示,大家只需要会drop database 数据库名字 即可。
7.3 删除数据库的严重后果
执行DROP DATABASE后,会产生以下不可逆后果,需在执行前反复确认:
- 物理目录彻底删除 :数据库对应的物理目录(默认在
/var/lib/mysql/下)会被 MySQL 服务器彻底删除,包含该目录下的所有文件(表文件、索引文件、日志文件等); - 所有数据永久丢失:数据库内的所有数据表、数据记录、视图、存储过程、触发器等对象会被一并删除,无任何残留;
- 相关权限自动失效:之前授予用户的针对该数据库的所有权限(如 SELECT、INSERT、UPDATE)会自动失效,不会影响其他数据库的权限;
- 无法通过 MySQL 恢复:MySQL 没有 "回收站" 功能,删除后无法通过自身工具恢复,只能依赖提前备份的文件。
7.4 高危操作的安全防护措施
为避免误删数据库导致的数据灾难,需严格遵循以下安全措施,形成 "多道防线":
防线 1:所有删除操作必加 IF EXISTS
无论数据库是否存在,都必须添加IF EXISTS选项 ------ 即使你确认数据库存在,也能避免因拼写错误(如把ecommerce_test写成ecommerce_prod)导致的误删。
防线 2:执行前先验证数据库名称
删除前必须通过SHOW DATABASES LIKE 'db_name';确认数据库存在,且名称正确(尤其是生产环境)。
防线 3:生产环境必须先备份
删除生产环境的数据库前,必须先执行完整备份(使用mysqldump工具),并验证备份文件的可用性(如测试恢复)。备份文件需存储在异地(如云存储、移动硬盘),避免服务器故障导致备份文件丢失。
防线 4:生产环境禁止直接删除,先重命名观察
生产环境中,若需删除数据库,建议先 "重命名数据库",观察一段时间(如 1 周)确认无业务依赖后,再删除旧数据库:
# 步骤1:创建新名称的空数据库(临时占位)
CREATE DATABASE IF NOT EXISTS ecommerce_old_backup;
# 步骤2:重命名旧数据库(实际是通过备份恢复实现,MySQL无直接重命名命令)
# 备份旧数据库
mysqldump -uroot -p -B ecommerce_old > /home/backup/ecommerce_old_dump.sql;
# 删除旧数据库
DROP DATABASE IF EXISTS ecommerce_old;
# 恢复为新名称(模拟重命名)
mysql -uroot -p ecommerce_old_backup < /home/backup/ecommerce_old_dump.sql;
# 步骤3:观察1周,确认无业务访问 ecommerce_old_backup 后,再删除
# DROP DATABASE IF EXISTS ecommerce_old_backup;
防线 5:限制删除权限
生产环境中,仅给管理员(如 root)分配DROP DATABASE权限,普通开发人员、测试人员仅授予查询、修改权限(如 SELECT、INSERT、UPDATE),禁止授予DROP权限。
防线 6:开启二进制日志(binlog)
二进制日志记录了所有数据操作(包括创建、修改、删除),若误删数据库,可通过 binlog 恢复到删除前的状态(需提前开启):
-
开启 binlog:修改 MySQL 配置文件(
/etc/mysql/mysql.conf.d/mysqld.cnf),添加:[mysqld] server-id=1 log_bin=/var/log/mysql/mysql-bin.log -
重启 MySQL 服务:
sudo systemctl restart mysql; -
查看 binlog:
mysqlbinlog /var/log/mysql/mysql-bin.000001; -
恢复数据:
mysqlbinlog --stop-datetime="2025-01-20 10:00:00" /var/log/mysql/mysql-bin.000001 | mysql -uroot -p。
防线 7:使用数据库审计工具
生产环境可部署数据库审计工具(如 MySQL Enterprise Audit、阿里云数据库审计),记录所有DROP DATABASE操作,便于误删后追溯操作人、操作时间,同时起到威慑作用。
7.5 禁止删除的数据库(系统库)
以下系统数据库是 MySQL 运行的核心,禁止执行DROP DATABASE操作,否则会导致 MySQL 无法正常运行:
information_schema:存储元数据,删除后无法查看数据库、表结构;mysql:存储用户权限、密码,删除后无法登录 MySQL;performance_schema:存储性能监控数据,删除后无法进行性能分析;sys:简化性能监控视图,删除后影响系统状态查看。
错误示例:尝试删除 mysql 系统库
# 错误:禁止删除系统库
DROP DATABASE IF EXISTS mysql;
报错信息(MySQL 8.0):
ERROR 3630 (HY000): The database 'mysql' is system database and cannot be dropped.
7.6 常见删除场景与操作建议
场景 1:测试环境删除临时数据库
# 适用:开发测试完成后,删除临时测试库
DROP DATABASE IF EXISTS temp_test_db;
操作建议:
- 测试环境可直接删除,无需复杂流程;
- 若临时库包含重要测试数据,建议先备份。
场景 2:生产环境删除废弃数据库
# 适用:业务下线后,删除不再使用的数据库
# 步骤1:备份
mysqldump -uroot -p -B obsolete_db > /home/backup/obsolete_db_20250120.sql;
# 步骤2:验证备份
mysql -uroot -p -e "CREATE DATABASE IF NOT EXISTS obsolete_db_backup; USE obsolete_db_backup; source /home/backup/obsolete_db_20250120.sql;"
# 步骤3:删除原数据库
DROP DATABASE IF EXISTS obsolete_db;
操作建议:
- 必须执行备份和备份验证步骤;
- 删除后观察 1-2 周,确认无业务依赖后,再删除备份文件。
场景 3:误删数据库后的应急恢复
# 适用:误删数据库后,通过备份恢复
# 步骤1:停止相关业务服务,避免数据写入
# 步骤2:创建空数据库
CREATE DATABASE IF NOT EXISTS restored_db;
# 步骤3:恢复备份
mysql -uroot -p restored_db < /home/backup/obsolete_db_20250120.sql;
# 步骤4:验证数据
mysql -uroot -p -e "USE restored_db; SELECT COUNT(*) FROM user;"
# 步骤5:恢复业务服务
操作建议:
- 误删后立即停止业务服务,避免新数据写入导致恢复后数据不一致;
- 恢复后务必验证数据完整性(如查询核心表的记录数)。
八、数据库备份与恢复:数据安全的最后一道防线
数据库的备份与恢复是保障数据安全的核心手段,也是每个开发者必须掌握的技能。无论是误删数据、服务器故障,还是黑客攻击,定期备份都能让你快速恢复数据,减少损失。
8.1 备份工具介绍:mysqldump(MySQL 自带,推荐)
mysqldump是 MySQL 官方提供的命令行备份工具,支持全量备份、增量备份,备份结果为 SQL 脚本文件(包含创建数据库、表、插入数据的语句),具有以下优势:
- 跨平台兼容:支持 Linux、Windows、MacOS;
- 操作简单:仅需一条命令即可完成备份;
- 灵活性高:支持备份单个数据库、多个数据库、所有数据库,或指定表;
- 恢复方便:备份文件可直接通过
source命令或 mysql 客户端执行恢复。
它的实质其实就是把我们对这个被备份的数据库的所有操作都记录下来放进备份文件中,然后等我们source它恢复数据库的时候,诶嘿,mysql就会把备份文件中的所有的操作都重新执行一遍。
8.2 备份操作:mysqldump 详细用法
8.2.1 基础语法(命令行执行,非 MySQL 交互终端),注意,是不能在MySQL交互终端使用的哦,只能在命令行去执行,注意注意!!!
sql
# 基础语法:备份单个数据库
mysqldump -u 用户名 -p -P 端口 -h 主机地址 -B 数据库名 > 备份文件路径.sql
# 常用参数说明
-u:指定MySQL用户名(如root);
-p:提示输入密码(推荐,安全性高);
-P:指定MySQL端口(默认3306,可省略);
-h:指定MySQL主机地址(本地为localhost,远程为服务器IP);
-B:必选参数,作用:1. 备份文件中包含CREATE DATABASE语句;2. 自动执行USE语句;3. 支持备份多个数据库;
>:重定向符号,将备份结果写入指定文件;
备份文件路径:备份文件的存储路径(需确保目录存在且有写入权限)。
那么聪明的你其实很容易就你发现,mysqldump的用法其实就和我们在命令行链接mysql的用法差不多,只不过是从mysql变为了mysqldump,然后后面跟上-B 数据库名字 > 备份文件路径.sql,注意备份文件要以.sql结尾哦,同样是可以指定字符集的。还是比较容易记忆滴
8.2.2 常见备份场景示例
场景 1:备份本地单个数据库(带字符集指定)
# 备份db_chinese数据库到/home/backup目录,文件名包含日期(便于区分)
mysqldump -uroot -p -B db_chinese --default-character-set=utf8mb4 > /home/backup/db_chinese_backup_20250120.sql
执行流程:
- 输入命令后,按回车,系统提示输入 MySQL 密码;
- 密码正确后,开始备份,备份完成后无提示(可通过文件大小判断是否成功);
- 查看备份文件:
ls -l /home/backup/db_chinese_backup_20250120.sql。


场景 2:备份本地多个数据库
# 同时备份db_chinese、blog_test、ecommerce_prod三个数据库
mysqldump -uroot -p -B db_chinese blog_test ecommerce_prod --default-character-set=utf8mb4 > /home/backup/multi_db_backup_20250120.sql
说明:
- 多个数据库名之间用空格分隔;
- 备份文件中会包含每个数据库的 CREATE DATABASE 和 USE 语句,恢复时会自动创建并切换数据库。
场景 3:备份远程数据库(服务器 IP:192.168.1.100)
# 备份远程服务器上的ecommerce_prod数据库
mysqldump -uroot -p -h192.168.1.100 -P3306 -B ecommerce_prod --default-character-set=utf8mb4 > /home/backup/ecommerce_prod_remote_backup.sql
前提条件:
- 远程 MySQL 服务器已开放 3306 端口;
- 备份用户(如 root)具有远程访问权限;
- 本地能 ping 通远程服务器。
场景 4:备份数据库时排除指定表
# 备份db_chinese数据库,但排除user和order表(表级排除,数据库级备份不常用)
mysqldump -uroot -p -B db_chinese --ignore-table=db_chinese.user --ignore-table=db_chinese.order --default-character-set=utf8mb4 > /home/backup/db_chinese_without_user_order.sql
说明:
--ignore-table参数格式为 "数据库名。表名";- 若需排除多个表,可多次使用
--ignore-table参数。 - 这个也是比较常用的一个操作,就是带上 --ignore-table 而已。
场景 5:备份所有数据库(包含系统库)
# 备份MySQL服务器上的所有数据库(谨慎使用,系统库备份文件较大)
mysqldump -uroot -p -A --default-character-set=utf8mb4 > /home/backup/all_db_backup_20250120.sql
说明:
-A是--all-databases的缩写,备份所有数据库;- 包含系统库(如 mysql、information_schema),恢复时会覆盖原有系统配置,生产环境需谨慎使用。
场景 6:压缩备份(节省存储空间)
# 备份并通过gzip压缩,生成.sql.gz文件
mysqldump -uroot -p -B db_chinese --default-character-set=utf8mb4 | gzip > /home/backup/db_chinese_backup_20250120.sql.gz
说明:
- 压缩后的文件大小仅为原文件的 1/3-1/5,节省存储空间;
- 恢复时需先解压:
gzip -d db_chinese_backup_20250120.sql.gz。
8.3 恢复操作:两种核心方法
恢复数据库是备份的逆操作,即将备份的 SQL 脚本文件执行到 MySQL 服务器中,重建数据库和数据。常用的恢复方法有两种:source命令(MySQL 交互终端)和 mysql 客户端(命令行)。
8.3.1 方法 1:MySQL 交互终端中使用 source 命令
就是
sql
source+备份文件路径以及名字


# 步骤1:连接MySQL服务器
mysql -uroot -p
# 步骤2:(可选)删除已存在的目标数据库(避免表结构冲突)
DROP DATABASE IF EXISTS db_chinese;
# 步骤3:执行source命令恢复(指定备份文件的绝对路径)
source /home/backup/db_chinese_backup_20250120.sql;
执行结果:
Query OK, 0 rows affected (0.00 sec)
Query OK, 0 rows affected (0.01 sec)
...
Query OK, 10 rows affected (0.02 sec)
Records: 10 Duplicates: 0 Warnings: 0
说明:
- 恢复过程中会显示每个 SQL 语句的执行结果(Query OK 表示成功);
- 若备份文件包含
CREATE DATABASE语句(使用-B参数备份),可省略步骤 2(删除旧数据库),恢复时会自动创建; - 若备份文件未包含
CREATE DATABASE语句(未使用-B参数),需先手动创建空数据库,再执行USE 数据库名;,最后执行source命令,说白了就是-B的时候,备份文件里会自动存储上创建该数据库的命令。
8.3.2 方法 2:命令行直接执行(非交互模式,适合脚本自动化)
其实就是把原本我们备份数据库的>换为<,然后没有-B 数据库名字罢了。
sql
mysql -u root -p < 备份文件路径+名字.sql
so so easy.

# 语法:mysql -u用户名 -p 数据库名 < 备份文件路径.sql
# 示例1:备份文件包含CREATE DATABASE(使用-B参数),无需指定数据库名
mysql -uroot -p < /home/backup/db_chinese_backup_20250120.sql
# 示例2:备份文件不包含CREATE DATABASE(未使用-B参数),需指定数据库名
# 步骤1:创建空数据库
mysql -uroot -p -e "CREATE DATABASE IF NOT EXISTS db_chinese;"
# 步骤2:恢复数据到指定数据库
mysql -uroot -p db_chinese < /home/backup/db_chinese_backup_20250120.sql
说明:
- 输入命令后,按回车,系统提示输入 MySQL 密码;
- 密码正确后,后台执行恢复操作,无中间输出(可通过查看数据库表确认是否成功);
- 适合自动化脚本(如 crontab 定时恢复测试)。
8.4 备份与恢复的关键注意事项
注意 1:字符集一致性(避免中文乱码)
备份和恢复时必须使用相同的字符集,否则会导致中文乱码:
-
备份时指定
--default-character-set=utf8mb4; -
恢复时也需指定字符集:
# 命令行恢复时指定字符集 mysql -uroot -p --default-character-set=utf8mb4 db_chinese < /home/backup/db_chinese_backup_20250120.sql
注意 2:恢复前的准备工作
- 生产环境恢复前,必须停止相关业务服务,避免恢复过程中数据被修改(导致数据不一致);
- 恢复前若目标数据库已存在,建议先备份当前数据库(避免恢复失败后原数据丢失);
- 确保 MySQL 服务器有足够的磁盘空间(恢复后的数据大小不超过磁盘剩余空间)。
注意 3:备份文件的安全性
-
备份文件包含数据库的所有数据(可能含敏感信息如用户密码、支付记录),需设置严格的文件权限,也就是使用chmod指令:
# 仅允许所有者读写,其他用户无权限 chmod 600 /home/backup/db_chinese_backup_20250120.sql -
建议将备份文件存储在异地(如云存储、移动硬盘),避免服务器硬盘损坏导致备份文件丢失;
-
定期更换备份文件的存储介质(如每月更换一次移动硬盘),防止介质老化。
注意 4:定期备份策略(生产环境必遵循)
-
备份频率 :根据数据更新频率调整:
- 核心业务库(如订单、支付):每天备份一次(全量备份);
- 非核心业务库(如博客文章、商品分类):每周备份一次;
- 数据更新极快的库(如实时统计):每天全量备份 + 每小时增量备份;
-
自动化备份 :使用 crontab(Linux)或任务计划程序(Windows)定时执行备份脚本,避免手动备份遗漏:
# Linux crontab示例:每天凌晨2点自动备份db_chinese数据库 0 2 * * * mysqldump -uroot -p123456 -B db_chinese --default-character-set=utf8mb4 > /home/backup/db_chinese_backup_$(date +%Y%m%d).sql -
备份验证:每月至少一次恢复测试,验证备份文件的可用性(如恢复到测试环境,检查数据完整性);
-
备份文件保留期限:保留最近 3 个月的备份文件,超过期限的可删除(或迁移到低成本存储),避免占用过多空间。
注意 5:增量备份与全量备份的结合(大数据量场景)
对于数据量较大的数据库(如 100GB 以上),每天全量备份会占用大量存储空间和带宽,可采用 "全量备份 + 增量备份" 的组合策略:
- 全量备份:每周日凌晨执行一次全量备份;
- 增量备份:周一至周六凌晨执行增量备份(仅备份前一天新增或修改的数据);
- 恢复时:先恢复最新的全量备份,再依次恢复后续的增量备份。
增量备份示例(使用 mysqldump+binlog)
# 步骤1:开启binlog(已在之前配置)
# 步骤2:每周日执行全量备份,并重置binlog
mysqldump -uroot -p -B db_large --default-character-set=utf8mb4 > /home/backup/full_backup_$(date +%Y%m%d).sql
mysql -uroot -p -e "FLUSH LOGS;" # 重置binlog,生成新的日志文件
# 步骤3:周一至周六执行增量备份(备份binlog文件)
cp /var/log/mysql/mysql-bin.00000* /home/backup/incremental_$(date +%Y%m%d)/
九、查看数据库连接情况:SHOW PROCESSLIST(排查性能问题)
在实际应用中,数据库连接数过多、存在慢查询或异常连接,可能导致服务器性能下降、响应变慢,甚至出现 "连接超时"。SHOW PROCESSLIST命令可实时查看当前所有连接到 MySQL 服务器的会话,帮助你排查连接异常、定位慢查询、优化服务器性能。
9.1 语法
# 查看所有连接(默认显示前100条,需root权限)
SHOW PROCESSLIST;
# 查看所有连接(无条数限制,显示完整SQL语句)
SHOW FULL PROCESSLIST;
语法说明
SHOW PROCESSLIST默认仅显示前 100 条连接,且Info字段仅显示 SQL 语句的前 100 个字符;SHOW FULL PROCESSLIST无条数限制,且Info字段显示完整的 SQL 语句(适合定位长 SQL);- 普通用户仅能查看自己的连接,root 用户可查看所有连接。

9.2 执行结果详细解读
+----+------+-----------------+--------------+---------+------+-------+-----------------------+
| Id | User | Host | db | Command | Time | State | Info |
+----+------+-----------------+--------------+---------+------+-------+-----------------------+
| 2 | root | localhost | db_chinese | Sleep | 1386 | | NULL |
| 3 | root | localhost | NULL | Query | 0 | NULL | show full processlist |
| 4 | test | 192.168.1.100:54321 | ecommerce_prod | Query | 5 | Executing | SELECT * FROM order WHERE user_id=100 AND create_time>='2025-01-01' |
| 5 | app | 192.168.1.101:65432 | blog_test | Sleep | 60 | | NULL |
+----+------+-----------------+--------------+---------+------+-------+-----------------------+
4 rows in set (0.00 sec)
字段逐字解读(核心重点)
| 字段 | 含义说明 | 实用价值 |
|---|---|---|
| Id | 连接会话的唯一 ID(线程 ID) | 用于杀死异常连接(KILL 会话ID;) |
| User | 发起连接的 MySQL 用户名 | 识别连接所属用户,排查异常用户登录(如陌生用户连接) |
| Host | 连接来源(本地连接显示localhost,远程连接显示 "IP: 端口") |
定位连接来源,排查异地异常连接(如黑客尝试登录) |
| db | 当前连接所在的数据库(NULL 表示未选择数据库) | 了解各数据库的连接分布,判断哪个数据库访问频繁 |
| Command | 连接的当前状态 | 关键状态:Sleep(空闲)、Query(执行查询)、Connect(正在连接)、Quit(退出) |
| Time | 连接持续时间(单位:秒) | 识别长时间空闲连接(Time>300 秒)或长时间执行的慢查询(Time>10 秒) |
| State | 连接的具体状态(仅 Query 状态时有值) | 如 Executing(正在执行 SQL)、Locked(等待锁)、Sorting result(排序结果) |
| Info | 正在执行的 SQL 语句(NULL 表示无执行语句,如 Sleep 状态) | 定位慢查询 SQL、异常操作 SQL(如全表扫描、大事务) |
9.3 实用场景:通过 PROCESSLIST 排查问题
场景 1:杀死长时间空闲的连接(释放资源)
长时间空闲的连接(如 Sleep 状态且 Time>300 秒)会占用服务器连接数资源,导致新连接无法建立:
# 步骤1:查看空闲时间超过300秒的连接
SHOW PROCESSLIST WHERE Command='Sleep' AND Time>300;
# 步骤2:杀死指定ID的连接(如ID=2)
KILL 2;
场景 2:定位执行时间过长的慢查询
慢查询(如执行时间超过 10 秒)会占用 CPU、内存资源,导致服务器响应变慢:
# 查看执行时间超过10秒的查询(Command='Query'表示正在执行SQL)
SHOW FULL PROCESSLIST WHERE Command='Query' AND Time>10;
示例结果:
+----+------+-----------------+--------------+---------+------+-----------+-----------------------+
| Id | User | Host | db | Command | Time | State | Info |
+----+------+-----------------+--------------+---------+------+-----------+-----------------------+
| 6 | app | 192.168.1.102:56789 | ecommerce_prod | Query | 15 | Executing | SELECT * FROM order WHERE total_price>1000 |
+----+------+-----------------+--------------+---------+------+-----------+-----------------------+
优化建议:
-
杀死慢查询连接:
KILL 6;; -
优化 SQL 语句:给
total_price字段添加索引,避免全表扫描; -
开启慢查询日志,长期监控慢查询:
SET GLOBAL slow_query_log=ON; SET GLOBAL long_query_time=10; # 执行时间超过10秒的SQL记录到慢查询日志
场景 3:识别异常登录连接(如黑客尝试)
若发现陌生 IP 的连接(尤其是 root 用户),可能是黑客尝试暴力破解:
# 查看非本地的root用户连接
SHOW PROCESSLIST WHERE User='root' AND Host<>'localhost';
安全措施:
-
杀死异常连接:
KILL 异常ID;; -
限制 root 用户仅允许本地连接:
DROP USER 'root'@'%'; CREATE USER 'root'@'localhost' IDENTIFIED BY '你的密码'; GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION; FLUSH PRIVILEGES; -
加强密码复杂度,启用防火墙限制访问 IP。
场景 4:查看连接数分布(优化服务器配置)
# 统计各数据库的连接数
SELECT db, COUNT(*) AS connection_count FROM information_schema.PROCESSLIST GROUP BY db;
# 统计各用户的连接数
SELECT User, COUNT(*) AS connection_count FROM information_schema.PROCESSLIST GROUP BY User;
示例结果:
+--------------+-----------------+
| db | connection_count |
+--------------+-----------------+
| db_chinese | 5 |
| ecommerce_prod | 12 |
| blog_test | 3 |
+--------------+-----------------+
优化建议:
-
若 ecommerce_prod 连接数过多(12 个),可优化应用程序的连接池配置,减少不必要的连接;
-
调整 MySQL 的
max_connections参数(默认 151),增加最大连接数:SET GLOBAL max_connections=500;(需修改配置文件
my.cnf永久生效)。
9.4 常见问题:PROCESSLIST 显示 "Too many connections"
现象
执行SHOW PROCESSLIST时,报错:
ERROR 1040 (08004): Too many connections
原因
MySQL 服务器的连接数已达到max_connections上限(默认 151),无法建立新连接。
解决方案
-
紧急处理:杀死空闲连接,释放资源:
# Linux命令:批量杀死Sleep状态超过300秒的连接 mysql -uroot -p -e "SELECT CONCAT('KILL ', Id, ';') FROM information_schema.PROCESSLIST WHERE Command='Sleep' AND Time>300;" | mysql -uroot -p -
临时调整最大连接数:
SET GLOBAL max_connections=500; -
永久优化:
-
修改配置文件
my.cnf:[mysqld] max_connections=500 wait_timeout=300 # 空闲连接超时时间(300秒),自动关闭 -
优化应用程序连接池:减少连接超时时间,避免连接泄露;
-
排查是否存在连接泄露(如应用程序未关闭连接)。
-
十、常见问题与陷阱
在数据库操作过程中,新手常遇到各种问题(如中文乱码、权限不足、连接失败)
10.1 中文乱码问题(最常见)
现象
- 插入中文数据后,查询显示为 "???` 或乱码;
- 备份文件中的中文显示乱码,恢复后数据异常。
原因
- 数据库字符集未指定为 utf8mb4(MySQL 5.7 默认 latin1);
- 连接时字符集与数据库字符集不一致;
- 备份 / 恢复时未指定字符集。
解决方案
-
数据库字符集设置为 utf8mb4:
ALTER DATABASE db_chinese CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; -
连接时指定字符集:
# 命令行连接 mysql -uroot -p --default-character-set=utf8mb4 # 图形化工具连接(如Navicat):在连接属性中设置字符集为utf8mb4 -
备份 / 恢复时指定字符集:
# 备份 mysqldump -uroot -p -B db_chinese --default-character-set=utf8mb4 > backup.sql # 恢复 mysql -uroot -p --default-character-set=utf8mb4 db_chinese < backup.sql -
已存在表的字符集同步:
ALTER TABLE user CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
10.2 数据库名称大小写敏感问题
现象
- Linux 系统中,
CREATE DATABASE Ecommerce;和CREATE DATABASE ecommerce;创建两个不同数据库; - Windows 系统中,上述命令创建一个数据库,切换数据库时
USE Ecommerce;和USE ecommerce;都有效。
原因
MySQL 的lower_case_table_names参数控制数据库名、表名的大小写敏感性:
- Linux 默认
lower_case_table_names=0(区分大小写); - Windows 默认
lower_case_table_names=1(不区分大小写); - Mac 默认
lower_case_table_names=2(存储时保留大小写,比较时不区分)。
解决方案
-
开发阶段统一数据库名大小写(推荐全小写),避免跨平台冲突;
-
生产环境修改
lower_case_table_names参数(需重启 MySQL):# 编辑配置文件my.cnf [mysqld] lower_case_table_names=1 # 不区分大小写(推荐生产环境配置) -
已有数据库的处理:
- 若数据库名包含大写字母,需先备份,删除原数据库,再用小写名称重建,最后恢复数据。
10.3 数据库名与关键字冲突
现象
创建数据库时使用 MySQL 关键字(如order、user、database),抛出语法错误:
CREATE DATABASE order;
报错信息:
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'order' at line 1
解决方案
-
避免使用关键字命名(推荐);
-
若必须使用,用反引号(`)包裹关键字:
CREATE DATABASE IF NOT EXISTS `order`; -
切换和删除时也需用反引号:
USE `order`; DROP DATABASE IF EXISTS `order`;
10.4 权限不足导致操作失败
现象
执行CREATE DATABASE、DROP DATABASE、ALTER DATABASE时,抛出权限错误:
ERROR 1044 (42000): Access denied for user 'test'@'localhost' to database 'db_new'
原因
当前用户没有对应的操作权限(如CREATE、DROP、ALTER权限)。
解决方案
-
使用 root 用户登录 MySQL,授予权限:
# 授予test用户创建数据库的全局权限 GRANT CREATE ON *.* TO 'test'@'localhost'; # 授予test用户删除db_old数据库的权限 GRANT DROP ON db_old.* TO 'test'@'localhost'; # 授予test用户修改db_chinese数据库的权限 GRANT ALTER ON db_chinese.* TO 'test'@'localhost'; # 刷新权限 FLUSH PRIVILEGES; -
生产环境遵循 "最小权限原则":
- 普通用户仅授予必要权限(如 SELECT、INSERT、UPDATE),不授予全局
CREATE、DROP权限; - 按业务场景分配数据库权限(如电商开发仅能操作 ecommerce_test 库)。
- 普通用户仅授予必要权限(如 SELECT、INSERT、UPDATE),不授予全局
10.5 数据库创建后无法显示
现象
执行CREATE DATABASE后,SHOW DATABASES无法看到该数据库。
原因
- 当前用户没有该数据库的
SHOW DATABASES权限(普通用户默认仅能看到自己创建的数据库); - 数据库名称包含隐藏字符(如空格、制表符),导致显示异常。
解决方案
-
使用 root 用户登录查看:
SHOW DATABASES LIKE 'db_%'; # 按前缀查找 -
授予当前用户
SHOW DATABASES权限:GRANT SHOW DATABASES ON *.* TO 'test'@'localhost'; FLUSH PRIVILEGES; -
重新创建无特殊字符的数据库:
DROP DATABASE IF EXISTS `db_name `; # 注意名称后的空格 CREATE DATABASE IF NOT EXISTS db_name CHARACTER SET utf8mb4;
10.6 备份 / 恢复时提示 "Access denied"
现象
执行mysqldump备份时,报错:
mysqldump: Got error: 1045: Access denied for user 'root'@'localhost' (using password: YES) when trying to connect
原因
- 密码错误(最常见);
- 用户没有
SELECT、LOCK TABLES等备份所需权限; - 远程备份时,用户没有远程访问权限。
解决方案
-
验证密码正确性,重新输入:
mysqldump -uroot -p'正确密码' -B db_chinese > backup.sql -
授予备份所需权限:
GRANT SELECT, LOCK TABLES, SHOW VIEW ON *.* TO 'root'@'localhost'; FLUSH PRIVILEGES; -
远程备份时,确保用户有远程访问权限:
CREATE USER 'root'@'192.168.1.%' IDENTIFIED BY '密码'; GRANT ALL PRIVILEGES ON *.* TO 'root'@'192.168.1.%' WITH GRANT OPTION; FLUSH PRIVILEGES;