【MySQL篇】数据库操作:从创建到管理

文章目录

数据库操作:从创建到管理

一、前言

💬 这一篇讲什么:学会操纵数据库本身

🚀 核心内容

  • 如何创建数据库?
  • 字符集和校验规则有什么区别?
  • 如何修改、删除数据库?
  • 如何备份和恢复数据?

在前一篇中,我们成功安装了 MySQL,并通过简单的例子了解了数据库的基本概念。现在需要深入学习如何实际操作数据库。这一篇的所有操作都是在 MySQL 命令行中执行的 SQL 语句。


二、创建数据库

2.1 基本语法

创建数据库的标准语法如下:

sql 复制代码
CREATE DATABASE [IF NOT EXISTS] db_name 
[DEFAULT CHARACTER SET charset_name]
[DEFAULT COLLATE collation_name];

各参数说明:

参数 说明
IF NOT EXISTS 可选。如果数据库已存在则不报错
db_name 要创建的数据库名称
CHARACTER SET 可选。指定数据库使用的字符集
COLLATE 可选。指定字符集的校验规则(排序和比较规则)

2.2 创建数据库的三种方式

方式一:最简单的创建
sql 复制代码
CREATE DATABASE db1;

这种方式不指定字符集和校验规则。MySQL 会使用系统默认值。在 Ubuntu 22.04 MySQL 8.0 中,默认字符集是 utf8mb4,校验规则是 utf8mb4_0900_ai_ci

方式二:指定字符集
sql 复制代码
CREATE DATABASE db2 DEFAULT CHARACTER SET utf8mb4;

或者简写为:

sql 复制代码
CREATE DATABASE db2 CHARSET=utf8mb4;

这样创建的数据库将使用 utf8mb4 字符集,校验规则仍然使用默认值。

方式三:同时指定字符集和校验规则
sql 复制代码
CREATE DATABASE db3 
DEFAULT CHARACTER SET utf8mb4 
DEFAULT COLLATE utf8mb4_unicode_ci;

这是最完整的创建方式,明确指定字符集和排序规则。

2.3 IF NOT EXISTS 的用处

如果数据库已经存在,直接执行 CREATE DATABASE 会报错。使用 IF NOT EXISTS 可以避免这个错误:

sql 复制代码
CREATE DATABASE IF NOT EXISTS db1;

如果 db1 已存在,这条语句不会报错,也不会做任何操作。如果不存在,就创建它。这在脚本中特别有用,因为脚本可能执行多次。


三、字符集与校验规则

3.1 什么是字符集

字符集定义了数据库中允许使用哪些字符以及这些字符如何编码。不同的字符集支持不同的语言。

字符集 支持语言 说明
utf8mb4 所有语言(推荐) 4 字节 UTF-8,支持 emoji 表情,是现代应用的标准
utf8 所有语言 3 字节 UTF-8,历史遗留,新应用不推荐用
latin1 英文 单字节,占用空间少,但只支持西欧字符
gbk 中文 2 字节,仅中文应用,不兼容其他语言

在互联网应用中,强烈推荐使用 utf8mb4。它支持所有语言和表情符号,是国际标准。

3.2 什么是校验规则

校验规则(Collation) 定义了字符的排序和比较方式。同一个字符集可能有多个校验规则。

utf8mb4 为例,常见的校验规则有:

校验规则 说明
utf8mb4_unicode_ci Unicode 标准排序,ci 表示 case insensitive(不区分大小写)
utf8mb4_bin 二进制比较,区分大小写
utf8mb4_general_ci 通用排序,不区分大小写(较旧)
utf8mb4_0900_ai_ci MySQL 8.0 新增,ai 表示 accent insensitive(不区分重音)

ci vs bin 的区别

  • ci(case insensitive):'A''a' 被视为相同。
  • bin(binary):'A''a' 被视为不同,严格按二进制值比较。

3.3 查看系统默认字符集

sql 复制代码
SHOW VARIABLES LIKE 'character_set%';

输出示例:

