MySQL 数据库理论、安装、查询、事务与备份恢复

目录

  1. [CentOS、Ubuntu 等发行版与 MySQL](#CentOS、Ubuntu 等发行版与 MySQL)
  2. 关系型数据库理论
  3. [MySQL 安装与配置](#MySQL 安装与配置)
  4. [MySQL 客户端与非客户端工具](#MySQL 客户端与非客户端工具)
  5. [数据类型与 SQL 模型](#数据类型与 SQL 模型)
  6. 表与索引管理
  7. 单表查询、多表查询与子查询
  8. [视图与 DML](#视图与 DML)
  9. 事务与隔离级别
  10. 用户与权限管理
  11. 日志管理
  12. 备份与恢复

📌 核心概念一览

主题 核心概念 一句话
关系运算 投影、选择、自然连接、笛卡尔积 投影取列、选择取行、自然连接按同名字段连接
MySQL 安装 cmake、yum、通用二进制、源码 5.5+ 用 cmake 编译;yum 装 rpm;二进制解压即用
存储引擎 MyISAM、InnoDB、表空间、.frm/.MYD/.MYI/.ibd MyISAM 无事务表锁;InnoDB 事务行锁、支持热备
客户端工具 mysql、mysqladmin、mysqldump、mysqlimport、mysqlcheck mysql 交互/批处理;mysqladmin 管理;mysqldump 逻辑备份
数据类型 数值、字符、日期、ENUM/SET、sql_mode 定长/变长、精确/近似;sql_mode 控制校验与隐式转换
表与索引 CREATE/ALTER TABLE、主键、唯一键、外键、索引 主键唯一标识;外键引用完整性;索引加速查询
查询 SELECT、WHERE、JOIN、子查询、视图 单表/多表/子查询;视图即保存的 SELECT
事务 ACID、隔离级别、锁、MVCC、autocommit 原子性/一致性/隔离性/持久性;READ COMMITTED 等四级
用户权限 user@host、GRANT、REVOKE、授权表、FLUSH PRIVILEGES 权限存 mysql 库;GRANT 授权、REVOKE 撤销
日志 错误/一般/慢查询/二进制/中继/事务日志 二进制日志用于复制与即时点恢复;事务日志保证 D 性
备份恢复 热/温/冷、完全/增量/差异、mysqldump、LVM、Xtrabackup InnoDB 热备用 Xtrabackup 或 --single-transaction

CentOS、Ubuntu 等发行版与 MySQL 🐧

包名与服务名

项目 CentOS / RHEL Ubuntu / Debian
服务端包 mysql-server 或 mariadb-server mysql-server 或 mariadb-server
客户端包 mysql mysql-client 或 default-mysql-client
开发包 mysql-devel libmysqlclient-dev
服务名 mysqld mysql 或 mysqld
启动 service mysqld start 或 systemctl start mysqld systemctl start mysql
配置文件 /etc/my.cnf /etc/mysql/my.cnf 或 /etc/mysql/mysql.conf.d/
数据目录 /var/lib/mysql(rpm)或编译指定 /var/lib/mysql

安装方式对照

方式 CentOS / RHEL Ubuntu / Debian
包安装 yum install mysql-server 或 mariadb-server apt install mysql-server 或 mariadb-server
查已安装 rpm -qa | grep mysql;yum list installed mysql* dpkg -l | grep mysql
编译依赖 yum install cmake gcc-c++ ncurses-devel 等 apt install cmake g++ libncurses5-dev 等
初始化 mysql_install_db 或 mysqld --initialize(5.7+) 包安装后多自动初始化;源码同 mysqld --initialize

使用场景与发行版选择

场景 建议 说明
企业/生产 CentOS/RHEL 或 Ubuntu LTS 长期支持、文档多;MySQL/MariaDB 包均可用
开发/学习 任意,Ubuntu 安装更简单 apt install mysql-server 一条即可
编译安装 两派步骤类似 依赖包名不同:*-devel(RHEL)vs *-dev(Debian)

生活例子:CentOS 像"标准套餐"(服务名 mysqld、配置 /etc/my.cnf),Ubuntu 像"另一家店同款菜"(服务可能叫 mysql、配置在 /etc/mysql/),吃起来都是 MySQL,只是摆盘略不同。


关系型数据库理论 📐

关系运算

运算 含义 SQL 对应 生活例子
投影 只输出指定的属性(列) SELECT col1, col2 FROM tb 像"只填姓名和电话两列"
选择 只输出符合条件的行 WHERE 条件 像"只选年龄>18 的人"
自然连接 两表按同名字段等值连接 JOIN ON 或 NATURAL JOIN 像"按学号把学生表和成绩表对齐"
笛卡尔积 两表所有行两两组合 FROM a, b 无 WHERE 像"每件上衣配每条裤子"全组合
两结果集合并去重 UNION 像"两个班级名单合并成一份"

SQL 语言组成

类型 作用 典型语句
DDL 数据定义(库、表、索引、视图) CREATE、ALTER、DROP
DML 数据操作(增删改查) SELECT、INSERT、UPDATE、DELETE
完整性定义 约束(主键、外键、唯一、检查) 含在 DDL 中
事务控制 提交、回滚、保存点 COMMIT、ROLLBACK、SAVEPOINT
DCL 授权与回收 GRANT、REVOKE
嵌入式/动态 SQL 程序与 RDBMS 交互 ODBC、JDBC、mysql_connect() 等

程序与 RDBMS 交互方式

对比:嵌入式 SQL 与 动态 SQL

对比项 嵌入式 SQL 动态 SQL
确定时机 编译时语句就固定 运行时拼接/指定 SQL
典型接口 ODBC(C/通用) JDBC(Java)、各语言驱动(如 PHP mysql_*)
方式 预编译、绑定变量 通过 API 发 SQL 字符串、取结果

存储引擎与表文件

对比:MyISAM 与 InnoDB

对比项 MyISAM InnoDB
事务 不支持 支持
表锁 行锁(并发好)
外键 不支持 支持
表文件 .frm + .MYD + .MYI .frm + .ibd(每表一表空间时)或共享表空间
索引 B-Tree、FULLTEXT、空间索引 B-Tree、聚簇索引、自适应 hash
表压缩 支持(myisampack) 不支持
适用 读多写少、数据仓库(1.5.8 前性能好) 在线事务、高并发写(5.5.8+ 默认推荐)
备份 仅温备 可热备(Xtrabackup、--single-transaction)

MyISAM
InnoDB
📋 表
存储引擎?
📄 .frm 结构

📄 .MYD 数据

📄 .MYI 索引
📄 .frm 结构

📄 .ibd 表空间

或共享 ibdata
🔒 表锁
🔒 行锁

InnoDB 每表一表空间innodb_file_per_table=1(建议开启),每表生成独立 .ibd 文件;否则所有表共享 ibdata1。查看:SHOW VARIABLES LIKE 'innodb_file%';

查看表引擎SHOW TABLE STATUS LIKE 'tb_name'\G;SHOW ENGINES;

修改表引擎ALTER TABLE tb_name ENGINE=InnoDB;

表空间与数据字典

概念 含义 生活例子
表空间(table space) 存多个表数据的文件或逻辑空间 像"一层楼里多间办公室"
数据字典(Data Dictionary) 存关系名、字段名、类型、约束、用户等元数据 像"整栋楼的登记册"
缓冲区管理器 管理内存中的页、置换策略 像"前台把常用房间钥匙放手边"
访问路径选择性 某条件用某索引能少读多少页 像"查电话簿按姓查比一页页翻快"

📖 名词解释

名词 解释 生活例子
RDBMS 关系型数据库管理系统 像"用表格管数据的软件"
关系(Relation) 一张表,行是元组,列是属性 像"一张 Excel 表"
元组(Tuple) 表中的一行 像"表格里的一行记录"
属性(Attribute) 表中的一列 像"表格里的列名"
投影 只取部分列 像"只抄姓名和电话"
选择 只取满足条件的行 像"只挑 18 岁以上的"
自然连接 按同名列等值连接两表 像"按学号把两张表拼起来"
笛卡尔积 两表行两两组合 像"上衣×裤子所有搭配"
ODBC 开放数据库互联,通用 C/API 像"万能翻译器",各种程序都能用
JDBC Java 数据库互联 像"Java 专用翻译器"
存储引擎 表数据的底层实现(MyISAM/InnoDB 等) 像"发动机类型",同车不同引擎

MySQL 安装与配置 🛠️

安装方式概览

方式 特点 适用
rpm/deb 包 安装快、路径固定、版本随发行版 快速部署、与系统一致
通用二进制 解压即用、需自建用户与初始化 要指定版本、不想编译时
源码编译 5.5+ 用 cmake,可定制选项与路径 定制、生产统一环境

配置文件查找顺序

Unix 下查找顺序(先找到的优先,但会继续读后面的,同选项后读的覆盖先读的):

text 复制代码
/etc/my.cnf → /etc/mysql/my.cnf → $MYSQL_HOME/my.cnf → --defaults-extra-file 指定文件 → ~/.my.cnf

对比:CentOS 与 Ubuntu 常见路径

发行版 常见主配置 说明
CentOS/RHEL /etc/my.cnf rpm 安装后多在此
Ubuntu/Debian /etc/mysql/my.cnf、/etc/mysql/mysql.conf.d/mysqld.cnf 可能拆成多个 include

cmake 编译 MySQL 5.5

configure 与 cmake 对照

make 方式 cmake 方式
./configure cmake .
./configure --help cmake . -LH 或 ccmake .
--prefix=/usr/local/mysql -DCMAKE_INSTALL_PREFIX=/usr/local/mysql

常用 cmake 选项

bash 复制代码
# 路径
-DCMAKE_INSTALL_PREFIX=/usr/local/mysql
-DMYSQL_DATADIR=/data/mysql
-DSYSCONFDIR=/etc

# 存储引擎(默认有 csv、myisam、myisammrg、heap)
-DWITH_INNOBASE_STORAGE_ENGINE=1
-DWITH_ARCHIVE_STORAGE_ENGINE=1
-DWITH_BLACKHOLE_STORAGE_ENGINE=1
-DWITH_FEDERATED_STORAGE_ENGINE=1
-DWITHOUT_EXAMPLE_STORAGE_ENGINE=1

# 字符集
-DDEFAULT_CHARSET=utf8
-DDEFAULT_COLLATION=utf8_general_ci
-DEXTRA_CHARSETS=all

# 其他
-DMYSQL_TCP_PORT=3306
-DMYSQL_UNIX_ADDR=/tmp/mysql.sock
-DWITH_SSL=system
-DWITH_ZLIB=system

编译与安装步骤示例

bash 复制代码
groupadd -r mysql
useradd -g mysql -r -d /data/mydata mysql
tar xf mysql-5.5.25a.tar.gz && cd mysql-5.5.25a
cmake . -DCMAKE_INSTALL_PREFIX=/usr/local/mysql \
  -DMYSQL_DATADIR=/mydata/data \
  -DSYSCONFDIR=/etc \
  -DWITH_INNOBASE_STORAGE_ENGINE=1 \
  -DDEFAULT_CHARSET=utf8 \
  -DDEFAULT_COLLATION=utf8_general_ci
make && make install

清理上次编译make clean 并删除 CMakeCache.txt

yum 安装与基本操作(CentOS)

bash 复制代码
# 查看是否已安装
yum list installed mysql*
rpm -qa | grep mysql

# 安装
yum install mysql
yum install mysql-server
yum install mysql-devel

# 启动与开机自启
service mysqld start
chkconfig --add mysqld
chkconfig --list | grep mysql

# 设置 root 密码
mysqladmin -u root password '123456'

# 忘记密码时(停服务后)
mysqld_safe --user=root --skip-grant-tables &
mysql -u root
# 在 mysql 中: UPDATE mysql.user SET password=PASSWORD('new_pass') WHERE user='root'; FLUSH PRIVILEGES;

手动安装后的初始化

bash 复制代码
chown -R mysql:mysql /usr/local/mysql
scripts/mysql_install_db --user=mysql --datadir=/usr/local/mysql/data
cp support-files/my-large.cnf /etc/my.cnf
cp support-files/mysql.server /etc/init.d/mysqld
chkconfig --add mysqld
service mysqld start
# 建议在 /etc/profile.d/mysql.sh 中加 export PATH=$PATH:/usr/local/mysql/bin

修改 root 密码的几种方式

方法 命令/操作 说明
mysqladmin mysqladmin -u root -p password 'NEW_PASS' 需知旧密码
SET PASSWORD SET PASSWORD FOR 'root'@'localhost'=PASSWORD('new_pass'); SQL 内执行
UPDATE user UPDATE mysql.user SET password=PASSWORD('new_pass') WHERE ...; FLUSH PRIVILEGES; 改表后必须 FLUSH
--skip-grant-tables 启动时加该参数,再 UPDATE user 改密码,再去掉参数重启 忘记密码时用

初始账号说明

Unix 上 mysql_install_db 会创建:

  • 三个 root:root@127.0.0.1、root@localhost、root@hostname
  • 两个匿名用户:''@localhost、''@hostname

建议删除匿名用户并限制 root 的 host;远程访问需 GRANT 并开放防火墙 3306。

📖 名词解释

名词 解释 生活例子
cmake 跨平台构建工具,可 out-of-source 编译 像"在工地外画图纸,不弄脏源码房"
mysqld MySQL 服务端进程 像"数据库总台",负责存数据、执行 SQL
mysqld_safe 带守护与重启逻辑的启动脚本 像"带保镖的老板",挂了会拉起来
mysql_install_db 初始化数据目录、系统库、默认用户 像"新楼第一次装修、发钥匙"
datadir 数据文件存放目录 像"仓库地址"
basedir 安装根目录 像"公司总部地址"
$MYSQL_HOME 环境变量,未设时默认等于 basedir 像"当前用的那套配置所在目录"
--skip-grant-tables 启动时不读授权表,任何人可无密码登录 像"紧急通道,不查证件"
--skip-networking 不监听 TCP,仅本地 socket 配合 skip-grant-tables 时更安全

MySQL 客户端与非客户端工具 📟

连接方式:socket 与 TCP

  • Unix 本机 :不指定 -h 或 -h localhost 时,默认用 Unix socket(如 /tmp/mysql.sock),不占端口。
  • Windows 本机 :用 命名管道(memory)
  • -h 127.0.0.1 或远程 IP :走 TCP/IP

无或 localhost
127.0.0.1 或 IP
💻 mysql 客户端
-h 参数?
🔌 Unix Socket

/tmp/mysql.sock
🌐 TCP/IP

3306
🗄️ mysqld

客户端常用选项

选项 含义
-u, --user 用户名
-h, --host 主机
-p, --password 密码(可空,会提示)
-P, --port 端口
--protocol tcp、socket、pipe、memory
-D, --database 连接后默认使用的库

mysql 的两种模式

模式 用途 示例
交互式 日常查询、调试 直接 mysql -u root -p 后输入 SQL
批处理 执行脚本、自动化 mysql db_name < script.sql 或 mysql -e "SELECT ..."

mysql 内部命令摘要

命令 作用
\c 终止当前语句
\g 发送到服务器执行(不管 delimiter)
\G 发送并竖排显示结果
\d 或 delimiter 设置语句结束符
! cmd 执行 shell 命令
\q / exit / quit 退出
SOURCE file 执行脚本文件
HELP keyword 查看帮助

mysqladmin 常用命令

bash 复制代码
mysqladmin -uroot -p password 'NEW_PASS'   # 改密码
mysqladmin create DATABASE                  # 建库
mysqladmin drop DATABASE                    # 删库
mysqladmin ping                             # 检测服务是否存活
mysqladmin processlist                      # 线程列表
mysqladmin status                           # 简要状态
mysqladmin status --sleep 2 --count 2       # 每 2 秒打一次,打 2 次
mysqladmin extended-status                 # 状态变量
mysqladmin variables                        # 服务器变量
mysqladmin flush-privileges                 # 重载授权表
mysqladmin flush-logs                       # 滚动日志
mysqladmin shutdown                         # 关闭服务
mysqladmin start-slave / stop-slave          # 启停复制

MyISAM 非客户端工具

工具 作用
myisamchk 检查、修复 MyISAM 表文件(直接操作文件,不连 mysqld)
myisampack 压缩 MyISAM 表为只读

GUI 客户端工具

工具 平台 特点
phpMyAdmin Web(需 PHP + Web 服务器) 免费、跨平台、浏览器访问
MySQL Workbench Windows/Linux/Mac 官方工具,可视化建模、设计、管理
SQLyog Windows 成熟、社区版免费、企业版功能全
Navicat for MySQL 跨平台 商业软件,界面友好
MySQL Administrator 跨平台 用户管理、监控、备份恢复
MySQL Query Browser 跨平台 查询编辑器、可视化查询

mysql 客户端高级特性

特性 说明 命令/选项
历史记录 保存命令历史 ~/.mysql_history
Tab 补全 自动补全库名、表名、列名 默认开启;--disable-auto-rehash 关闭;# 或 rehash 重新加载
输出格式 水平/垂直/HTML/XML \G 竖排;--html 或 -H;--xml 或 -X
分页 像 more/less 分页显示 \P more 或 pager more;\n 或 nopager 取消
安全更新模式 防止误删全表 --safe-updates:UPDATE/DELETE 必须有 WHERE 或 LIMIT
快捷键 Ctrl-w 删词、Ctrl-u 删行、Ctrl-a/e 行首/尾 类似 bash

📖 名词解释

名词 解释 生活例子
mysql 命令行客户端,发 SQL、看结果 像"前台接线员",你说话(SQL)他转达给后台
mysqladmin 管理命令,改密码、看状态、flush 等 像"经理专用电话",管人不干活
mysqldump 逻辑备份,导出为 SQL 文本 像"把仓库清单抄成一本册子"
mysqlcheck 检查、修复、分析表 像"仓库巡检员"
mysqlimport 把文本文件导入表 像"按清单往仓库搬货"
delimiter 指定语句结束符,常用于存储过程/触发器 像"换成分号以外的句号,避免和语句里的分号冲突"
\G 结果竖排显示 像"把横表转成竖表看"
批处理模式 从文件或管道读 SQL 执行 像"按稿子念,不一句句敲"

数据类型与 SQL 模型 📊

字符集与排序规则

bash 复制代码
SHOW CHARACTER SET;    # 支持的字符集
SHOW COLLATION;        # 字符集及排序规则

对比:常见字符集

字符集 说明 典型用途
utf8 MySQL 的 utf8(最多 3 字节) 通用,省空间
utf8mb4 完整 UTF-8(4 字节,含 emoji) 建议新库使用
gbk / gb2312 中文 老系统、国内

数值类型详解

类型 字节 有符号范围 无符号范围 说明
TINYINT 1 -128 ~ 127 0 ~ 255 小整数
SMALLINT 2 -32768 ~ 32767 0 ~ 65535 中整数
MEDIUMINT 3 -8388608 ~ 8388607 0 ~ 16777215 中等整数
INT 4 -2147483648 ~ 2147483647 0 ~ 4294967295 标准整数
BIGINT 8 约 -9×10^18 ~ 9×10^18 0 ~ 约 1.8×10^19 大整数
DECIMAL(g,f) 变长 精确小数 精确小数 金额等精确计算
FLOAT(g,f) 4 单精度浮点 单精度浮点 可能精度损失
DOUBLE(g,f) 8 双精度浮点 双精度浮点 可能精度损失
BIT(x) (x+7)/8 1~64 位 1~64 位 存位串

字符类型详解

类型 最大长度 特点 适用
CHAR(n) 255 定长,不足补空格 固定长度(手机号、身份证)
VARCHAR(n) 65535 字节 变长,+1~2 字节存长度 变长字段(姓名、地址)
BINARY(n) 255 定长二进制,不足补 \0 定长二进制
VARBINARY(n) 65535 变长二进制 变长二进制
TINYTEXT/TINYBLOB 255 字节 +1 字节开销 短文本/二进制
TEXT/BLOB 64KB +2 字节开销 文章、小文件
MEDIUMTEXT/MEDIUMBLOB 16MB +3 字节开销 长文章
LONGTEXT/LONGBLOB 4GB +4 字节开销 大文本/文件(不推荐存 DB)

日期时间类型详解

类型 格式 范围 字节 时区
DATE YYYY-MM-DD 1000-01-01 ~ 9999-12-31 3 无关
TIME HH:MM:SS -838:59:59 ~ 838:59:59 3 无关
DATETIME YYYY-MM-DD HH:MM:SS 1000-01-01 00:00:00 ~ 9999-12-31 23:59:59 8 无关
TIMESTAMP YYYY-MM-DD HH:MM:SS 1970-01-01 00:00:01 ~ 2038-01-19 03:14:07 4 受影响
YEAR(2/4) YY 或 YYYY 1901~2155 或 7069(19702069) 1 无关

注意:DATE + TIME 共 6 字节,DATETIME 8 字节;TIMESTAMP 存 UTC,取时转当前时区。

ENUM 与 SET

类型 说明 示例 内部存储
ENUM 枚举,单选(1~65535 个值) gender ENUM('M','F') 索引值(1、2...)
SET 集合,多选(1~64 个值) hobby SET('读书','运动','音乐') 位串(如 '读书,音乐' 存为 0b101)

ENUM 插入数字 :插入 1 等同插入第一个字符串;插入超范围数字视为无效。SET 比较:可用位运算(& 精确匹配、| 子集判断)。

AUTO_INCREMENT 要点 :整型、非空、主键或唯一键;每表一个;可用 LAST_INSERT_ID() 取最后插入 ID;可设 auto_increment_offset 改起始值。SERIAL DEFAULT VALUE 是 NOT NULL AUTO_INCREMENT UNIQUE KEY 的简写。

BOOLEAN:是 TINYINT(1) 的别名,0 为 FALSE,非 0 为 TRUE。

sql_mode

控制校验与隐式转换:如 STRICT_TRANS_TABLESSTRICT_ALL_TABLESTRADITIONAL 等。严格模式可禁止无效数据插入、截断等。

bash 复制代码
SHOW GLOBAL VARIABLES LIKE 'sql_mode';
SET GLOBAL sql_mode='STRICT_TRANS_TABLES';
SET SESSION sql_mode='STRICT_TRANS_TABLES';

对比:服务器变量作用域

作用域 查看 修改 生效范围
全局 SHOW GLOBAL VARIABLES SET GLOBAL var=value 对新会话有效
会话 SHOW [SESSION] VARIABLES SET SESSION var=value 仅当前会话、即时

生活例子:sql_mode 像"店规"------宽松时"差不多就行"(隐式转换、截断);严格时"不符合就不收"(报错)。

📖 名词解释

名词 解释 生活例子
字符集(Character Set) 字符与二进制编码的对应 像"字典",字和编号一一对应
排序规则(Collation) 比较与排序规则 像"按拼音排还是按笔画排"
sql_mode 服务器 SQL 行为与校验模式 像"店规",严不严你定
AUTO_INCREMENT 自动递增整型,常用于主键 像"排队号机",取一个就加一

表与索引管理 📋

建表方式

  1. 直接定义空表;2. 从查询结果建表(CREATE TABLE ... SELECT);3. 按其他表结构建空表(LIKE)。
sql 复制代码
CREATE TABLE tb1 (id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, Name CHAR(20) NOT NULL, Age TINYINT NOT NULL) ENGINE=InnoDB;
CREATE TABLE tb2 SELECT * FROM tb1;   -- 复制数据与结构,部分属性可能丢失
CREATE TABLE tb3 LIKE tb1;            -- 只复制结构

建表示例(原文)

sql 复制代码
-- 单字段主键
CREATE TABLE tb1 (
  id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
  Name CHAR(20) NOT NULL,
  Age TINYINT NOT NULL
) ENGINE=InnoDB;

-- 多字段约束
CREATE TABLE tb2 (
  id INT UNSIGNED NOT NULL AUTO_INCREMENT,
  Name CHAR(20) NOT NULL,
  Age TINYINT NOT NULL,
  PRIMARY KEY(id),
  UNIQUE KEY(Name),
  INDEX(Age)
);

-- 外键示例
CREATE TABLE courses (
  cid TINYINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
  course VARCHAR(50) NOT NULL
);

CREATE TABLE person (
  id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
  name CHAR(20) NOT NULL,
  cid TINYINT UNSIGNED,
  FOREIGN KEY (cid) REFERENCES courses(cid)
);

键与索引

类型 说明 数量
PRIMARY KEY 主键,唯一且非空 每表一个
UNIQUE KEY 唯一键,可空 可多个
INDEX/KEY 普通索引,加速查询 可多个
FOREIGN KEY 外键,引用他表主键/唯一键 InnoDB 支持

📋 表
🔑 主键

PRIMARY KEY
🔒 唯一键

UNIQUE
📇 索引

INDEX
🔗 外键

FOREIGN KEY
📋 另一张表

ALTER TABLE 常用操作

sql 复制代码
-- 添加字段
ALTER TABLE students ADD course VARCHAR(100);
ALTER TABLE students ADD starttime DATE DEFAULT '2013-12-12';

-- 修改字段
ALTER TABLE students MODIFY age INT;
ALTER TABLE students CHANGE Course course VARCHAR(50) NOT NULL;

-- 删除字段
ALTER TABLE students DROP course;

-- 添加索引
ALTER TABLE test ADD UNIQUE KEY (course);
CREATE INDEX idx_name ON tb_name (col);

-- 添加外键
ALTER TABLE person ADD FOREIGN KEY foreign_cid(cid) REFERENCES courses(cid);

-- 修改表名
ALTER TABLE test RENAME TO testcourses;
RENAME TABLE testcourse TO test;

-- 修改引擎
ALTER TABLE courses ENGINE=InnoDB;

-- 查看索引
SHOW INDEXES FROM tb_name;

单表查询、多表查询与子查询 🔍

SELECT 结构

text 复制代码
SELECT 投影列 FROM 表 [WHERE 条件] [GROUP BY 列] [HAVING 条件] [ORDER BY 列] [LIMIT [offset,] n]
子句 作用
WHERE 行过滤,=、>、<、BETWEEN、LIKE、IN、IS NULL、AND/OR/NOT
GROUP BY 分组,常配聚合 SUM/AVG/COUNT/MAX/MIN
HAVING 对分组结果过滤
ORDER BY 排序,ASC/DESC
LIMIT 限制行数

LIKE% 任意长度,_ 单字符。REGEXP/RLIKE:正则。

多表连接

连接类型 说明 典型写法
交叉连接 笛卡尔积 FROM a, b
自然/等值连接 按等值条件 FROM a JOIN b ON a.id=b.aid
左外连接 左表全保留 FROM a LEFT JOIN b ON ...
右外连接 右表全保留 FROM a RIGHT JOIN b ON ...
自连接 同一张表当两张用 FROM t AS a JOIN t AS b ON ...

子查询

  • 在 WHERE 中:比较运算子查询需返回单值;IN 子查询可返回多行单列。
  • 在 FROM 中:把子查询结果当表用(派生表)。

联合查询

UNION :合并多条 SELECT 结果,去重;UNION ALL:不去重。

生活例子:左连接像"点名册+成绩单"------点名册所有人都在,没成绩的填 NULL。


视图与 DML 📄

视图

视图是保存下来的 SELECT;查询视图即执行该 SELECT。不单独存数据。物化视图:某些 DBMS 支持将视图结果缓存(MySQL 不直接支持,可用表+触发器模拟)。

sql 复制代码
CREATE VIEW v_name AS SELECT ...;
SHOW CREATE VIEW v_name;
DROP VIEW v_name;

DML 详解

INSERT

sql 复制代码
-- 单行
INSERT INTO tb (col1, col2) VALUES (val1, val2);
-- 多行
INSERT INTO tb (col1, col2) VALUES (v1, v2), (v3, v4);
-- SET 方式
INSERT INTO tb SET col1=val1, col2=val2;
-- 从其他表插入
INSERT INTO teachers (tname, gender, age) 
  SELECT name, gender, age FROM students WHERE age > 20;
-- 查询最后插入 ID
SELECT LAST_INSERT_ID();

REPLACE:有主键/唯一键冲突则删旧插新,否则直接插入。

DELETE

sql 复制代码
DELETE FROM tb WHERE condition;
-- 支持 ORDER BY + LIMIT
DELETE FROM tb WHERE age < 18 ORDER BY age LIMIT 10;

TRUNCATE:清空表并重置 AUTO_INCREMENT 计数器;比 DELETE 快,不可回滚。

UPDATE

sql 复制代码
UPDATE tb SET col1=val1, col2=val2 WHERE condition;

数据导入导出

sql 复制代码
-- 导出到文件
SELECT * INTO OUTFILE '/tmp/person.txt' FROM student.person;
-- 从文件导入
LOAD DATA INFILE '/tmp/person.txt' INTO TABLE persons;

事务与隔离级别 ⚖️

ACID

特性 含义
原子性(Atomicity) 事务内操作要么全做要么全不做
一致性(Consistency) 事务前后数据满足约束与业务规则
隔离性(Isolation) 多事务并发时互不干扰
持久性(Durability) 提交后即使宕机也不丢

📦 事务
🔬 原子性
✅ 一致性
🔀 隔离性
💾 持久性

隔离级别(从低到高)

级别 脏读 不可重复读 幻读
READ UNCOMMITTED 可能 可能 可能
READ COMMITTED 可能 可能
REPEATABLE READ 可能(InnoDB 通过 MVCC 减轻)
SERIALIZABLE
sql 复制代码
SHOW GLOBAL VARIABLES LIKE '%iso%';
SET tx_isolation='READ-COMMITTED';
START TRANSACTION;
  -- SQL
COMMIT;
ROLLBACK;
SAVEPOINT sid;
ROLLBACK TO sid;

autocommit:为 1 时每条语句自动提交;建议显式 START TRANSACTION 并 set autocommit=0 做多语句事务。

  • 读锁(共享锁):可多会话同时读。
  • 写锁(独占锁):独占写。
  • 粒度:表锁(MyISAM)、行锁(InnoDB)。
  • LOCK TABLES tb READ/WRITEUNLOCK TABLES

生活例子:事务像"转账"------扣 A 加 B 必须一起成功或一起取消;隔离级别像"排队距离",越严格越不串线。


用户与权限管理 👤

账号与授权表

  • 账号形式:'username'@'host';host 可为 IP、网段、%、_ 等。
  • 授权信息在 mysql 库的 user、db、host(废弃)、tables_priv、columns_priv、procs_priv、proxies_priv 等表中;FLUSH PRIVILEGES 使修改生效。

授权表说明

作用
user 用户账号、全局权限、非权限列(如密码、连接限制)
db 库级别权限
tables_priv 表级别权限
columns_priv 列级别权限
procs_priv 存储过程和函数权限
proxies_priv 代理用户权限

常用命令

sql 复制代码
CREATE USER 'user'@'host' IDENTIFIED BY 'password';
GRANT 权限 ON [对象类型] 对象 TO 'user'@'host' [IDENTIFIED BY 'password'];
  -- 对象类型:TABLE、FUNCTION、PROCEDURE
REVOKE 权限 ON 对象 FROM 'user'@'host';
SHOW GRANTS FOR 'user'@'host';
DROP USER 'user'@'host';
RENAME USER old TO new;

权限层级 :全局(. )、库(db.*)、表(db.tb)、列(UPDATE(col))、存储过程/函数。GRANT OPTION 表示可再授权。

权限示例

sql 复制代码
-- 全局所有权限
GRANT ALL PRIVILEGES ON *.* TO 'admin'@'%' IDENTIFIED BY 'password';
-- 仅某库
GRANT SELECT, INSERT ON mydb.* TO 'user1'@'localhost';
-- 仅某表
GRANT DELETE, ALTER ON mydb.tb1 TO 'user2'@'%';
-- 仅某列
GRANT UPDATE(age) ON mydb.students TO 'user3'@'%';
-- 存储过程
GRANT EXECUTE ON FUNCTION mydb.func TO 'user4'@'%';

连接限制(GRANT 时可加)

  • MAX_QUERIES_PER_HOUR:每小时最多查询数
  • MAX_UPDATES_PER_HOUR:每小时最多更新数
  • MAX_CONNECTIONS_PER_HOUR:每小时最多连接数
  • MAX_USER_CONNECTIONS:同时最多连接数

忘记 root 密码

  1. 停服务:service mysqld stop
  2. 启动时加参数:mysqld_safe --skip-grant-tables --skip-networking &
  3. 无密码登录:mysql -u root
  4. 改密码:UPDATE mysql.user SET password=PASSWORD('new_pass') WHERE user='root'; FLUSH PRIVILEGES;
  5. 去掉参数重启

--skip-name-resolve:不反解 IP 为主机名,加速连接,建议生产开启。


日志管理 📝

日志类型对比

日志 作用 主要变量/文件
错误日志 启动/运行错误、警告 log_error、log_warnings
一般查询日志 记录所有语句(慎开) general_log、general_log_file、log_output
慢查询日志 执行时间超过 long_query_time 的 SQL slow_query_log、slow_query_log_file、long_query_time
二进制日志 变更操作,用于复制与即时点恢复 log_bin、binlog_format(statement/row/mixed)
中继日志 从库从主库复制的 binlog 事件 relay_log、relay_log_purge
事务日志(InnoDB redo) 保证持久性,随机 IO 转顺序 IO innodb_log_file_size、innodb_flush_log_at_trx_commit

二进制日志格式statement (语句)、row (行)、mixed(混合)。建议生产用 row 或 mixed。

对比:二进制日志三种格式

格式 记录内容 优点 缺点
statement SQL 语句 日志小 非确定性语句可能主从不一致
row 行数据变化 一致性好 日志大
mixed 混合,由服务器选择 折中 行为依赖服务器判断

常用日志变量(原文要点):log_error、log_warnings、general_log、general_log_file、log_output(TABLE/FILE/NONE)、slow_query_log、slow_query_log_file、long_query_time、log_bin、binlog_format、sync_binlog(建议 1)、expire_logs_days、innodb_flush_log_at_trx_commit(0/1/2)、relay_log、relay_log_purge 等。
🗄️ mysqld
📛 错误日志
📋 一般查询
🐢 慢查询
📦 二进制日志
🔴 InnoDB 事务日志
📥 中继日志

从库

二进制日志管理命令

sql 复制代码
-- 查看所有二进制日志
SHOW BINARY LOGS;
-- 查看当前使用的日志
SHOW MASTER STATUS;
-- 查看日志事件
SHOW BINLOG EVENTS IN 'mysql-bin.000007' FROM 179;
-- 删除指定日志之前的所有日志
PURGE BINARY LOGS TO 'mysql-bin.000003';
-- 手动滚动日志
FLUSH LOGS;

mysqlbinlog 工具

bash 复制代码
# 查看二进制日志内容
mysqlbinlog mysql-bin.000007

# 按位置导出
mysqlbinlog --start-position=179 --stop-position=207 mysql-bin.000007 > temp.sql

# 按时间导出
mysqlbinlog --start-datetime='2013-05-03 12:05:30' \
  --stop-datetime='2013-05-03 14:00:00' \
  mysql-bin.000003 mysql-bin.000004 > binlog.sql

# 重放到数据库
mysqlbinlog mysql-bin.000012 | mysql -uroot -p

重要日志变量详解(原文)

变量 说明 建议值
sync_binlog 多少次写操作后 fsync 到磁盘 1(最安全,每事务 sync)
innodb_flush_log_at_trx_commit 0:每秒 sync;1:每事务 sync+flush;2:每事务 sync 不 flush 1(最安全)
expire_logs_days 二进制日志自动删除天数(0~99) 7 或 14
log_output 一般/慢查询日志输出位置 FILE(TABLE 慢)
long_query_time 慢查询阈值(秒) 1~5
log_query_not_using_indexes 未用索引的查询记入慢查询 ON(排查用)
binlog_cache_size 二进制日志缓存 根据事务大小调整
max_binlog_size 单个 binlog 文件上限 1G(默认)

备份与恢复 💾

备份类型对比

维度 类型 说明
在线程度 热备 读写不中断(InnoDB 可用 Xtrabackup、--single-transaction)
温备 可读不可写(如 MyISAM 锁表)
冷备 停机备份
内容 完全 全量数据
增量 相对上次完全或上次增量以来的变化
差异 相对上次完全以来的变化
形式 物理 复制数据文件,快、可配合快照
逻辑 导出为 SQL 或文本,可读、可跨版本

常用工具对比

工具 类型 引擎支持 特点
mysqldump 逻辑 MyISAM 温、InnoDB 热(--single-transaction) 通用、可编辑、慢、大库费时
LVM 快照 物理 需数据在 LV 上,配合锁表 近乎热备、恢复快
Xtrabackup/innobackupex 物理 InnoDB 热、MyISAM 温 热备、增量、流式、压缩

mysqldump 常用选项

bash 复制代码
mysqldump -uroot -p --single-transaction --master-data=2 --flush-logs --all-databases > all.sql
# --lock-all-tables 温备(MyISAM)
# --databases db1 db2 指定库
# --routines --triggers --events 备份例程/触发器/事件

Xtrabackup 流程概要

  1. 完全备份:innobackupex --user=root --password=xxx /backup/
  2. 准备:innobackupex --apply-log /backup/时间戳目录/
  3. 恢复:innobackupex --copy-back /backup/时间戳目录/,再 chown mysql:mysql 数据目录
  4. 增量:--incremental /backup --incremental-basedir=上次备份目录;准备时用 --apply-log --redo-only 先合并 base 再合并各增量,最后对 base 做一次 --apply-log 再 copy-back。

即时点恢复

全备 + 二进制日志:先恢复全备,再用 mysqlbinlog --start-position=... --stop-position=... 或 --start-datetime/--stop-datetime 重放 binlog 到故障前一刻。

mysqldump 与 binlog 配合:备份前 FLUSH TABLES WITH READ LOCK 或 --lock-all-tables(温备);--master-data=2 在备份文件中记录当前 binlog 位置,便于从库或即时点恢复;--flush-logs 滚动 binlog。恢复时先 SET sql_log_bin=0,导入全备与增量 binlog,再 SET sql_log_bin=1。

LVM 快照要点:数据与事务日志在同一逻辑卷;FLUSH TABLES WITH READ LOCK 后 FLUSH LOGS,记录 SHOW MASTER STATUS,创建只读快照后 UNLOCK TABLES,再挂载快照做拷贝;增量用 mysqlbinlog 从记录的位置重放。

Xtrabackup 增量:基于 LSN;第一次增量 --incremental-basedir=全备目录,后续 --incremental-basedir=上次增量目录。准备时对全备目录先 --apply-log --redo-only,再逐个 --apply-log --redo-only 合并增量目录到全备,最后对全备再执行一次 --apply-log(不再 --redo-only)再 --copy-back。

生活例子:热备像"边营业边盘点",冷备像"打烊后盘点";增量像"只记今天新进的货",完全像"整本账重抄一遍"。

📖 名词解释

名词 解释 生活例子
热备份 不中断业务读写 像"边开车边换胎"(要专门工具)
逻辑备份 导出成 SQL/文本 像"把仓库写成清单"
物理备份 复制数据文件 像"整栋仓库拍照复制"
二进制日志(binlog) 记录引起或可能引起数据变化的操作 像"操作录像",可回放
LSN 日志序列号,InnoDB 页的版本标识 像"每一页的版本号"
Xtrabackup InnoDB 物理热备工具 像"专业搬家队",不关门也能搬

相关推荐
SQL必知必会2 小时前
SQL 描述性统计:超越平均值和计数
数据库·sql
ActionTech2 小时前
数据集推荐 06 | 首款 NL2GeoSQL 的测试基准和数据集来了!
数据库·人工智能·sql
长谷深风1112 小时前
Redis入门:从MySQL到高效缓存的飞跃
redis·后端·mysql·缓存·nosql·java 开发
码云数智-大飞2 小时前
跳出索引思维定式:一次基于业务逻辑的非典型 SQL 优化实践
数据库·sql
PD我是你的真爱粉2 小时前
Redis基础与数据结构
数据结构·数据库·redis
山岚的运维笔记2 小时前
SQL Server笔记 -- 第46章 窗口函数
数据库·笔记·sql·microsoft·sqlserver
科技块儿2 小时前
【工具对比】免费IP库用于广告投放是否可靠?误差率实测报告
网络·数据库·tcp/ip
晔子yy2 小时前
带你了解Java中的Mono接口
java·数据库·oracle
全栈前端老曹2 小时前
【Redis】发布订阅模型 —— Pub/Sub 原理、消息队列、聊天系统实战
前端·数据库·redis·设计模式·node.js·全栈·发布订阅模型