目录
- [CentOS、Ubuntu 等发行版与 MySQL](#CentOS、Ubuntu 等发行版与 MySQL)
- 关系型数据库理论
- [MySQL 安装与配置](#MySQL 安装与配置)
- [MySQL 客户端与非客户端工具](#MySQL 客户端与非客户端工具)
- [数据类型与 SQL 模型](#数据类型与 SQL 模型)
- 表与索引管理
- 单表查询、多表查询与子查询
- [视图与 DML](#视图与 DML)
- 事务与隔离级别
- 用户与权限管理
- 日志管理
- 备份与恢复
📌 核心概念一览
| 主题 | 核心概念 | 一句话 |
|---|---|---|
| 关系运算 | 投影、选择、自然连接、笛卡尔积 | 投影取列、选择取行、自然连接按同名字段连接 |
| 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_TABLES 、STRICT_ALL_TABLES 、TRADITIONAL 等。严格模式可禁止无效数据插入、截断等。
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 | 自动递增整型,常用于主键 | 像"排队号机",取一个就加一 |
表与索引管理 📋
建表方式
- 直接定义空表;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/WRITE ;UNLOCK 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 密码:
- 停服务:
service mysqld stop - 启动时加参数:
mysqld_safe --skip-grant-tables --skip-networking & - 无密码登录:
mysql -u root - 改密码:
UPDATE mysql.user SET password=PASSWORD('new_pass') WHERE user='root'; FLUSH PRIVILEGES; - 去掉参数重启
--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 流程概要
- 完全备份:innobackupex --user=root --password=xxx /backup/
- 准备:innobackupex --apply-log /backup/时间戳目录/
- 恢复:innobackupex --copy-back /backup/时间戳目录/,再 chown mysql:mysql 数据目录
- 增量:--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 物理热备工具 | 像"专业搬家队",不关门也能搬 |