
MySQL 介绍
MySQL 是世界上最流行的开源关系型数据库管理系统之一,被广泛应用于各种规模的应用程序中。本文将从基础概念到高级特性,全面介绍 MySQL 的核心知识。
MySQL 简介
MySQL 是一个关系型数据库管理系统,由瑞典 MySQL AB 公司开发,目前属于 Oracle 公司。MySQL 以其可靠性、性能和易用性而闻名,被广泛应用于 Web 应用、企业应用和嵌入式应用等领域。
MySQL 的主要特点
开源免费:MySQL 社区版是完全免费的,可以自由使用和修改
性能卓越:针对不同的应用场景进行了优化,提供高性能的数据处理能力
可靠性高:经过多年的发展和广泛的应用,MySQL 已经成为一个非常稳定和可靠的数据库系统
跨平台:支持多种操作系统,包括 Windows、Linux、macOS 等
支持多种编程语言:提供了丰富的 API,支持 Java、PHP、Python、C++ 等多种编程语言
MySQL 安装与配置
Windows 安装
1. 从 MySQL 官网下载安装包
2. 运行安装程序,按照向导进行安装
3. 配置 MySQL 服务和初始密码
4. 验证安装是否成功
mysql -u root -p
Linux 安装
# CentOS/RHEL
sudo yum install mysql-server
sudo systemctl start mysqld
sudo systemctl enable mysqld
# Ubuntu/Debian
sudo apt-get install mysql-server
sudo systemctl start mysql
sudo systemctl enable mysql
基本配置
MySQL 的主要配置文件是 my.cnf
(Linux)或 my.ini
(Windows),常见的配置项包括:
[mysqld]
# 基本设置
port = 3306
socket = /tmp/mysql.sock
datadir = /var/lib/mysql
# 字符集设置
character-set-server = utf8mb4
collation-server = utf8mb4_general_ci
# 连接设置
max_connections = 1000
max_connect_errors = 10000
# 缓冲区设置
key_buffer_size = 256M
sort_buffer_size = 2M
read_buffer_size = 2M
# InnoDB 设置
innodb_buffer_pool_size = 1G
innodb_log_file_size = 256M
innodb_flush_log_at_trx_commit = 1
MySQL 基础架构
MySQL 的基础架构可以分为三层:
1. 连接层:负责客户端连接、授权认证
2. 服务层:包括查询缓存、解析器、优化器、执行器等
3. 存储引擎层:负责数据的存储和提取
查询执行流程
1. 客户端发送 SQL 语句到服务器
2. 服务器检查查询缓存,如果命中则直接返回结果
3. 服务器进行 SQL 解析,生成解析树
4. 预处理器进行语法检查和字段检查
5. 查询优化器生成执行计划
6. 执行器根据执行计划调用存储引擎接口
7. 存储引擎执行操作并返回结果
SQL 语句基础
数据定义语言(DDL)
-- 创建数据库
CREATE DATABASE mydb CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
-- 使用数据库
USE mydb;
-- 创建表
CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50) NOT NULL UNIQUE,
password VARCHAR(100) NOT NULL,
email VARCHAR(100) UNIQUE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
-- 修改表
ALTER TABLE users ADD COLUMN status TINYINT DEFAULT 1;
ALTER TABLE users MODIFY COLUMN username VARCHAR(100);
ALTER TABLE users DROP COLUMN status;
-- 删除表
DROP TABLE users;
数据操作语言(DML)
-- 插入数据
INSERT INTO users (username, password, email) VALUES ('admin', 'password123', 'admin@example.com');
-- 更新数据
UPDATE users SET password = 'newpassword' WHERE username = 'admin';
-- 删除数据
DELETE FROM users WHERE id = 1;
-- 查询数据
SELECT * FROM users;
SELECT id, username, email FROM users WHERE id > 10 ORDER BY created_at DESC LIMIT 10;
数据查询语言(DQL)
-- 基本查询
SELECT * FROM users WHERE status = 1;
-- 连接查询
SELECT u.username, o.order_id, o.amount
FROM users u
JOIN orders o ON u.id = o.user_id
WHERE o.amount > 100;
-- 子查询
SELECT username FROM users
WHERE id IN (SELECT user_id FROM orders WHERE amount > 1000);
-- 分组查询
SELECT user_id, COUNT(*) as order_count, SUM(amount) as total_amount
FROM orders
GROUP BY user_id
HAVING COUNT(*) > 5;
数据控制语言(DCL)
-- 创建用户
CREATE USER 'webuser'@'localhost' IDENTIFIED BY 'password';
-- 授权
GRANT SELECT, INSERT, UPDATE ON mydb.* TO 'webuser'@'localhost';
-- 撤销权限
REVOKE UPDATE ON mydb.* FROM 'webuser'@'localhost';
-- 删除用户
DROP USER 'webuser'@'localhost';
MySQL 数据类型
整数类型
| 类型 | 存储空间 | 最小值(有符号) | 最大值(有符号) |
|------|----------|------------------|------------------|
| TINYINT | 1 字节 | -128 | 127 |
| SMALLINT | 2 字节 | -32768 | 32767 |
| MEDIUMINT | 3 字节 | -8388608 | 8388607 |
| INT | 4 字节 | -2147483648 | 2147483647 |
| BIGINT | 8 字节 | -9223372036854775808 | 9223372036854775807 |
浮点数类型
FLOAT:单精度浮点数,4 字节
DOUBLE:双精度浮点数,8 字节
DECIMAL(M,D):定点数,M 表示总位数,D 表示小数位数
字符串类型
CHAR(N):固定长度字符串,最多 255 个字符
VARCHAR(N):可变长度字符串,最多 65535 个字符
TEXT:文本类型,最大长度为 65535 个字符
MEDIUMTEXT:中等长度文本,最大长度为 16777215 个字符
LONGTEXT:长文本,最大长度为 4294967295 个字符
日期和时间类型
DATE:日期,格式为 'YYYY-MM-DD'
TIME:时间,格式为 'HH:MM:SS'
DATETIME:日期和时间,格式为 'YYYY-MM-DD HH:MM:SS'
TIMESTAMP:时间戳,范围从 '1970-01-01 00:00:01' UTC 到 '2038-01-19 03:14:07' UTC
YEAR:年份,范围从 1901 到 2155
二进制类型
BINARY(N):固定长度二进制字符串
VARBINARY(N):可变长度二进制字符串
BLOB:二进制大对象,最大长度为 65535 字节
MEDIUMBLOB:中等长度二进制大对象,最大长度为 16777215 字节
LONGBLOB:长二进制大对象,最大长度为 4294967295 字节
MySQL 索引
索引是提高数据库查询性能的重要手段,MySQL 支持多种类型的索引。
索引类型
普通索引:最基本的索引类型,没有任何限制
唯一索引:索引列的值必须唯一,但允许有空值
主键索引:特殊的唯一索引,不允许有空值
组合索引:多个列组合在一起创建的索引
全文索引:用于全文搜索
空间索引:用于地理空间数据类型
创建索引
-- 创建表时指定索引
CREATE TABLE users (
id INT AUTO_INCREMENT,
username VARCHAR(50) NOT NULL,
email VARCHAR(100),
PRIMARY KEY (id),
UNIQUE INDEX idx_username (username),
INDEX idx_email (email)
);
-- 在已有表上创建索引
CREATE INDEX idx_created_at ON users (created_at);
CREATE UNIQUE INDEX idx_email ON users (email);
-- 创建组合索引
CREATE INDEX idx_name_email ON users (username, email);
-- 创建全文索引
CREATE FULLTEXT INDEX idx_content ON articles (content);
索引的使用原则
1. 选择合适的列建立索引:经常用于查询、排序、分组的列
2. 索引列的基数:基数越大(列中不同值的数量越多),索引的效果越好
3. 前缀索引:对于长字符串,可以只索引前几个字符
4. 覆盖索引:尽量使用能够覆盖查询的索引
5. 避免过多索引:索引会占用空间并影响写入性能
6. 组合索引的顺序:遵循最左前缀原则
MySQL 事务
事务是数据库操作的基本单位,具有 ACID 特性。
ACID 特性
原子性(Atomicity):事务是不可分割的工作单位,要么全部执行,要么全部不执行
一致性(Consistency):事务执行前后,数据库从一个一致性状态变到另一个一致性状态
隔离性(Isolation):多个事务并发执行时,一个事务的执行不应影响其他事务的执行
持久性(Durability):事务一旦提交,其结果就是永久性的
事务控制语句
-- 开始事务
START TRANSACTION;
-- 执行操作
INSERT INTO accounts (user_id, balance) VALUES (1, 1000);
UPDATE accounts SET balance = balance - 100 WHERE user_id = 1;
INSERT INTO transactions (user_id, amount, type) VALUES (1, 100, 'withdraw');
-- 提交事务
COMMIT;
-- 回滚事务
ROLLBACK;
-- 设置保存点
SAVEPOINT my_savepoint;
-- 回滚到保存点
ROLLBACK TO SAVEPOINT my_savepoint;
事务隔离级别
MySQL 支持四种事务隔离级别,用于解决并发事务可能出现的问题(脏读、不可重复读、幻读)。
| 隔离级别 | 脏读 | 不可重复读 | 幻读 | 性能影响 |
|----------|------|------------|------|----------|
| READ UNCOMMITTED | 可能 | 可能 | 可能 | 最小 |
| READ COMMITTED | 不可能 | 可能 | 可能 | 较小 |
| REPEATABLE READ(默认) | 不可能 | 不可能 | 可能 | 较大 |
| SERIALIZABLE | 不可能 | 不可能 | 不可能 | 最大 |
-- 查看当前隔离级别
SELECT @@transaction_isolation;
-- 设置隔离级别
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
MySQL 锁机制
锁是数据库并发控制的基本手段,MySQL 中有多种类型的锁。
锁的类型
共享锁(S 锁):允许多个事务同时读取同一资源,但不允许写入
排他锁(X 锁):只允许一个事务访问资源,阻止其他事务读取和写入
意向锁:表示事务想要在表中的某些行上加共享锁或排他锁
记录锁:锁定索引记录
间隙锁:锁定索引记录之间的间隙
临键锁:记录锁和间隙锁的组合,锁定索引记录及其前面的间隙
加锁语句
-- 共享锁
SELECT * FROM users WHERE id = 1 LOCK IN SHARE MODE;
-- 排他锁
SELECT * FROM users WHERE id = 1 FOR UPDATE;
-- 表级锁
LOCK TABLES users READ;
LOCK TABLES users WRITE;
UNLOCK TABLES;
MySQL 存储引擎
MySQL 的一个重要特性是支持多种存储引擎,不同的存储引擎具有不同的特性和适用场景。
常见存储引擎
InnoDB
InnoDB 是 MySQL 5.5 之后的默认存储引擎,具有以下特点:
支持事务,符合 ACID 特性
支持行级锁,提高并发性能
支持外键约束
支持崩溃恢复
使用聚集索引存储数据
适用场景:需要事务支持、高并发、外键约束的应用
MyISAM
MyISAM 是 MySQL 5.5 之前的默认存储引擎,具有以下特点:
不支持事务
支持表级锁
不支持外键
拥有较高的插入和查询速度
支持全文索引
适用场景:读密集型应用、不需要事务支持的应用
Memory
Memory 存储引擎将数据存储在内存中,具有以下特点:
数据存储在内存中,速度极快
重启后数据会丢失
支持哈希索引
适用场景:临时表、缓存、需要快速访问的小型数据集
Archive
Archive 存储引擎适用于存储和检索大量很少被访问的历史数据,具有以下特点:
只支持 INSERT 和 SELECT 操作
使用行级锁
高度压缩数据
适用场景:日志和数据归档
查看和设置存储引擎
-- 查看支持的存储引擎
SHOW ENGINES;
-- 查看表的存储引擎
SHOW TABLE STATUS WHERE Name = 'users';
-- 创建表时指定存储引擎
CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50)
) ENGINE = InnoDB;
-- 修改表的存储引擎
ALTER TABLE users ENGINE = MyISAM;
MySQL 优化策略
查询优化
1. 使用 EXPLAIN 分析查询:了解 MySQL 如何执行查询
EXPLAIN SELECT * FROM users WHERE username = 'admin';
2. 索引优化:
为经常用于查询条件的列创建索引
利用覆盖索引减少回表操作
避免在索引列上使用函数或表达式
3. SQL 语句优化:
只查询需要的列,避免
SELECT *
使用 LIMIT 限制结果集大小
使用连接(JOIN)代替子查询
使用 EXISTS 代替 IN
避免使用 OR 条件,可以使用 UNION 代替
4. 分页查询优化:
-- 优化前
SELECT * FROM users ORDER BY id LIMIT 10000, 10;
-- 优化后
SELECT * FROM users WHERE id > 10000 ORDER BY id LIMIT 10;
数据库设计优化
1. 合理的表设计:
遵循数据库范式,减少数据冗余
适当反范式化,提高查询性能
使用合适的数据类型
避免过多的列
2. 分区表:对大表进行分区,提高查询和管理效率
CREATE TABLE sales (
id INT,
sale_date DATE,
amount DECIMAL(10,2)
)
PARTITION BY RANGE (YEAR(sale_date)) (
PARTITION p0 VALUES LESS THAN (2020),
PARTITION p1 VALUES LESS THAN (2021),
PARTITION p2 VALUES LESS THAN (2022),
PARTITION p3 VALUES LESS THAN MAXVALUE
);
3. 垂直拆分:将大表按列拆分成多个表
4. 水平拆分:将大表按行拆分成多个表
服务器优化
1. 配置优化:
调整缓冲池大小(innodb_buffer_pool_size)
优化日志写入策略(innodb_flush_log_at_trx_commit)
调整连接数(max_connections)
优化查询缓存(query_cache_size)
2. 硬件优化:
使用 SSD 存储数据
增加内存
使用多核 CPU
优化网络配置
MySQL 备份与恢复
备份方法
1. 逻辑备份:
mysqldump:生成 SQL 语句的备份
mysqldump -u root -p --all-databases > backup.sql
mysqldump -u root -p --databases db1 db2 > backup.sql
mysqldump -u root -p db1 table1 table2 > backup.sql
mysqlpump:增强版的 mysqldump,支持并行备份
mysqlpump -u root -p --all-databases > backup.sql
2. 物理备份:
直接复制数据文件
使用 MySQL Enterprise Backup
使用 Percona XtraBackup
xtrabackup --backup --target-dir=/path/to/backup
3. 增量备份:
使用二进制日志(binlog)
使用 Percona XtraBackup 的增量备份功能
xtrabackup --backup --target-dir=/path/to/full-backup
xtrabackup --backup --target-dir=/path/to/inc1 --incremental-basedir=/path/to/full-backup
恢复方法
1. 逻辑备份恢复:
mysql -u root -p < backup.sql
2. 物理备份恢复:
停止 MySQL 服务
替换数据文件
启动 MySQL 服务
3. 使用二进制日志恢复:
mysqlbinlog binlog.000001 binlog.000002 | mysql -u root -p
4. 使用 Percona XtraBackup 恢复:
xtrabackup --prepare --target-dir=/path/to/backup
xtrabackup --copy-back --target-dir=/path/to/backup
MySQL 高可用方案
主从复制
主从复制是 MySQL 最基本的高可用方案,一个主服务器(Master)可以有多个从服务器(Slave)。
配置主服务器
# my.cnf
[mysqld]
server-id = 1
log-bin = mysql-bin
binlog-format = ROW
配置从服务器
# my.cnf
[mysqld]
server-id = 2
relay-log = relay-bin
设置复制
-- 在主服务器上创建复制用户
CREATE USER 'repl'@'%' IDENTIFIED BY 'password';
GRANT REPLICATION SLAVE ON . TO 'repl'@'%';
-- 获取主服务器状态
SHOW MASTER STATUS;
-- 在从服务器上配置复制
CHANGE MASTER TO
MASTER_HOST='master_host',
MASTER_USER='repl',
MASTER_PASSWORD='password',
MASTER_LOG_FILE='mysql-bin.000001',
MASTER_LOG_POS=123;
-- 启动复制
START SLAVE;
-- 查看复制状态
SHOW SLAVE STATUS\G
组复制(Group Replication)
组复制是 MySQL 5.7 引入的一种新的复制方案,提供了更高的一致性和可用性。
# my.cnf
[mysqld]
server-id = 1
gtid_mode = ON
enforce_gtid_consistency = ON
binlog_checksum = NONE
plugin_load = 'group_replication.so'
group_replication_group_name = 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee'
group_replication_start_on_boot = OFF
group_replication_local_address = 'server1:33061'
group_replication_group_seeds = 'server1:33061,server2:33061,server3:33061'
MySQL InnoDB Cluster
MySQL InnoDB Cluster 是 MySQL 8.0 提供的一个完整的高可用解决方案,包括:
MySQL Group Replication:提供数据复制
MySQL Router:提供自动路由
MySQL Shell:提供管理工具
# 使用 MySQL Shell 创建 InnoDB Cluster
mysqlsh
\connect root@server1
dba.createCluster('myCluster')
cluster = dba.getCluster()
cluster.addInstance('root@server2')
cluster.addInstance('root@server3')
MySQL 8.0 新特性
MySQL 8.0 引入了许多新特性,包括:
1. 窗口函数:
SELECT
name,
department,
salary,
RANK() OVER (PARTITION BY department ORDER BY salary DESC) as salary_rank
FROM employees;
2. 公共表表达式(CTE):
WITH cte AS (
SELECT user_id, COUNT(*) as order_count
FROM orders
GROUP BY user_id
)
SELECT u.username, c.order_count
FROM users u
JOIN cte c ON u.id = c.user_id
WHERE c.order_count > 10;
3. JSON 增强:
SELECT JSON_TABLE(
'{"employees": [{"name": "John", "age": 30}, {"name": "Jane", "age": 25}]}',
'$.employees[*]' COLUMNS(
name VARCHAR(50) PATH '$.name',
age INT PATH '$.age'
)
) as employee_data;
4. 原子 DDL:DDL 操作现在是原子的,要么完全成功,要么完全失败
5. 隐藏索引:可以隐藏索引而不删除它,用于测试索引的影响
ALTER TABLE users ALTER INDEX idx_email INVISIBLE;
ALTER TABLE users ALTER INDEX idx_email VISIBLE;
6. 降序索引:支持降序索引
CREATE INDEX idx_created_at_desc ON users (created_at DESC);
7. 资源组:可以为不同的查询分配不同的资源
CREATE RESOURCE GROUP rg_admin
TYPE = USER
VCPU = 0-3
THREAD_PRIORITY = 10;
8. 角色管理:简化权限管理
CREATE ROLE 'app_read', 'app_write';
GRANT SELECT ON app.* TO 'app_read';
GRANT INSERT, UPDATE, DELETE ON app.* TO 'app_write';
GRANT 'app_read', 'app_write' TO 'app_user'@'localhost';
SET DEFAULT ROLE 'app_read', 'app_write' TO 'app_user'@'localhost';
- 感谢你赐予我前进的力量