☰
MySQL 库操作详解:建库、字符集与备份恢复
2026/10/14 3:32:08 网站建设 项目流程

库的操作说白了就四件事:增、删、改、查。但真正值得停下来想一想的,是藏在背后的两个问题:

  1. 我敲下create database d1;,硬盘上到底发生了什么?
  2. 为什么同一条select * from person where name='a';,在两个库里查出来的行数不一样?

第一个问题的答案会让你彻底理解"库"和"目录"的对应关系;第二个问题的答案,是字符集(Character Set)和校验集(Collation)——这两个词,是这一篇的核心。

环境说明:示例在 MySQL 5.7 / 8.0 上都能跑;utf8在 8.0 里会被规范成utf8mb3,文中遇到时会标注。下文mysql>开头的是你在客户端里敲的,其余是 MySQL 的返回结果。


目录:

〇、先看全局:思维导图

一、库住在哪儿?——数据目录 /var/lib/mysql

二、创建数据库

2.1 语法

2.2 if not exists:一个纯粹为了"别报错"的选项

2.3 本质:创建数据库 = 创建一个目录

三、字符集与校验集:本篇最该搞懂的地方

3.1 两个概念

3.2 查看字符集与校验集

3.3 _ci 和 _bin:区分大小写的那道分水岭

3.4 校验规则对数据库的影响(对比实验)

四、建库时指定编码与校验规则

4.1 三种写法

4.2 建完怎么验证?去看 db.opt

4.3 就近原则:谁说了算?

4.4 那……我到底为什么要设置库的编码?

五、删除数据库

六、操纵数据库

6.1 查看数据库

6.2 显示创建语句

6.3 use:切换到某个库

6.4 select database():我当前在哪个库?

6.5 修改数据库

七、备份和恢复

7.1 为什么不能"直接拷目录"?

7.2 备份

7.3 还原

7.4 -B 到底加不加?

7.5 注意事项:只备份部分内容

八、查看连接情况

九、两条"别乱来"

9.1 别随意删库

9.2 别随意改库名

十、番外:MySQL 5.7 与 8.0 的元数据存放差异

附录:知识速查表

速查表 1:库操作命令总览

速查表 2:字符集与校验集

速查表 3:备份与恢复

速查表 4:常见报错对照

速查表 5:踩坑清单


〇、先看全局:思维导图


一、库住在哪儿?——数据目录/var/lib/mysql

在敲第一条 SQL 之前,先把"库"的物理位置钉死。

MySQL 是跑在 Linux 上的服务进程(mysqld),它把所有数据库都放在一个固定的数据目录里,默认是/var/lib/mysql。进去看看,你会发现一个极其朴素的事实——每一个数据库,就是一个同名的文件夹:

[root@localhost ~]# cd /var/lib/mysql [root@localhost mysql]# ls d1 d2 ibdata1 ib_logfile0 ib_logfile1 mysql performance_schema sys

d1、d2是我们的库,mysql、performance_schema、sys是系统自带的库。

数据目录的实际位置取决于安装方式(源码编译、yum、apt、Docker 都可能不同),由配置文件里的datadir参数指定,可用show variables like 'datadir';查询。

这个认知会一路用下去:库 = 目录。后面所有的"创建""删除",都可以在脑子里同步翻译成mkdir和rm -rf。


二、创建数据库

2.1 语法

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指定字符集的校验规则。

注意create database后面没有 s——这和查看语句刚好相反,show databases时必须带 s,初学者容易在两处各错一次。

2.2if not exists:一个纯粹为了"别报错"的选项

mysql> create database if not exists db1; Query OK, 1 row affected, 1 warning (0.00 sec)

返回1 warning,因为db1已经存在了。这个选项的意思是:"如果它不存在,那我就创建;如果已经存在,我就不创建了,你也别报错。"加不加它,就是报错和警告的区别:

-- 不加:库已存在 → 直接报错 mysql> create database db1; ERROR 1007 (HY000): Can't create database 'db1'; database exists -- 加了:库已存在 → 只给个警告,语句安全地"空跑" mysql> create database if not exists db1; Query OK, 1 row affected, 1 warning (0.00 sec)

为什么不干脆让它报错?因为脚本和初始化 SQL 文件里无法保证库是否已建过。有了它,脚本就能反复执行而不中断——这在还原场景里是刚需(第七节你会看到,mysqldump导出的文件里全是这种写法)。

2.3 本质:创建数据库 = 创建一个目录