bash 复制代码
+------------------------+-----------------------------+
| Variable_name          | Value                       |
+------------------------+-----------------------------+
| character_set_client   | utf8mb4                     |
| character_set_connection | utf8mb4                   |
| character_set_database | utf8mb4                     |
| character_set_filesystem | binary                     |
| character_set_results  | utf8mb4                     |
| character_set_server   | utf8mb4                     |
| character_set_system   | utf8                        |
+------------------------+-----------------------------+

这些变量控制 MySQL 在不同阶段使用的字符集。其中 character_set_server 是默认的字符集。

3.4 查看系统默认校验规则

sql 复制代码
SHOW VARIABLES LIKE 'collation%';

输出示例:

bash 复制代码
+--------------------+--------------------+
| Variable_name      | Value              |
+--------------------+--------------------+
| collation_connection | utf8mb4_0900_ai_ci |
| collation_database | utf8mb4_0900_ai_ci |
| collation_server   | utf8mb4_0900_ai_ci |
+--------------------+--------------------+

3.5 查看系统支持的所有字符集

sql 复制代码
SHOW CHARSET;

这会列出 MySQL 支持的所有字符集以及它们的默认校验规则。

3.6 查看系统支持的所有校验规则

sql 复制代码
SHOW COLLATION;

这会列出所有可用的校验规则。如果输出太多,可以用 WHERE 过滤:

sql 复制代码
SHOW COLLATION WHERE Charset = 'utf8mb4';

四、校验规则的实际影响

4.1 案例:区分大小写 vs 不区分大小写

现在通过两个实验,直观感受校验规则的影响。

实验一:不区分大小写查询

创建数据库和表

sql 复制代码
CREATE DATABASE test_ci COLLATE utf8mb4_unicode_ci;
USE test_ci;

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');

查询大写字母 'A'

sql 复制代码
SELECT * FROM person WHERE name = 'A';

输出结果

bash 复制代码
+------+
| name |
+------+
| a    |
| A    |
+------+
2 rows in set (0.00 sec)

utf8mb4_unicode_ci 校验规则下,'A''a' 被视为相同,所以两条都返回了。

实验二:区分大小写查询

创建数据库和表

sql 复制代码
CREATE DATABASE test_bin COLLATE utf8mb4_bin;
USE test_bin;

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');

查询大写字母 'A'

sql 复制代码
SELECT * FROM person WHERE name = 'A';

输出结果

bash 复制代码
+------+
| name |
+------+
| A    |
+------+
1 row in set (0.00 sec)

utf8mb4_bin 校验规则下,只返回了大写字母 'A'。

4.2 案例:排序规则的影响

校验规则不仅影响查询条件,还影响排序结果。

不区分大小写的排序

test_ci 数据库中执行:

sql 复制代码
SELECT * FROM person ORDER BY name;

输出结果

bash 复制代码
+------+
| name |
+------+
| a    |
| A    |
| b    |
| B    |
+------+

因为不区分大小写,小写字母和对应的大写字母按插入顺序排列。

区分大小写的排序

test_bin 数据库中执行:

sql 复制代码
SELECT * FROM person ORDER BY name;

输出结果

bash 复制代码
+------+
| name |
+------+
| A    |
| B    |
| a    |
| b    |
+------+

因为区分大小写,大写字母的 ASCII 值小于小写字母,所以所有大写字母排在前面。

4.3 校验规则选择建议

  • 互联网应用(推荐) :使用 utf8mb4_unicode_ci。大多数应用中,用户输入通常不区分大小写,这样的设计更符合用户习惯。
  • 需要精确匹配 :使用 utf8mb4_bin。比如存储密码哈希值,必须精确匹配。
  • 系统字段 :考虑 utf8mb4_bin。比如用户名、邮箱,虽然显示上不区分,但实际存储要精确,避免冲突。

五、操纵数据库

5.1 查看所有数据库

sql 复制代码
SHOW DATABASES;

输出示例:

bash 复制代码
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
| db1                |
| db2                |
| db3                |
+--------------------+

前四个是 MySQL 系统库,不要删除。我们自己创建的数据库(如 db1db2db3)显示在下面。

5.2 查看数据库的创建语句

sql 复制代码
SHOW CREATE DATABASE db_name;

这个命令会显示创建该数据库时使用的完整 SQL 语句,包括字符集和校验规则。

示例

sql 复制代码
SHOW CREATE DATABASE db2;

