3.MySQL操作库
文章目录
- 3.MySQL操作库
-
- [一、建库与删库:一条 SQL 对应一个目录](#一、建库与删库:一条 SQL 对应一个目录)
- 二、字符集与校验规则:存与比必须同编码
- 三、建库时显式指定编码:就近原则
- 四、校验规则影响查询与排序
- [五、查看库:show databases、show create database、use](#五、查看库:show databases、show create database、use)
- 六、修改库与删除库
- [七、备份与恢复:mysqldump 与 source](#七、备份与恢复:mysqldump 与 source)
- [八、show processlist:查看谁连在库上](#八、show processlist:查看谁连在库上)
- 九、建表:语法与完整示例
- 十、存储引擎不同,磁盘文件不同
- 十一、查看表结构
- 十二、修改表(一):加列与改列属性
- 十三、修改表(二):删列、改表名与改列名
- 十四、删除表与结构改动纪律
- 总结
上一篇笔记把数据库从概念讲到了落地:建库就是在 /var/lib/mysql 下建目录、建表就是在目录里建文件;SQL 分 DDL、DML、DCL 三类;MySQL 是分层网络服务,默认存储引擎是 InnoDB。上篇止于"认识",本篇进入"上手"。
实操分两大阶段:先做库的操作------创建、查看、修改、删除数据库,重点讲字符集与校验规则,最后讲备份恢复;再做表的操作------创建表、查看表结构、修改表、删除表,并借建表比较 MyISAM 与 InnoDB 在磁盘文件上的差异。老师始终把库表操作与 Linux 文件操作对照讲解,本篇沿用这条线:每类 SQL 都回答它落到 Linux 上到底做了什么。
一、建库与删库:一条 SQL 对应一个目录
库的操作从建库开始。创建数据库的 SQL 非常简单,完整语法如下(中括号表示可选项):
sql
CREATE DATABASE [IF NOT EXISTS] db_name
[DEFAULT] CHARACTER SET charset_name -- 字符集
[DEFAULT] COLLATE collation_name -- 校验规则
语法上只需记三点:
- 关键字大小写均可,习惯大写只为可读性。
- 中括号内是可选项:字符集、校验规则子句不写则采用系统默认。
- create database 的 database 不带 s,而查看命令 show databases 带 s,固定用法不要混。库名结合业务自行定义。
亲手验证建库与 Linux 的对应。数据目录是 /var/lib/mysql(需超级用户权限),打开 mysql 客户端执行:
sql
show databases; -- 查看当前可见的数据库列表
create database db1; -- 建库
drop database db1; -- 删库
每执行一次建库或删库,回到数据目录 ls,同名目录随之出现或消失。建库的本质是在数据目录下创建一个同名目录;删库的本质是连同目录递归删除。库目录里只有 db.opt 等少量配置文件,内容要在建表之后才充实起来。四条 SQL 与 Linux 操作的对应关系:
#mermaid-svg-Yk99MRjbNi94YG5R{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-Yk99MRjbNi94YG5R .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-Yk99MRjbNi94YG5R .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-Yk99MRjbNi94YG5R .error-icon{fill:#552222;}#mermaid-svg-Yk99MRjbNi94YG5R .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-Yk99MRjbNi94YG5R .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-Yk99MRjbNi94YG5R .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-Yk99MRjbNi94YG5R .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-Yk99MRjbNi94YG5R .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-Yk99MRjbNi94YG5R .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-Yk99MRjbNi94YG5R .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-Yk99MRjbNi94YG5R .marker{fill:#333333;stroke:#333333;}#mermaid-svg-Yk99MRjbNi94YG5R .marker.cross{stroke:#333333;}#mermaid-svg-Yk99MRjbNi94YG5R svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-Yk99MRjbNi94YG5R p{margin:0;}#mermaid-svg-Yk99MRjbNi94YG5R .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-Yk99MRjbNi94YG5R .cluster-label text{fill:#333;}#mermaid-svg-Yk99MRjbNi94YG5R .cluster-label span{color:#333;}#mermaid-svg-Yk99MRjbNi94YG5R .cluster-label span p{background-color:transparent;}#mermaid-svg-Yk99MRjbNi94YG5R .label text,#mermaid-svg-Yk99MRjbNi94YG5R span{fill:#333;color:#333;}#mermaid-svg-Yk99MRjbNi94YG5R .node rect,#mermaid-svg-Yk99MRjbNi94YG5R .node circle,#mermaid-svg-Yk99MRjbNi94YG5R .node ellipse,#mermaid-svg-Yk99MRjbNi94YG5R .node polygon,#mermaid-svg-Yk99MRjbNi94YG5R .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-Yk99MRjbNi94YG5R .rough-node .label text,#mermaid-svg-Yk99MRjbNi94YG5R .node .label text,#mermaid-svg-Yk99MRjbNi94YG5R .image-shape .label,#mermaid-svg-Yk99MRjbNi94YG5R .icon-shape .label{text-anchor:middle;}#mermaid-svg-Yk99MRjbNi94YG5R .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-Yk99MRjbNi94YG5R .rough-node .label,#mermaid-svg-Yk99MRjbNi94YG5R .node .label,#mermaid-svg-Yk99MRjbNi94YG5R .image-shape .label,#mermaid-svg-Yk99MRjbNi94YG5R .icon-shape .label{text-align:center;}#mermaid-svg-Yk99MRjbNi94YG5R .node.clickable{cursor:pointer;}#mermaid-svg-Yk99MRjbNi94YG5R .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-Yk99MRjbNi94YG5R .arrowheadPath{fill:#333333;}#mermaid-svg-Yk99MRjbNi94YG5R .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-Yk99MRjbNi94YG5R .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-Yk99MRjbNi94YG5R .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Yk99MRjbNi94YG5R .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-Yk99MRjbNi94YG5R .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Yk99MRjbNi94YG5R .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-Yk99MRjbNi94YG5R .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-Yk99MRjbNi94YG5R .cluster text{fill:#333;}#mermaid-svg-Yk99MRjbNi94YG5R .cluster span{color:#333;}#mermaid-svg-Yk99MRjbNi94YG5R div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-Yk99MRjbNi94YG5R .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-Yk99MRjbNi94YG5R rect.text{fill:none;stroke-width:0;}#mermaid-svg-Yk99MRjbNi94YG5R .icon-shape,#mermaid-svg-Yk99MRjbNi94YG5R .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Yk99MRjbNi94YG5R .icon-shape p,#mermaid-svg-Yk99MRjbNi94YG5R .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-Yk99MRjbNi94YG5R .icon-shape .label rect,#mermaid-svg-Yk99MRjbNi94YG5R .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Yk99MRjbNi94YG5R .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-Yk99MRjbNi94YG5R .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-Yk99MRjbNi94YG5R :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 对应
对应
对应
对应
create database db1
数据目录下创建 db1 目录
drop database db1
递归删除 db1 目录
show databases
列出数据目录下的目录
use db1
cd 进入 db1 目录
三点补充认识:
- 目录与库双向联动 。手动 mkdir 一个目录,show databases 同样能列出它;rm 掉这个目录它随之消失。这反向印证了"库即目录",但建库必须走 SQL,禁止手动 mkdir,手动创建的目录缺少数据库应有的元信息与结构。
- if not exists 用于防重。不带该选项时重复创建同名库会直接报错;加上后库已存在则跳过创建、仅给提示,不中断执行,适合初始化脚本反复运行。
- 删库不可逆:目录一删,将来库内所有的表与数据一并消失。先备份再删除,备份方法见第七节。
二、字符集与校验规则:存与比必须同编码
建库前先搞懂一对最容易混淆的概念:
- 字符集(character set)决定数据以什么编码存储。同一段文字按 utf8 还是 gbk 编码,落盘的字节完全不同。
- 校验规则(collation)决定比较与排序时按什么规则解读数据。查询 name = 'a'、按 name 排序,都要把数据逐字节比对,按哪套规则比、是否区分大小写,由校验规则决定。
两者在绝大多数的情况下是一致的:存进去用一套编码,取出来比较用另一套,有可能乱码或比较失真 。但并不是说必须一致,"怎么存"和"怎么比"是两个独立的问题 ,编码定下来后,比较规则并没有被定死 。同样是 utf8 编码的字节,可以有 utf8_general_ci(不区分大小写、宽松)、utf8_bin(逐字节比)、utf8_unicode_ci(按 Unicode 算法更精确地排)......一个字符集天然对应多种校验规则。
先看当前系统与库的默认值:
sql
show variables like 'character_set_database'; -- 当前默认字符集
show variables like 'collation_database'; -- 当前默认校验规则
查看系统支持的全部字符集与校验规则:
sql
show charset; -- 全部字符集(utf8 支持中文)
show collation; -- 全部校验规则
show collation 的结果里,校验规则与字符集存在配套关系,例如 gbk 配套的默认校验规则是 gbk_chinese_ci;字符集选定后,配套校验规则随之确定。
三、建库时显式指定编码:就近原则
默认值够用,但建库语句支持显式指定,写法等价、效果相同:
sql
create database db2 charset=utf8; -- 写法一:charset 等号
create database db3 character set utf8 collate utf8_general_ci; -- 写法二:character set 空格
create database db4 charset=gbk collate gbk_chinese_ci; -- 中文库可选 gbk
建好的库在目录内会多出一个 db.opt 文件,里面记录的正是该库的字符集与校验规则;指定为 gbk 的库,db.opt 里就是 gbk 与 gbk_chinese_ci。
由此引出就近原则:建库 SQL 里显式写了编码,按写的执行;没写,按系统默认执行。默认值沿"mysqld 配置、库、表"逐级下传:
#mermaid-svg-TaHgn2Ac8VBSDFiK{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-TaHgn2Ac8VBSDFiK .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-TaHgn2Ac8VBSDFiK .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-TaHgn2Ac8VBSDFiK .error-icon{fill:#552222;}#mermaid-svg-TaHgn2Ac8VBSDFiK .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-TaHgn2Ac8VBSDFiK .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-TaHgn2Ac8VBSDFiK .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-TaHgn2Ac8VBSDFiK .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-TaHgn2Ac8VBSDFiK .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-TaHgn2Ac8VBSDFiK .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-TaHgn2Ac8VBSDFiK .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-TaHgn2Ac8VBSDFiK .marker{fill:#333333;stroke:#333333;}#mermaid-svg-TaHgn2Ac8VBSDFiK .marker.cross{stroke:#333333;}#mermaid-svg-TaHgn2Ac8VBSDFiK svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-TaHgn2Ac8VBSDFiK p{margin:0;}#mermaid-svg-TaHgn2Ac8VBSDFiK .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-TaHgn2Ac8VBSDFiK .cluster-label text{fill:#333;}#mermaid-svg-TaHgn2Ac8VBSDFiK .cluster-label span{color:#333;}#mermaid-svg-TaHgn2Ac8VBSDFiK .cluster-label span p{background-color:transparent;}#mermaid-svg-TaHgn2Ac8VBSDFiK .label text,#mermaid-svg-TaHgn2Ac8VBSDFiK span{fill:#333;color:#333;}#mermaid-svg-TaHgn2Ac8VBSDFiK .node rect,#mermaid-svg-TaHgn2Ac8VBSDFiK .node circle,#mermaid-svg-TaHgn2Ac8VBSDFiK .node ellipse,#mermaid-svg-TaHgn2Ac8VBSDFiK .node polygon,#mermaid-svg-TaHgn2Ac8VBSDFiK .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-TaHgn2Ac8VBSDFiK .rough-node .label text,#mermaid-svg-TaHgn2Ac8VBSDFiK .node .label text,#mermaid-svg-TaHgn2Ac8VBSDFiK .image-shape .label,#mermaid-svg-TaHgn2Ac8VBSDFiK .icon-shape .label{text-anchor:middle;}#mermaid-svg-TaHgn2Ac8VBSDFiK .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-TaHgn2Ac8VBSDFiK .rough-node .label,#mermaid-svg-TaHgn2Ac8VBSDFiK .node .label,#mermaid-svg-TaHgn2Ac8VBSDFiK .image-shape .label,#mermaid-svg-TaHgn2Ac8VBSDFiK .icon-shape .label{text-align:center;}#mermaid-svg-TaHgn2Ac8VBSDFiK .node.clickable{cursor:pointer;}#mermaid-svg-TaHgn2Ac8VBSDFiK .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-TaHgn2Ac8VBSDFiK .arrowheadPath{fill:#333333;}#mermaid-svg-TaHgn2Ac8VBSDFiK .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-TaHgn2Ac8VBSDFiK .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-TaHgn2Ac8VBSDFiK .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-TaHgn2Ac8VBSDFiK .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-TaHgn2Ac8VBSDFiK .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-TaHgn2Ac8VBSDFiK .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-TaHgn2Ac8VBSDFiK .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-TaHgn2Ac8VBSDFiK .cluster text{fill:#333;}#mermaid-svg-TaHgn2Ac8VBSDFiK .cluster span{color:#333;}#mermaid-svg-TaHgn2Ac8VBSDFiK div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-TaHgn2Ac8VBSDFiK .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-TaHgn2Ac8VBSDFiK rect.text{fill:none;stroke-width:0;}#mermaid-svg-TaHgn2Ac8VBSDFiK .icon-shape,#mermaid-svg-TaHgn2Ac8VBSDFiK .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-TaHgn2Ac8VBSDFiK .icon-shape p,#mermaid-svg-TaHgn2Ac8VBSDFiK .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-TaHgn2Ac8VBSDFiK .icon-shape .label rect,#mermaid-svg-TaHgn2Ac8VBSDFiK .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-TaHgn2Ac8VBSDFiK .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-TaHgn2Ac8VBSDFiK .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-TaHgn2Ac8VBSDFiK :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 建库未指定则继承
建表未指定则继承
就近原则:以写的为准
就近原则:以写的为准
mysqld 配置默认
utf8 / utf8_general_ci
库(db.opt 记录)
表
建库 SQL 显式 charset / collate
建表 SQL 显式 charset / collate / engine
为什么源头已配好 utf8,每一层还要保留"指定编码"的能力?因为表默认继承所在库的编码:一个库里可能有各种业务表,个别场景需要差异化(如对接遗留系统的 gbk 数据)时在库层指定即可。绝大多数场景建库不必手写编码,默认 utf8 即满足要求。
四、校验规则影响查询与排序
字符集不同影响的是可读性(乱码),而校验规则不同会改变查询与排序的语义,用实验验证。建两个库,字符集相同(默认 utf8),只把校验规则分开:
sql
create database test1 collate utf8_general_ci; -- 不区分大小写
create database test2 collate utf8_bin; -- 区分大小写(按二进制逐字节比较)
collate 与 charset 可以只写其一:只指定 collate 时,字符集仍取默认 utf8。往两个库里放完全相同的表和数据:
sql
use test1;
create table person (name varchar(20));
insert into person values ('a'), ('A'), ('b'), ('B');
test2 重复同样的三条语句。执行等值查询 name = 'a':
txt
-- test1:utf8_general_ci
mysql> select * from person where name='a';
| a |
| A | -- 小写 a 与大写 A 都被查出:不区分大小写
-- test2:utf8_bin
mysql> select * from person where name='a';
| a | -- 只返回小写 a:严格区分大小写
再看排序,执行 select * from person order by name(默认升序):
txt
-- test1:utf8_general_ci 结果 a、A、b、B 忽略大小写,字母按组排
-- test2:utf8_bin 结果 A、B、a、b 大写 ASCII 码小于小写,按二进制排
结论:字段的等值比较与排序行为都由校验规则决定。
五、查看库:show databases、show create database、use
查看层面有两条命令:show databases 看库的清单,show create database 看某个库当初是怎么建的:
sql
show databases; -- 当前用户可见的数据库列表
show create database test2; -- 显示建库语句(含字符集与校验规则)
show create database 的输出形如课件中的 mytest 示例(省略了表格边框):
txt
mysql> show create database mytest;
CREATE DATABASE `mytest` /*!40100 DEFAULT CHARACTER SET utf8 */
输出与当初敲的语句可能不完全相同,三点细节:
- 库名被自动包上反引号:防止库名恰好是 MySQL 关键字或含特殊字符时产生歧义。
/*!40100 ... */ 不是注释,是版本条件判断:MySQL 版本大于等于 4.01(40100 即版本号)才执行括号内的语句,这是建库语句跨版本兼容的机制。- 语句已被服务端规范化:统一大小写、补齐默认值,呈现为标准格式。
库在 Linux 上是一个目录,使用前要先进去:
sql
use test1; -- 选择数据库(对应 cd 进入目录)
select database(); -- 查看当前所在库;未选择库时返回 NULL
select database() 是一行函数查询,脚本里常用它确认当前上下文,避免把表建进错误的库。
六、修改库与删除库
库层面允许的修改很有限,几乎只改编码:
sql
alter database test2 charset=gbk; -- 修改字符集
执行后 test2 目录内 db.opt 的字符集变为 gbk;只改字符集不写 collate 时,MySQL 会自动配上该字符集默认的校验规则(gbk 配 gbk_chinese_ci)。show create database test2 可确认改动生效。
删除库:
sql
drop database [if exists] test2; -- if exists:存在才删,防止误报错
drop database 是级联删除:目录连同其中所有表与数据一并消失,没有回收站。围绕删与改有两点纪律、一条禁令:
- 库轻易不删。确需删除先做备份(第七节),并确认没有上层应用正在使用。
- 库名轻易不改,MySQL 不支持重命名库 。早期版本曾短暂支持 rename database(5.1.7 引入、5.1.23 移除),后因官方认定该语句可能导致库内容丢失而被移除;直接 mv 数据目录改名同样不被推荐。原因很实际:上层应用代码里写死了库名,库名一变,所有依赖它的程序全部失联,改库名约等于删库重建。
- 因业务需要"换名",正道是走备份恢复。
七、备份与恢复:mysqldump 与 source
先回答"为什么不直接拷贝目录"。直接拷贝或打包数据目录、mv 改名都不被推荐:数据库文件与版本强相关(低版本建出的文件高版本未必识别),绕过服务端直接操作目录风险高,库名又不可改(上一节)。官方做法是用 MySQL 自带的 mysqldump 做逻辑备份。
以 test1 库为例(内含第四节实验的 person 表),退出 mysql,在 shell 下执行:
bash
mysqldump -P3306 -u root -p -B test1 > test1.sql
选项含义:-P3306 指定端口(默认即 3306),-u root 指定用户,-p 回车后输入密码(本机免密直接回车),-B test1 指明备份整个库,> 是 shell 重定向,把输出写进文件(见 基础 IO 的重定向)。打开生成的 test1.sql,能看到一连串熟悉的语句(节选,头部版本注释已省略):
sql
CREATE DATABASE /*!32312 IF NOT EXISTS*/ `test1` /*!40100 DEFAULT CHARACTER SET utf8 */; -- 带 -B 时才有建库语句
USE `test1`;
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'); -- 数据逐条补回
带 -B 时先有 create database test1,随后 drop table 再 create table 重建 person,最后逐条 insert 补回数据 。所以 mysqldump 备份的不是某个数据文件的快照,而是该库自建库以来的全部有效 SQL 历史;备份文件是纯文本,可阅读、可传输。
恢复在 mysql 客户端内用 source 执行文件里的 SQL:
sql
source /path/to/test1.sql; -- 逐条执行文件内 SQL,路径按实际填写
执行完 show databases 可见 test1 回来,use test1、show tables、select * from person,数据原样恢复。备份恢复的典型场景是迁移或定期同步到另一台机器:
#mermaid-svg-ibZbli0zaXbOMg9R{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-ibZbli0zaXbOMg9R .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-ibZbli0zaXbOMg9R .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-ibZbli0zaXbOMg9R .error-icon{fill:#552222;}#mermaid-svg-ibZbli0zaXbOMg9R .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-ibZbli0zaXbOMg9R .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-ibZbli0zaXbOMg9R .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-ibZbli0zaXbOMg9R .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-ibZbli0zaXbOMg9R .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-ibZbli0zaXbOMg9R .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-ibZbli0zaXbOMg9R .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-ibZbli0zaXbOMg9R .marker{fill:#333333;stroke:#333333;}#mermaid-svg-ibZbli0zaXbOMg9R .marker.cross{stroke:#333333;}#mermaid-svg-ibZbli0zaXbOMg9R svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-ibZbli0zaXbOMg9R p{margin:0;}#mermaid-svg-ibZbli0zaXbOMg9R .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-ibZbli0zaXbOMg9R .cluster-label text{fill:#333;}#mermaid-svg-ibZbli0zaXbOMg9R .cluster-label span{color:#333;}#mermaid-svg-ibZbli0zaXbOMg9R .cluster-label span p{background-color:transparent;}#mermaid-svg-ibZbli0zaXbOMg9R .label text,#mermaid-svg-ibZbli0zaXbOMg9R span{fill:#333;color:#333;}#mermaid-svg-ibZbli0zaXbOMg9R .node rect,#mermaid-svg-ibZbli0zaXbOMg9R .node circle,#mermaid-svg-ibZbli0zaXbOMg9R .node ellipse,#mermaid-svg-ibZbli0zaXbOMg9R .node polygon,#mermaid-svg-ibZbli0zaXbOMg9R .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-ibZbli0zaXbOMg9R .rough-node .label text,#mermaid-svg-ibZbli0zaXbOMg9R .node .label text,#mermaid-svg-ibZbli0zaXbOMg9R .image-shape .label,#mermaid-svg-ibZbli0zaXbOMg9R .icon-shape .label{text-anchor:middle;}#mermaid-svg-ibZbli0zaXbOMg9R .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-ibZbli0zaXbOMg9R .rough-node .label,#mermaid-svg-ibZbli0zaXbOMg9R .node .label,#mermaid-svg-ibZbli0zaXbOMg9R .image-shape .label,#mermaid-svg-ibZbli0zaXbOMg9R .icon-shape .label{text-align:center;}#mermaid-svg-ibZbli0zaXbOMg9R .node.clickable{cursor:pointer;}#mermaid-svg-ibZbli0zaXbOMg9R .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-ibZbli0zaXbOMg9R .arrowheadPath{fill:#333333;}#mermaid-svg-ibZbli0zaXbOMg9R .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-ibZbli0zaXbOMg9R .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-ibZbli0zaXbOMg9R .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-ibZbli0zaXbOMg9R .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-ibZbli0zaXbOMg9R .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-ibZbli0zaXbOMg9R .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-ibZbli0zaXbOMg9R .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-ibZbli0zaXbOMg9R .cluster text{fill:#333;}#mermaid-svg-ibZbli0zaXbOMg9R .cluster span{color:#333;}#mermaid-svg-ibZbli0zaXbOMg9R div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-ibZbli0zaXbOMg9R .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-ibZbli0zaXbOMg9R rect.text{fill:none;stroke-width:0;}#mermaid-svg-ibZbli0zaXbOMg9R .icon-shape,#mermaid-svg-ibZbli0zaXbOMg9R .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-ibZbli0zaXbOMg9R .icon-shape p,#mermaid-svg-ibZbli0zaXbOMg9R .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-ibZbli0zaXbOMg9R .icon-shape .label rect,#mermaid-svg-ibZbli0zaXbOMg9R .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-ibZbli0zaXbOMg9R .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-ibZbli0zaXbOMg9R .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-ibZbli0zaXbOMg9R :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 拷贝到机器 B
机器 A
mysqldump -B test1 > test1.sql
test1.sql
库的完整 SQL 历史
机器 B
source test1.sql
test1 库与数据原样恢复
变体语法按需取用:
bash
mysqldump -u root -p 库名 表1 表2 > 文件.sql # 只备份库中的若干表(不带 -B)
mysqldump -u root -p -B 库1 库2 > 文件.sql # 同时备份多个库
-B 是关键开关:带 -B,备份文件含 create database,恢复时无需预建库;不带 -B(如只备份若干表),文件里没有建库语句,恢复前必须先把库手动建好、use 进入,再 source。上一节说的"换名恢复"正是利用这一点:不带 -B 备份旧库内容,建好新名空库,source 回去。
八、show processlist:查看谁连在库上
库操作部分最后给一个运维小命令。感觉数据库访问变慢时,先看当前有哪些连接:
sql
show processlist;
结果示例(行已精简):
txt
+----+------+-----------+------+---------+------+-------+-------------------+
| 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 表示未选库),Command 当前状态(Sleep 空闲挂起、Query 正在执行查询),Time 已持续秒数,Info 正在执行的语句。用途有二:排查慢与排查入侵。发现陌生来源的连接(尤其 Host 不是本机的),很可能库已被入侵;库变慢时看谁在跑什么 SQL,空闲挂起过久的连接是清理对象。
库的操作至此收束为一条纪律:库建好后轻易不动,改名、删库都要先备份并评估上层影响。下面进入本课第二阶段:库内部的表。
九、建表:语法与完整示例
第二阶段处理库里面的表,同样是四个话题:创建表、查看表、修改表、删除表,即表结构的增删查改。先建表。建表语法与建库对称,区别在于多了圆括号内的列定义:
sql
CREATE TABLE [IF NOT EXISTS] table_name (
field1 datatype [comment '列说明'],
field2 datatype [comment '列说明']
) character set 字符集 collate 校验规则 engine 存储引擎;
语法要点:
- 列定义成对出现:列名在前、类型在后。comment '说明' 给列加注释,团队协作时通过 show create table 回看。
- 列之间用逗号分隔,最后一列后面不能有逗号,否则语法错误。
- 圆括号后的 character set、collate、engine 子句都可省略:省略时表继承所在库的字符集与校验规则,存储引擎取配置默认 InnoDB。
- 列类型(int、varchar、date 等)本课先用起来,取值规则由下一课《4.MySQL数据类型》专门展开。
课程演示建两张结构完全相同的表,故意把存储引擎分开(引擎与编码一样,等号、空格两种风格等价):
sql
create database user_db charset=utf8; -- 建演示库
use user_db;
create table users ( -- 写法一:空格风格,MyISAM 引擎
id int,
name varchar(20) comment '用户名',
password char(32) comment '密码是 32 位的 md5 值',
birthday date comment '生日'
) character set utf8 collate utf8_general_ci engine MyISAM;
create table users2 ( -- 写法二:等号风格,InnoDB 引擎
id int,
name varchar(20) comment '用户名',
password char(32) comment '密码是 32 位的 md5 值',
birthday date comment '生日'
) charset=utf8 collate=utf8_general_ci engine=InnoDB;
回车后 user_db 目录内立即多出两张表对应的磁盘文件。为什么建两张一样的表?下一节看存储引擎如何改变文件形态。
十、存储引擎不同,磁盘文件不同
回到数据目录观察两张表的文件:
txt
$ ls /var/lib/mysql/user_db
db.opt users.frm users.MYD users.MYI -- users:3 个文件
users2.frm users2.ibd -- users2:2 个文件
同为一条 create table,文件个数不同,分工如下:
| 引擎 | 文件数 | 文件分工 |
|---|---|---|
| MyISAM | 3 | 表结构 .frm;数据文件 .MYD;索引文件 .MYI,数据与索引分离 |
| InnoDB(默认) | 2 | 表结构 .frm;.ibd 内数据与索引合并存放 |
结论:存储引擎决定表在磁盘上的组织方式,文件个数与分工随引擎不同而不同。这正是《2.MySQL数据库基础》所说"存储引擎是存储方案的具体实现"的落地证据;《12.MySQL索引(上)》讲磁盘 IO 时见到的 .ibd,就是 InnoDB 表的数据文件。文件内部是二进制格式,由 mysqld 服务端维护,使用者无需直接操作。列类型、字符集、引擎共同构成表的完整定义,show create table 可以看到全部细节(下一节)。
十一、查看表结构
建好的表如何查看?三个命令各管一层:
sql
show tables; -- 当前库有哪些表
desc users; -- 表内字段明细(desc 是 describe 的缩写)
show create table users\G; -- 建表原语完整回放(\G 让输出竖排,更易读)
desc users 输出形如:
txt
mysql> desc users;
+----------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------+-------------+------+-----+---------+-------+
| id | int(11) | YES | | NULL | |
| name | varchar(20) | YES | | NULL | |
| password | char(32) | YES | | NULL | |
| birthday | date | YES | | NULL | |
+----------+-------------+------+-----+---------+-------+
desc 只回答"表里有哪些列、各是什么类型",六列含义:Field 列名、Type 列类型、Null 是否允许为空、Key 索引情况(主键、外键等约束后续课程展开)、Default 默认值、Extra 附加信息。comment 等更完整的信息 desc 不显示,要看 show create table:返回的正是当初建表的完整语句,包含字符集、校验规则、引擎与每列 comment。它和你敲的原始语句可能不完全一样:SQL 进入服务端后经过词法、语法分析,被规范化为标准写法记录(补齐默认值、统一格式)。MySQL 忠实记录每次结构操作的最终形态,这既是审计痕迹,也是 show create table 能精确回放的依据。
十二、修改表(一):加列与改列属性
表结构修改与改数据是两回事:改结构属 DDL,操作的是表本身。所有结构修改从 alter table 开始,配套 add、modify、drop、change 与 rename 五个动词。以 users 表为例。先插入两行数据作底子(按建表列序给值):
sql
insert into users values (1, 'a', 'b', '1982-01-04'), (2, 'b', 'c', '1984-01-04');
1. 加列用 add。 业务场景:用户头像图片不直接入库,图片放 Linux 目录、库里只存路径:
sql
alter table users add assets varchar(100) comment '图片路径' after birthday;
after birthday 指定新列插在 birthday 之后(不写则追加到末尾)。desc users 可见五列;select * from users 会发现历史两行的 assets 全是 NULL:新列对老数据零影响,缺的字段自动补空值,这是加列的标准行为。
2. 改列属性用 modify。 把 name 的长度从 20 放宽到 60:
sql
alter table users modify name varchar(60);
desc 中 name 已变为 varchar(60),放宽长度不会动已有数据。但此时执行 show create table users\G 会发现 name 列原来的 comment '用户名' 丢了 。原因:modify 是整列覆盖式修改 ,新定义整体替换旧定义,新写法里没带上的属性全部丢失。因此,修改列的某个属性,必须先把该列全部属性原样抄全(用 show create table 取整列定义),只改目标项再提交。
sql
alter table users modify name varchar(60) comment '用户名';
十三、修改表(二):删列、改表名与改列名
3. 删列用 drop。 password 列不想要了:
sql
alter table users drop password;
desc users 只剩四列。drop 列连同该列全部数据永久删除、不可恢复,动手前确认列数据已无用或已备份。
4. 改表名用 rename:
sql
alter table users rename to employee; -- to 可以省略
show tables 中 users 消失、employee 出现。改表名在 Linux 上就是给表文件改名,底层走 mv(移动/重命名)系统调用,与普通文件改名无异;表名随时可改,但上层代码中的表名引用要同步修改。
5. 改列名用 change。 把 name 改成 xingming:
sql
alter table employee change name xingming varchar(60);
change 与 modify 的差别在列名:change 把列名连同新定义一起换。与 modify 相同,change 必须给出新列的完整定义(类型、comment 等),不能只写新名字,否则同样丢属性。
五类结构修改收拢如下(modify 与 change 都要带全列定义):
| 操作 | 命令骨架 | 要点 |
|---|---|---|
| 加列 | alter table 表名 add 新列完整定义 after 某列 | 历史行该列自动为 NULL |
| 改列属性 | alter table 表名 modify 列名 完整新定义 | 覆盖式,必须带全原属性 |
| 改列名 | alter table 表名 change 旧列名 新列名 完整定义 | 必须带全原属性 |
| 删列 | alter table 表名 drop 列名 | 列数据永久删除 |
| 改表名 | alter table 表名 rename to 新表名 | 底层 mv,即表文件改名 |
十四、删除表与结构改动纪律
最后一种结构操作是删表,语法与删库一致:
sql
drop table [if exists] t1 [, t2 ...]; -- 一次可删多张
示例:把 users2 删掉:
sql
drop table users2;
show tables; -- 只剩 employee
表一旦 drop,表结构与全部数据从磁盘消失,同样不可恢复。
总结
本篇用一大节完成了库、表两层结构操作的上手,核心是让每条 SQL 都能对应到 Linux 上的动作。
库层面:建库即建目录、删库即删目录 ,防重用 if not exists,可选项集中在字符集与校验规则;字符集决定存储编码,校验规则决定比较与排序语义 ,SQL 显式指定时遵循就近原则。库的查看用 show databases、show create database,进入用 use,确认位置用 select database();修改只涉及编码,MySQL 不支持改库名,库也轻易不删。备份恢复用 mysqldump 配 source:-B 决定备份文件是否含建库语句,备份内容实质是库的完整 SQL 历史,把文件传到另一台机器 source 即可原样重建;show processlist 负责查看连接、排查入侵与慢查询。
表层面:create table 除列定义外可指定字符集、校验规则与引擎,缺省时逐级继承;存储引擎决定磁盘文件形态,MyISAM 三文件(.frm 结构、.MYD 数据、.MYI 索引),InnoDB 两文件(.frm 与数据索引合并的 .ibd)。查看用 show tables、desc、show create table,服务端会把每次结构操作规范化为标准语句记录。结构修改统一走 alter table:add 加列对历史行补 NULL,modify 与 change 是覆盖式操作、必须带全列定义,drop 删列与 drop table 删表均永久不可恢复,rename 改表名对应文件系统的 mv。这些结构操作全部属于 DDL,与操作数据的 DML 相区分。