这解释了一个常见疑问:"我能不能直接在/var/lib/mysql下mkdir一个目录来建库?"

答案是:技术上它真的能工作,但你打死都不要这么干。

-- 绝对不要这么做! [root@localhost mysql]# mkdir d3

因为手动mkdir出来的目录没有在数据字典里登记,字符集、校验规则这些元信息全是缺的,MySQL 会认为它处于"半成品"的不一致状态;直接rm -rf掉库目录同样危险——MySQL 并不知道你干了什么。

结论:库的增删改查一律走 SQL。这不是"建议",是"必须"。


三、字符集与校验集:本篇最该搞懂的地方

3.1 两个概念

MySQL 存取数据时用到两套规则:

名称英文作用何时生效
字符集Character Set决定数据怎么存(用哪种编码把字符变成字节)写入 / 存储时
校验集Collation决定数据怎么比(字符串之间如何比较、排序)读取 / 比较 / 排序时

字符集主要控制用什么语言,比如 utf8 就可以使用中文。

一个贴切的类比:字符集是"我们用什么语言写字",大家都约定用汉字写,那谁写的谁就能读懂;校验集是"我们用什么规则判断两个字一不一样",判断 "a" 和 "A" 是不是同一个字,不同规则给出的答案完全不同。

为什么两个都必须是统一的?因为存进去的东西,必须用同一套规则才能读出来。就像一段二进制,你按整数写进去的,将来就必须按整数读出来——按浮点数去读,数据就毁了,比较也无从谈起。

一句话记住:数据库无论对数据做任何操作,都必须保证操作和编码是一致的。

3.2 查看字符集与校验集

查看系统默认的字符集与校验规则(两种写法,效果一样):

-- 写法一:show variables mysql> show variables like 'character_set_database'; +------------------------+---------+ | Variable_name | Value | +------------------------+---------+ | character_set_database | utf8mb3 | +------------------------+---------+ mysql> show variables like 'collation_database'; +--------------------+--------------------+ | Variable_name | Value | +--------------------+--------------------+ | collation_database | utf8mb3_general_ci | +--------------------+--------------------+ -- 写法二:select @@变量名,更短 mysql> select @@character_set_database, @@collation_database;

查看数据库支持的全部字符集:

show charset;

查看数据库支持的全部校验规则(结果很长,用\G竖排看更舒服):

show collation;

后两张表里,每个字符集下面都列着它能匹配的校验集,一一对应。比如gbk对应的默认校验集就是gbk_chinese_ci("简体中文、不区分大小写")。

关于utf8与utf8mb3:结果里的utf8mb3就是老版本里那个utf8。MySQL 的utf8从来都不是完整的 UTF-8——它最多只存 3 个字节,存不了 emoji 这类 4 字节字符。8.0 起官方把它正名为utf8mb3,并推荐新项目一律用utf8mb4。看到utf8mb3_general_ci你要知道:这就是那个"不区分大小写的老 utf8"。

3.3_ci和_bin:区分大小写的那道分水岭

校验规则的名字里通常带一个后缀,最常见的就是这两个:

后缀全称含义
_cicase insensitive不区分大小写
_binbinary区分大小写(按字节的二进制值直接比)

差别体现在哪?就是一个等号的事。往下看实验。

3.4 校验规则对数据库的影响(对比实验)

造两个库,唯一变量是校验规则。

不区分大小写——校验规则用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');

区分大小写——校验规则用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');

建表时没有指定字符集——它会自动继承所在数据库的设置。这正是实验成立的前提:两个库字符集相同,唯一变量就是校验规则。

对比查询

-- test1(utf8_general_ci):a 和 A 被当作同一个值 mysql> use test1; mysql> select * from person where name='a'; +------+ | name | +------+ | a | | A | +------+ 2 rows in set (0.01 sec) -- test2(utf8_bin):严格按字节匹配,只有小写 a 符合 mysql> use test2; mysql> select * from person where name='a'; +------+ | name | +------+ | a | +------+ 1 row in set (0.01 sec)

结论:同一个where条件,在utf8_general_ci下返回 2 行、在utf8_bin下只返回 1 行——校验规则直接决定了比较结果。

为什么这个知识点值钱?因为"用户名 / 邮箱登录不区分大小写"是常见需求,"密码哈希 / 验证码必须区分大小写"也是常见需求。这些需求不需要你在业务代码里写lower(),把列的校验规则定对就够了——这是数据库帮你守的规矩。


