1. MySQL学习笔记:从零开始的数据库实战指南
作为后端开发中最常用的关系型数据库之一,MySQL几乎成了每个程序员必须掌握的技能。记得我第一次接触MySQL时,面对各种陌生的术语和命令完全摸不着头脑,直到真正在项目中用它处理了几十万条数据后,才逐渐理解那些看似枯燥的概念背后的实用价值。这份笔记记录了我从入门到实战的完整学习路径,特别适合已经了解SQL基础但想系统掌握MySQL核心特性的开发者。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. MySQL核心架构解析
2.1 存储引擎选型策略
InnoDB和MyISAM是MySQL最常用的两种存储引擎,它们的差异直接影响着系统性能:
| 特性 | InnoDB | MyISAM |
|---|---|---|
| 事务支持 | 支持ACID | 不支持 |
| 锁机制 | 行级锁 | 表级锁 |
| 外键 | 支持 | 不支持 |
| 崩溃恢复 | 有redo log保证 | 需手动修复 |
| 适用场景 | 高并发写/事务型应用 | 读多写少/报表系统 |
实际项目中我强烈建议默认使用InnoDB,除非有明确的只读需求。曾经有个报表系统因为历史原因用了MyISAM,结果某次服务器宕机导致索引文件损坏,花了整整一天时间修复数据。
2.2 索引优化实战心得
B+树索引是MySQL的默认索引结构,但如何用好它却有很多门道:
sql复制-- 创建复合索引的正确姿势
ALTER TABLE `user_order` ADD INDEX `idx_status_create_time` (`order_status`, `create_time`);
-- 常见错误:索引列顺序不当导致失效
SELECT * FROM products WHERE price > 100 AND category = 'electronics';
-- 如果索引是(price, category)就会有问题
几个血泪教训:
- 避免在WHERE条件中对索引列使用函数操作
- 范围查询后的索引列会失效(如上面price>100会导致category无法用索引)
- TEXT/BLOB类型建索引必须指定前缀长度
3. 事务与锁机制深度剖析
3.1 事务隔离级别的选择
MySQL默认使用REPEATABLE READ,但在不同场景下需要调整:
sql复制-- 查看当前隔离级别
SELECT @@transaction_isolation;
-- 修改为READ COMMITTED(适合大多数OLTP场景)
SET GLOBAL transaction_isolation = 'READ-COMMITTED';
曾经遇到过一个商品超卖问题:在高并发下单时,即使有库存检查还是会出现负库存。最终发现是REPEATABLE READ下"幻读"导致的问题,改用SELECT...FOR UPDATE加锁才解决。
3.2 死锁排查实战记录
sql复制-- 查看最近死锁日志
SHOW ENGINE INNODB STATUS\G
-- 典型死锁场景:事务1和事务2按不同顺序更新相同行
-- 事务1
UPDATE accounts SET balance = balance - 100 WHERE user_id = 1;
UPDATE accounts SET balance = balance + 100 WHERE user_id = 2;
-- 事务2(相反顺序)
UPDATE accounts SET balance = balance + 200 WHERE user_id = 2;
UPDATE accounts SET balance = balance - 200 WHERE user_id = 1;
解决方案:
- 统一应用层的更新顺序
- 减小事务范围
- 对热点数据使用乐观锁
4. 性能优化全链路实践
4.1 EXPLAIN执行计划详解
sql复制EXPLAIN SELECT u.name, o.order_no
FROM users u JOIN orders o ON u.id = o.user_id
WHERE u.vip_level > 3 AND o.status = 'paid';
关键指标解读:
- type列:从优到差 system > const > eq_ref > ref > range > index > ALL
- Extra列:Using filesort/Using temporary表示需要优化
- rows列:预估扫描行数越少越好
4.2 慢查询日志配置技巧
ini复制# my.cnf配置
slow_query_log = 1
slow_query_log_file = /var/log/mysql/mysql-slow.log
long_query_time = 1 # 超过1秒记录
log_queries_not_using_indexes = 1
分析工具推荐:
bash复制# 使用mysqldumpslow分析
mysqldumpslow -s t /var/log/mysql/mysql-slow.log
# 使用pt-query-digest(更强大)
pt-query-digest /var/log/mysql/mysql-slow.log
5. 高可用架构设计要点
5.1 主从复制配置实录
sql复制-- 主库配置
CREATE USER 'repl'@'%' IDENTIFIED BY 'password';
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';
-- 从库执行
CHANGE MASTER TO
MASTER_HOST='master_host',
MASTER_USER='repl',
MASTER_PASSWORD='password',
MASTER_LOG_FILE='mysql-bin.000001',
MASTER_LOG_POS=154;
START SLAVE;
监控命令:
sql复制SHOW SLAVE STATUS\G
-- 关注Slave_IO_Running和Slave_SQL_Running状态
-- Seconds_Behind_Master表示复制延迟
5.2 分库分表实战策略
常见分片方案对比:
| 方案 | 优点 | 缺点 |
|---|---|---|
| 范围分片 | 易于扩展 | 可能产生热点 |
| 哈希分片 | 数据分布均匀 | 扩容需要迁移数据 |
| 时间分片 | 符合业务时序 | 历史数据访问不便 |
使用ShardingSphere的配置示例:
yaml复制spring:
shardingsphere:
datasource:
names: ds0,ds1
sharding:
tables:
t_order:
actual-data-nodes: ds$->{0..1}.t_order_$->{0..15}
table-strategy:
inline:
sharding-column: order_id
algorithm-expression: t_order_$->{order_id % 16}
6. 备份恢复与数据安全
6.1 全量+增量备份方案
bash复制# 全量备份
mysqldump -uroot -p --single-transaction --master-data=2 --databases mydb > full_backup.sql
# 增量备份(基于binlog)
mysqlbinlog --start-position=154 --stop-position=298 /var/lib/mysql/mysql-bin.000002 > incr_backup.sql
# 恢复流程
mysql -uroot -p < full_backup.sql
mysql -uroot -p < incr_backup.sql
6.2 数据加密最佳实践
sql复制-- 透明数据加密(TDE)配置
INSTALL PLUGIN file_key_management SONAME 'file_key_management.so';
CREATE TABLESPACE `secure_ts` ADD DATAFILE 'secure_ts.ibd' ENCRYPTION='Y';
-- 列级加密示例
CREATE TABLE patient_records (
id INT PRIMARY KEY,
name VARBINARY(255),
ssn VARBINARY(255)
);
-- 应用层加解密
INSERT INTO patient_records VALUES (1, AES_ENCRYPT('张三', 'secret_key'), AES_ENCRYPT('123-45-6789', 'secret_key'));
SELECT AES_DECRYPT(name, 'secret_key') FROM patient_records WHERE id = 1;
7. 监控与故障排查体系
7.1 关键性能指标监控
sql复制-- 查看当前连接数
SHOW STATUS LIKE 'Threads_connected';
-- InnoDB缓冲池命中率
SELECT (1 - (SELECT variable_value FROM performance_schema.global_status WHERE variable_name = 'Innodb_buffer_pool_reads') /
(SELECT variable_value FROM performance_schema.global_status WHERE variable_name = 'Innodb_buffer_pool_read_requests')) * 100 AS hit_ratio;
-- 表空间使用情况
SELECT table_schema, table_name,
data_length/1024/1024 AS data_size_mb,
index_length/1024/1024 AS index_size_mb
FROM information_schema.tables
ORDER BY (data_length + index_length) DESC;
7.2 常见故障处理手册
连接数爆满:
sql复制-- 查看当前所有连接
SELECT * FROM information_schema.processlist;
-- 紧急增加最大连接数
SET GLOBAL max_connections = 500;
-- 杀死空闲连接
SELECT CONCAT('KILL ', id, ';') FROM information_schema.processlist
WHERE COMMAND = 'Sleep' AND TIME > 300 INTO OUTFILE '/tmp/kill.sql';
SOURCE /tmp/kill.sql;
主从复制中断:
sql复制-- 常见错误:1062主键冲突/1032记录不存在
-- 临时跳过错误(慎用)
STOP SLAVE;
SET GLOBAL sql_slave_skip_counter = 1;
START SLAVE;
-- 更好的做法:手动修复数据后重新同步