输出

bash 复制代码
+-------+-----------------------------------------------+
| Database | Create Database                             |
+-------+-----------------------------------------------+
| db2   | CREATE DATABASE `db2` /*!40100 DEFAULT      |
|       | CHARACTER SET utf8mb4 */                    |
+-------+-----------------------------------------------+

输出说明

  • 反引号 ````` 用来围绕数据库名,防止名称恰好是 SQL 关键字时出错。
  • /*!40100 ... */ 不是注释。40100 表示 MySQL 版本号,语义是"如果 MySQL 版本 >= 4.01,就执行这句话"。这是 MySQL 特有的版本控制语法。

5.3 修改数据库字符集

虽然不建议修改已使用的数据库字符集,但语法是这样的:

sql 复制代码
ALTER DATABASE db_name 
DEFAULT CHARACTER SET charset_name 
[DEFAULT COLLATE collation_name];

示例 :将 db2 的字符集改为 gbk

sql 复制代码
ALTER DATABASE db2 DEFAULT CHARACTER SET gbk;

验证修改:

sql 复制代码
SHOW CREATE DATABASE db2;

注意:修改数据库的字符集只影响之后创建的新表,不会改变已有表中数据的字符集。如果需要完全转换,通常的做法是导出数据,删除旧库,用新字符集重建。

5.4 删除数据库

sql 复制代码
DROP DATABASE [IF EXISTS] db_name;

示例

sql 复制代码
DROP DATABASE db1;

删除后的影响

  • 数据库从 MySQL 系统中消失,再也看不到。
  • 数据库对应的磁盘文件夹被删除,其中包含的所有表和数据全部丢失。

使用 IF EXISTS 避免错误

sql 复制代码
DROP DATABASE IF EXISTS db1;

如果 db1 存在就删除,不存在也不报错。这在脚本中很有用。

警告:删除数据库是不可逆的操作。确保数据已备份后再执行删除。


六、数据库备份与恢复

在实际工作中,定期备份数据库是必须的。数据库崩溃、硬件故障或误操作都可能导致数据丢失。备份是最后的保险。

6.1 完整备份一个数据库

语法
bash 复制代码
mysqldump -h <host> -P <port> -u <user> -p<password> -B database_name > backup_file.sql

参数说明:

参数 说明
-h MySQL 服务器地址,默认 localhost
-P MySQL 端口,默认 3306
-u 数据库用户名
-p 密码,紧接在 -p 后面,中间无空格
-B 备份整个数据库(包含 CREATE DATABASE 语句)
示例:备份 db2 数据库

在 Ubuntu 的 bash 终端中执行(不在 MySQL 命令行中):

bash 复制代码
mysqldump -u root -p -B db2 > ~/db2_backup.sql

系统会提示输入密码。输入后,备份文件 db2_backup.sql 会生成在用户主目录。

查看备份文件内容
bash 复制代码
cat ~/db2_backup.sql

备份文件包含了创建数据库和表的所有 SQL 语句,以及数据的 INSERT 语句。

6.2 恢复数据库

从备份文件恢复

在 MySQL 命令行中执行:

sql 复制代码
SOURCE ~/db2_backup.sql;

或者使用 < 符号从 bash 中直接恢复(退出 MySQL 后):

bash 复制代码
mysql -u root -p < ~/db2_backup.sql

系统会提示输入密码,然后恢复数据库。

恢复后验证
sql 复制代码
SHOW DATABASES;
USE db2;
SHOW TABLES;
SELECT * FROM person;

确认数据是否恢复正确。

6.3 备份单个表

如果只想备份数据库中的某些表,不备份整个库:

bash 复制代码
mysqldump -u root -p database_name table1 table2 > backup_tables.sql

这样只备份 database_name 中的 table1table2

6.4 同时备份多个数据库

bash 复制代码
mysqldump -u root -p -B db1 db2 db3 > backup_multiple.sql

-B 参数后面可以跟多个数据库名,用空格分隔。

6.5 备份最佳实践

  • 定期备份:根据数据重要性,每天、每周或每月备份一次。
  • 备份到不同位置:不要把备份文件和源数据库放在同一台机器上,防止硬件故障导致同时丢失。
  • 测试恢复:定期测试备份文件能否成功恢复,确保备份可用。
  • 记录备份时间:给备份文件名添加时间戳,便于管理。
bash 复制代码
mysqldump -u root -p -B db2 > ~/db2_backup_$(date +%Y%m%d_%H%M%S).sql

这样会生成类似 db2_backup_20240407_143022.sql 的文件名。


七、查看数据库连接

7.1 查看当前连接情况

sql 复制代码
SHOW PROCESSLIST;

这个命令显示当前所有连接到 MySQL 的客户端。

输出示例

bash 复制代码
+----+------+-----------+-------+---------+------+-------+------------------+
| Id | User | Host      | db    | Command | Time | State | Info             |
+----+------+-----------+-------+---------+------+-------+------------------+
| 1  | root | localhost | db1   | Sleep   | 120  |       | NULL             |
| 2  | root | localhost | db2   | Query   | 0    | NULL  | SHOW PROCESSLIST |
+----+------+-----------+-------+---------+------+-------+------------------+

字段说明

字段 说明
Id 连接的唯一标识,可用于 KILL 命令
User 连接的用户名
Host 连接来自的主机 IP 和端口
db 当前连接使用的数据库
Command 连接执行的操作,通常是 QuerySleepConnect
Time 连接持续的时间(秒)
State 连接的状态
Info 正在执行的 SQL 语句

7.2 使用场景

诊断数据库性能问题

如果发现数据库查询变慢,执行这个命令可以看到:

  • 当前有哪些用户连接。
  • 他们正在执行什么操作。
  • 当前State或者Command持续多久了(Time 字段)。
  • 是否有死连接(长时间 Sleep 的连接)。

安全检查

执行这个命令后,如果看到陌生的用户或异常的连接来源,可能表示数据库被入侵。

7.3 杀死连接

如果需要断开某个连接,使用:

sql 复制代码
KILL connection_id;

示例:断开 Id 为 1 的连接:

sql 复制代码
KILL 1;

八、总结与实践

现在你已经掌握了:

创建数据库:支持指定字符集和校验规则

字符集与校验规则:理解排序和比较规则的区别

修改与删除ALTER DATABASEDROP DATABASE 的用法

备份与恢复 :使用 mysqldump 备份,用 SOURCE 或管道恢复

连接管理 :通过 SHOW PROCESSLIST 监控数据库连接

建议练习

  1. 创建三个数据库,分别使用不同的字符集和校验规则。
  2. utf8mb4_unicode_ciutf8mb4_bin 的数据库中分别插入相同数据,对比查询结果。
  3. 备份其中一个数据库到文件,删除原数据库,然后恢复,确保流程熟悉。

下一篇,我们将深入学习表的操作:如何创建表、定义列、设置约束等。表是数据库中最重要的结构,直接影响数据的组织和性能。

相关推荐
酸钠鈀2 小时前
AI WB2 SDK Ubuntu 环境搭建
linux·运维·ubuntu
Robot_Nav2 小时前
双系统Linux死机解决方法
linux·运维·服务器
瀚高PG实验室2 小时前
ETL中,分区表子表未及时收集统计信息,导致sql执行耗时很长
数据库·数据仓库·sql·etl·瀚高数据库
LDG_AGI2 小时前
【搜索引擎】Elasticsearch(二):基于function_score的搜索排序
数据库·人工智能·深度学习·elasticsearch·机器学习·搜索引擎·推荐算法
枫叶林FYL2 小时前
【自然语言处理 NLP】7.2.2.4 去偏见技术与公平性优化
数据库
北亚数据恢复2 小时前
数据库数据恢复—无有效备份下Oracle Truncate数据表的数据恢复案例
oracle·数据恢复·服务器数据恢复·北亚数据恢复
加勒比之杰克2 小时前
从阻塞 IO 到 epoll:把 Linux 网络 IO 一次讲透
linux·网络·windows·select·多路转接·epoll·poll
星川水月3 小时前
SQL 开窗函数排序详解
数据库·sql
荒川之神3 小时前
Oracle 数据仓库雪花模型设计原则(核心 + 落地 + Oracle 数据库适配)
数据库·数据仓库·oracle