四、建库时指定编码与校验规则

4.1 三种写法

-- 1. 只用默认(不指定,跟随配置文件) create database d1; -- 2. 只指定字符集(校验规则会跟着字符集自动匹配一个默认值) create database d2 charset=utf8; -- 3. 字符集和校验规则都指定 create database d3 charset=utf8 collate utf8_general_ci;

不指定时,系统使用默认值:字符集utf8,校验规则utf8_general_ci;只指定字符集时,校验规则会自动匹配一个默认值。

charset也可以写成character set;语法里的[DEFAULT]是可选的修饰词,写不写都一样:

create database d4 default character set utf8 default collate utf8_general_ci;

⚠️拼写注意:指定校验规则的关键字是collate,不是collection,也不是collation。collate是动词,collation是它的名词形式,而collection是"集合"——完全不同的词,却坑过无数人:

mysql> create database d5 charset=utf8 collection utf8_general_ci; ERROR 1064 (42000): You have an error in your SQL syntax ...

4.2 建完怎么验证?去看db.opt

在 5.7 及以前,建完库后进数据目录,会看到每个库文件夹里多了一个db.opt:

[root@localhost mysql]# cd d3 [root@localhost d3]# cat db.opt default-character-set=utf8 default-collation=utf8_general_ci

就这么两行,这就是这个库"出生时"定下的编码规矩。

db.opt是 MySQL 5.7 的机制。8.0 把它取消了,改由系统表空间mysql.ibd统一保管——详见第十节。

4.3 就近原则:谁说了算?

配置文件和建库语句都指定了编码,听谁的?就近原则:

  • 用户在建库(或建表)时手动指定了→ 用你指定的;
  • 用户没指定→ 用配置文件里的默认值。
-- 配置文件默认是 utf8,但我就是要建个 gbk 的库 create database d_gbk charset=gbk collate=gbk_chinese_ci;

4.4 那……我到底为什么要设置库的编码?

这是初学时最容易"知其然不知其所以然"的地方。三层继承关系讲清楚就通了:

配置文件(my.cnf) ↓ 决定 数据库(database) ← 库的字符集/校验集 ↓ 决定 表(table) ← 建表不指定时,继承库的设置 ↓ 决定 列(column) ← 建表不指定时,继承表的设置

在配置文件里配,是为了改默认值——影响"创建数据库时的默认字符集和校验集";在建库时指定,是为了给这个库单独定调,因为未来在这个库里建的表,默认都会继承库的设置。

所以设置库的编码,本质上是在为库里即将出生的所有表预设好基因。原则很简单:建库时把编码定好,后面建表就完全不用操心。


五、删除数据库

DROP DATABASE [IF EXISTS] db_name;
mysql> drop database d1; Query OK, 0 rows affected (0.00 sec)

if exists和if not exists完全对称:库不存在时静默跳过,只给个警告不报错。

执行删除之后的结果有三层,一层比一层严重:

  1. 数据库内部看不到对应的数据库——show databases;里没有了;
  2. 对应的数据库文件夹被删除——/var/lib/mysql/d1整个目录没了;
  3. 级联删除,里面的数据表全部被删—— 库里曾经建过的所有表、表里的所有数据,一个不剩。

第三层才是真正要命的:drop database删的不只是"一个空壳",而是连同里面所有的表和数据一起。它没有回收站,没有确认弹窗,敲下去就没了。

注意:不要随意删除数据库。

这不是一句空话,是血泪教训。规范做法是删库之前先备份——先mysqldump把库导出成文件(见第七节),确认备份完好之后,再执行drop。同理,rm -rf直接删数据目录这种"野路子"也请一并戒掉。


六、操纵数据库

6.1 查看数据库

show databases;

6.2 显示创建语句

show create database 数据库名;
mysql> show create database mytest; +----------+----------------------------------------------------------------+ | Database | Create Database | +----------+----------------------------------------------------------------+ | mytest | CREATE DATABASE `mytest` /*!40100 DEFAULT CHARACTER SET utf8 */| +----------+----------------------------------------------------------------+ 1 row in set (0.00 sec)

