2. 库的操作
在 MySQL 中,数据是按 库(database)→ 表(table)→ 行(row) 的层级组织的。库是最高一级的逻辑容器,一个 MySQL 服务端可以有多个库,一个库可以有多个表。所以学习 MySQL 的第一步,就是把"库"这一层的操作搞熟。
2.1 创建数据库
语法
sql
CREATE DATABASE [IF NOT EXISTS] db_name
[create_specification [, create_specification] ...];
create_specification:
[DEFAULT] CHARACTER SET charset_name
[DEFAULT] COLLATE collation_name
db_name:数据库名,在 MySQL 中不区分大小写。IF NOT EXISTS:可选,如果库不存在才创建,避免重复创建报错CHARACTER SET:指定数据库字符集,控制数据怎么存储编码COLLATE:指定校验规则(排序规则),控制字符串比较、排序、大小写是否敏感
创建数据库案例
- 创建一个完全不指定字符集的库
sql
CREATE DATABASE IF NOT EXISTS db1;
这样创建出来的库,字符集和校验规则都会使用 MySQL 的默认配置。
- 创建一个使用 utf8 字符集、默认校验规则的库
sql
CREATE DATABASE IF NOT EXISTS db2
CHARACTER SET utf8;
- 创建一个使用 utf8 字符集、utf8_general_ci 校验规则的库
sql
CREATE DATABASE IF NOT EXISTS test1
CHARACTER SET utf8
COLLATE utf8_general_ci;
补充:在 MySQL 的 SQL 语法中,CHARSET 是 CHARACTER SET 的合法同义词,二者可以互换。例如下面三条语句完全等价:
sql
CREATE DATABASE db1 CHARACTER SET utf8mb4;
CREATE DATABASE db1 CHARSET utf8mb4;
CREATE DATABASE db1 DEFAULT CHARSET utf8mb4;
建表、改表、列定义、SHOW CHARSET 等场景同理。
但要注意:系统变量名、命令行参数、配置文件项不能简写。
2.2 字符集和校验规则
| 概念 | 作用 | 举例 |
|---|---|---|
| 字符集 | 决定"能存哪些字符、用什么编码" | utf8mb4、gbk、latin1 |
| 校验规则 | 决定"字符之间怎么比较、怎么排序" | utf8mb4_0900_ai_ci、utf8mb4_bin |
2.2.1 查看系统默认字符集与校验规则
sql
-- 查看当前数据库默认字符集
show variables like 'character_set_database';
-- 查看当前数据库默认校验规则
show variables like 'collation_database';
2.2.2 查看数据库支持的字符集
sql
show charset;
-- 或
show character set;
2.2.3 查看数据库支持的字符集校验规则
sql
show collation;
校验规则命名规律
以 utf8mb4_unicode_ci 举例:
utf8mb4:所属字符集unicode:基于 unicode 标准排序ci= case insensitive:大小写不敏感(A 和 a 认为相等)cs= case sensitive:大小写敏感(A≠a)bin:二进制比较,严格按字节对比,区分大小写
2.2.4 校验规则对数据库的影响
第一步:建两个库,字符集相同、校验规则不同
sql
CREATE DATABASE IF NOT EXISTS test1 CHARACTER SET utf8 COLLATE utf8_general_ci;
CREATE DATABASE IF NOT EXISTS test2 CHARACTER SET utf8 COLLATE utf8_bin;
第二步:分别在两个库中建同样的表,插入相同数据
sql
-- 在 test1 中
USE test1;
CREATE TABLE person (name VARCHAR(20));
INSERT INTO person VALUES ('a'), ('A'), ('b'), ('B');
-- 在 test2 中
USE test2;
CREATE TABLE person (name VARCHAR(20));
INSERT INTO person VALUES ('a'), ('A'), ('b'), ('B');
第三步:执行相同的查询 WHERE name = 'a'
sql
-- test1(utf8_general_ci,不区分大小写)
USE test1;
SELECT * FROM person WHERE name = 'a';
结果:

sql
-- test2(utf8_bin,区分大小写)
USE test2;
SELECT * FROM person WHERE name = 'a';
结果:

第四步:执行排序 ORDER BY
sql
-- test1
USE test1;
SELECT * FROM person ORDER BY name;
结果:

sql
-- test2
USE test2;
SELECT * FROM person ORDER BY name;
结果:

2.3 操纵数据库
2.3.1 查看数据库
sql
SHOW DATABASES;
查看当前所在的库:
sql
select database();
切换到某个库:
sql
use db_name;
2.3.2 显示数据库的创建语句
查看当初建库完整定义,看字符集和 collation:
sql
show create database mydb;
输出示例:

/*!40100 default.... */这个不是注释,表示当前mysql版本大于4.01版本,就执行这句话
2.3.3 修改数据库
语法:
sql
ALTER DATABASE db_name
[alter_specification [, alter_specification] ...];
alter_specification:
[DEFAULT] CHARACTER SET charset_name
[DEFAULT] COLLATE collation_name
重要说明:
ALTER DATABASE只能修改字符集和校验规则,不能修改库名(重命名库不支持,只能备份后删库重建,或新建库导数据);- 修改字符集后,已有的表不会自动变化,只影响之后新建的表(表的字符集在建表时确定);
- 生产环境改字符集需要谨慎,务必先备份。
示例:把 test2 的字符集改为 gbk
sql
alter database test2 character set gbk;
2.3.4 删除数据库
sql
DROP DATABASE [IF EXISTS] db_name;
高危操作警告:
- 执行
DROP DATABASE后,库及库内所有表、所有数据全部删除,且无法回滚; - 生产环境删库前务必:
1.先备份 (mysqldump);
2.确认当前不在目标库中(SELECT DATABASE(););
3.二次确认库名(尤其别把test1写成test);
2.3.5 备份和恢复
备份和恢复用的是 MySQL 客户端工具 mysqldump 和 mysql,不是在 mysql 交互界面里执行,需要在操作系统的终端 / 命令行中运行。
2.3.5.1 备份
语法:
sql
mysqldump -P 端口 -u 用户名 -p密码 -B 数据库名 > 备份文件路径
-B:表示备份整个库 ,且在备份文件中会包含CREATE DATABASE语句- 不带
-B时,只备份库中的表,不包含建库语句。
示例 1:备份单个库
bash
mysqldump -uroot -p -B 数据库名 > 备份文件路径
示例 2:一次备份多个库
bash
mysqldump -uroot -p -B 数据库名1 数据库名2 ... > 数据库存放路径
示例 3:只备份某张表
bash
mysqldump -uroot -p 数据库名 表名1 表名2 > 备份文件路径
2.3.5.2 还原
在 mysql 交互界面中 source
sql
mysql> source 备份文件路径;
- 如果备份一个数据库时,没有带上-B参数,在恢复数据库时,需要先创建空数据库,然后使用数据库,再使用source来还原。
2.3.6 查看连接情况
用来查看当前有哪些客户端连上 MySQL、正在执行什么 SQL、线程状态,排查卡死、慢查询。
语法:
sql
show processlist;
示例:

字段解释:
Id:连接线程 ID;User:连接用户;Host:客户端主机;db:当前所在库;Command:当前命令状态(Sleep表示空闲、Query表示正在执行查询);Time:该状态持续秒数;State:内部状态;Info:正在执行的 SQL。
3. 表的操作
3.1 创建表
sql
CREATE TABLE [IF NOT EXISTS] 表名 (
字段名1 数据类型 [COMMENT '字段注释'],
字段名2 数据类型 [COMMENT '字段注释'],
...
) [CHARACTER SET=字符集] [COLLATE=校验规则] [ENGINE=存储引擎];
创建表案例
sql
create table if not exists users (
id int comment '用户ID',
name varchar(20) comment '用户名',
password char(32) comment '密码是32位的md5值',
birthday date comment '生日'
) character set utf8 engine MyISAM;
- 不同的存储引擎,创建表的文件不一样。
users表存储引擎是MyISAM,在数据目中有三个不同的文件,分别是:users.frm:表结构users.MYD:表数据users.MYI:表索引
示例:

3.2 查看表结构
sql
desc 表名;
示例:


查看完整建表语句(推荐)
sql
show create table 表名;
示例:

这是查看表结构最完整的方式,能看到字段注释、字符集、存储引擎、索引等全部信息。
3.3 修改表
表创建后经常需要调整,比如加字段、改类型、加约束。ALTER TABLE 是修改表结构的核心命令。
1. 修改表名
sql
alter table 表名 rename to 新表名;
示例:

2. 添加列
语法:
sql
alter table 表名 add 列名 数据类型 [comment '字段注释'] [first | after 列名];
示例:

默认追加到末尾,用
after指定位置更灵活。但表结构的列顺序在业务上并不重要,不必过度纠结。
3. 修改列(MODIFY / CHANGE)
MODIFY:只改类型/约束,不改列名
sql
-- 把 name 从 VARCHAR(20) 改为 VARCHAR(60),并保留 NOT NULL 约束
alter table user modify name varchar(60) NOT NULL comment '姓名';
重点 :
MODIFY必须写出完整的列定义,否则未写出的约束会被丢弃 。比如原列是name VARCHAR(20) NOT NULL DEFAULT '',如果你只写MODIFY name VARCHAR(50),那么NOT NULL和默认值就没了!
示例:

CHANGE:改名 + 改类型
sql
-- 把 name 改名为 xingming,同时改为 VARCHAR(60)
alter table user change name xingming varchar(60) NOT NULL comment '学生姓名';
示例:

4. 删除列
sql
alter table 表名 drop 列名;
示例:

3.4 删除表
删除表结构和全部数据,表彻底消失。
sql
DROP TABLE [IF EXISTS] 表名;
-- 一次删多张表
DROP TABLE IF EXISTS t1, t2, t3;