这条输出里藏着三个细节。

  1. 细节一:MySQL 建议关键字大写,但不是必须的。CREATE DATABASE和create database效果完全一样,大写只是为了让 SQL 更易读。
  2. 细节二:反引号`是为了防关键字冲突。反引号是"标识符引用符",作用是告诉 MySQL:"这里面的东西是一个名字,别当关键字解析"。比如你非要建一个叫order或select的库/表/列,就必须用反引号包起来。日常开发建议别跟关键字撞车,但万一撞了,反引号能救你。
  3. 细节三:/*!40100 ... */不是注释。

如果当前 MySQL 版本 ≥ 4.01.00,就执行里面的内容。

这是 MySQL 特有的"版本条件执行"语法。

为什么要这么写?

因为 SQL 文件需要在不同版本的 MySQL 之间流转(比如从 5.7 备份、在 8.0 还原):语句对老版本有意义 → 老版本执行它;语句老版本不认识 → 老版本忽略它,而且不会报错。所以备份文件里到处都能看到/*!xxxxx ... */。看到它不是"注释",是"条件代码",就不会误判了。

6.3use:切换到某个库

mysql> use d1; Database changed

use的语义是"我接下来要在这个库里干活了"。我习惯把它类比成 Linux 的cd:

use d1;≈cd /var/lib/mysql/d1

这不是巧合——use之后你执行create table时,MySQL 确实就是在对应目录下创建文件。库的行为和 Linux 文件系统的行为是可以对应上的。

⚠️ 一个高频报错:忘了use就开始建表。

mysql> create table t1(id int); ERROR 1046 (3D000): No database selected

6.4select database():我当前在哪个库?

use了太久,容易忘了自己在哪儿。用这个函数确认:

mysql> select database(); +--------------+ | database() | +--------------+ | NULL | +--------------+ 1 row in set (0.00 sec)

结果NULL说明你当前不在任何数据库里(比如刚登录还没use)。切过去之后再看:

mysql> use test2; Database changed mysql> select database(); +------------+ | database() | +------------+ | test2 | +------------+

6.5 修改数据库

ALTER DATABASE db_name [alter_specification [, alter_specification] ...] alter_specification: [DEFAULT] CHARACTER SET charset_name [DEFAULT] COLLATE collation_name

对数据库的修改,主要就是指修改它的字符集和校验规则:

mysql> alter database mytest charset=gbk; Query OK, 1 row affected (0.00 sec) mysql> show create database mytest; +----------+----------------------------------------------------------------+ | Database | Create Database | +----------+----------------------------------------------------------------+ | mytest | CREATE DATABASE `mytest` /*!40100 DEFAULT CHARACTER SET gbk */ | +----------+----------------------------------------------------------------+

⚠️一个必须说清楚的点:alter database改的是这个库"之后建表时的默认值",也就是db.opt里那两行。

它不会去动这个库里已经建好的表——那些表在创建时就把编码定死了。想改已存在表的编码,得单独对它执行alter table(这属于会引起数据重建的操作,要慎重)。

另外,日常开发中alter database用得极少。因为库里一旦有了数据,编码改动牵一发动全身。编码这种事,应该在建库第一天就定好,而不是事后补救。


七、备份和恢复

7.1 为什么不能"直接拷目录"?

既然库就是一个目录,那我直接把/var/lib/mysql打个包,不就完成备份了?

技术上可以,但严重不推荐。原因很直白:跨版本的目录结构不兼容——你这边跑的是 5.7,备份出来的目录拿到一台跑 5.0 的机器上,文件格式很可能根本读不了。(用mv给库目录改名当备份?同样不推荐,原因见 9.2。)

正解:用 MySQL 自带的备份工具mysqldump。

7.2 备份

# mysqldump -P3306 -u root -p 密码 -B 数据库名 > 数据库备份存储的文件路径

示例:把mytest库备份到文件(先退出连接):

mysqldump -P3306 -u root -p123456 -B mytest > D:/mytest.sql
参数含义
-P3306指定连接端口号(P大写)
-uroot指定用户名 root(u小写)
-p提示输入密码
-B备份时带上"建库语句",详见 7.4

⚠️重要:mysqldump是一条操作系统命令,必须在终端里执行,不是在mysql>客户端里。这是新手最容易卡住的地方。

密码安全:课件示例写作-p123456(密码直接跟在-p后面),能跑,但密码会明文出现在命令历史(history)和进程列表里,生产环境绝对不要这么写。正确姿势是只写-p,回车后再交互输入。

打开mytest.sql看看内容,其实把我们整个创建数据库、建表、导入数据的语句都装载这个文件中了:

CREATE DATABASE /*!32312 IF NOT EXISTS*/ `mytest` /*!40100 DEFAULT CHARACTER SET utf8 */; USE `mytest`; DROP TABLE IF EXISTS `person`; CREATE TABLE `person` ( `name` varchar(20) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8; INSERT INTO `person` VALUES ('a'),('A'),('b'),('B');

看出门道了吗?mysqldump备份的不只是数据,而是"重建这个库所需要执行的全部有效操作":建库 → 删旧表(保证可重复执行)→ 建表 → 插数据。所以恢复的本质,就是把这堆 SQL 再跑一遍。

7.3 还原

mysql> source D:/mysql-5.7.22/mytest.sql;

source是mysql>客户端内部的命令(注意:和mysqldump刚好相反,这个要在客户端里执行),后面跟备份文件的完整路径。它的作用就是:把文件里的 SQL 语句,在这个 MySQL 里从头到尾执行一遍。

很实用的场景:把.sql文件发给另一台机器上的同事,他本地没有这个库,直接source一下,数据库就在他那边重建出来了。这就是"用 SQL 文件在机器之间搬运数据库"。

7.4-B到底加不加?

-B(--databases的简写)决定备份文件里有没有建库语句。

情况一:不加-B

mysqldump -u root -p mytest > D:/mytest.sql

导出的内容里只有CREATE TABLE和INSERT INTO,没有CREATE DATABASE和USE。恢复时直接跑这个文件会报错,因为MySQL 不知道要把这些表建到哪个库里。必须手动三步:

create database mytest; use mytest; source D:/mytest.sql;

情况二:加了-B

文件开头会自动带上CREATE DATABASE /*!32312 IF NOT EXISTS*/ ...和USE ...,恢复时什么都不用管,直接source就全自动完成。

结论:除非你有特殊理由,备份时一律加-B。多打两个字符,省下恢复时的一堆麻烦。

7.5 注意事项:只备份部分内容

只备份其中的一张表(或 N 张表):

mysqldump -u root -p 数据库名 表名1 表名2 > D:/mytest.sql

这里没有-B——因为备份的不是整个库,恢复时要自己先建库、use进去,再source。

同时备份多个数据库:

mysqldump -u root -p -B 数据库名1 数据库名2 ... > 数据库存放路径

带-B时后面可以跟多个库名,导出文件里会依次为每个库生成建库语句。

规律:不管是备份单表、多表、单库还是多库,备份命令的套路一样,恢复方式也一样。唯一要记住的就是-B那条分界线。


八、查看连接情况

有时候发现数据库比较慢、卡顿,第一反应应该是:现在有哪些人连着?在干什么?

mysql> show processlist; +----+------+-----------+------+---------+------+-------+------------------+ | Id | User | Host | db | Command | Time | State | Info | +----+------+-----------+------+---------+------+-------+------------------+ | 2 | root | localhost | test | Sleep | 1386 | | NULL | | 3 | root | localhost | NULL | Query | 0 | NULL | show processlist | +----+------+-----------+------+---------+------+-------+------------------+
列含义
Id连接的唯一编号
User是哪个用户在连
Host从哪台机器连过来的
db当前连的是哪个库(NULL表示没use任何库)
Command当前在执行什么类型的命令(Query/Sleep/Daemon)
Time该状态持续的秒数
State当前的具体状态
Info正在执行的 SQL 语句原文

它告诉我们当前有哪些用户连接到 MySQL。两个重要用途:

  • 安全排查:如果查出某个用户不是你正常登录的,很有可能你的数据库被人入侵了;
  • 性能排查:发现数据库比较慢时,盯着Time列看——如果某条Query的Time一直很大,那条 SQL 就是嫌疑人。

九、两条"别乱来"

9.1 别随意删库

第五节讲过,但要再强调一次:drop database是级联删除,表和数据一起没。删之前先备份,这个顺序不能反。

9.2 别随意改库名

MySQL不提供数据库重命名功能。以前有过RENAME DATABASE,后来被移除了,原因就是"改库名这件事本身就很危险":你改的时候,可能别人正在用这个库。

更要命的是第二条:应用层对数据库的依赖,全都是通过"库名"这个接口的。回头看看你的项目——配置文件里的连接串、ORM 的映射、各种脚本……到处都写着库名。你把库名一改,上层的所有应用全部失效——这不是夸张,这就是所谓的蝴蝶效应。想在 Linux 层面用mv改名绕过?前面说过了,严重不推荐。


十、番外:MySQL 5.7 与 8.0 的元数据存放差异

前面提到的db.opt,在 8.0 里消失了。

MySQL 5.7 及以前:就像每个班级(数据库)自己拿个小本本(db.opt)记自己的规矩(字符集、校验规则),各自管各自的。

MySQL 8.0:取消了小本本。所有班级的规矩全部统一上交到学校的总档案室(系统表空间mysql.ibd),由校长(MySQL 服务)统一保管。

mysql.ibd是什么?它就是那个"总档案室",属于 InnoDB 的系统表空间。你创建的数据库名、它们各自的字符集和排序规则,以及所有表的结构信息(也就是数据字典),全部存在这个文件里。你没法用文本编辑器打开它,只能通过 SQL 语句去查。这也是 8.0 一个重要的架构改进:元数据有了统一、事务安全的管理方式。

对我们使用者的影响:8.0 里库目录下再也找不到db.opt了,想确认库的编码,请用show create database 库名;或select @@character_set_database;这类 SQL 手段。


附录:知识速查表

速查表 1:库操作命令总览

目的语句备注
查看所有库show databases;有 s
创建库create database [if not exists] 库名;没有 s
指定编码建库create database 库名 charset=utf8 collate utf8_general_ci;校验规则关键字是collate
删除库drop database [if exists] 库名;级联删除,不可逆
切换库use 库名;相当于cd进目录
查当前库select database();返回NULL表示不在任何库
看建库语句show create database 库名;能看到字符集
改库默认编码alter database 库名 charset=gbk;只影响之后建的表
看谁在连show processlist;排查入侵和慢查询

速查表 2:字符集与校验集

概念作用何时生效
字符集 Character Set数据怎么存写入时
校验集 Collation数据怎么比读取、比较、排序时
查看命令作用
show variables like 'character_set_database';当前库的字符集
show variables like 'collation_database';当前库的校验规则
select @@character_set_database, @@collation_database;同上,更短
show charset;MySQL 支持的全部字符集
show collation;MySQL 支持的全部校验规则及对应关系
后缀含义where name='a'会返回
_ci(case insensitive)不区分大小写a和A都返回
_bin(binary)区分大小写,按字节值比只返回a

继承链:

配置文件→数据库→表→列,上一层决定下一层的默认值。

速查表 3:备份与恢复

场景命令在哪执行
备份整个库(推荐加-B)mysqldump -P3306 -uroot -p -B 库名 > 库名.sql终端
备份多个库mysqldump -uroot -p -B 库1 库2 > multi.sql终端
只备份某几张表(不加-B)mysqldump -uroot -p 库名 表1 表2 > t.sql终端
恢复source /完整路径/文件.sqlmysql>客户端内
-B选项备份文件里有建库语句吗恢复时要做什么
加了-B有(CREATE DATABASE+USE)直接source,全自动
没加-B没有必须先create database→use→ 再source

速查表 4:常见报错对照

错误码报错(节选)你踩了什么
1007Can't create database 'x'; database exists库已存在却没用if not exists
1008Can't drop database 'x'; database doesn't exist删一个不存在的库,可加if exists
1044Access denied for user ... to database ...当前用户没权限访问这个库
1046No database selected建表前忘了use 库名
1049Unknown database 'x'use了一个不存在的库
1064You have an error in your SQL syntax ...语法错误:collate拼成collection等
1366Incorrect string value: ... for column 'x'字符集存不下你插的内容(典型:utf8存不了 emoji)

速查表 5:踩坑清单

  1. create database没有 s,show databases有 s—— 两边各错一次是常态。
  2. if not exists和if exists是为了让脚本可重复执行,不是用来替代错误处理的。
  3. 数据目录里mkdir/rm -rf手动增删库目录,技术上能跑,实践上绝对别干。
  4. 库 = 目录,drop database= 删目录且级联删除里面所有表和数据,无回收站。
  5. 校验规则关键字是collate,不是collection,也不是collation。
  6. utf8在 MySQL 里是utf8mb3,最多 3 字节,存不了 emoji;新项目建议直接用utf8mb4。
  7. alter database改的是"以后建表的默认值",已存在的表不会跟着变。
  8. mysqldump在终端执行;source在mysql>客户端内执行 —— 两者刚好相反。
  9. 备份一律加-B,除非你只备份某几张表;不加-B恢复时得自己先建库。
  10. -p后面不要紧跟密码,否则密码会进命令历史和进程列表。
  11. MySQL不支持数据库重命名。库名一旦被上层应用依赖,改动就是蝴蝶效应。
  12. show processlist里出现陌生用户,很可能数据库被人入侵了。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询