MySQL 全详解:从入门到精通的实战指南

目录

MySQL简介

一、MySQL存储引擎

[二、MySAM VS InnoDB](#二、MySAM VS InnoDB)

[2.1 背景](#2.1 背景)

[2.2 核心特性对比](#2.2 核心特性对比)

[2.3 适用场景](#2.3 适用场景)

[2.3.1 MyISAM 适用场景](#2.3.1 MyISAM 适用场景)

[2.3.2 InnoDB 适用场景](#2.3.2 InnoDB 适用场景)

三、索引(InnoDB)

[3.1 聚簇索引&辅助索引](#3.1 聚簇索引&辅助索引)

[3.1.1 工作流程](#3.1.1 工作流程)

[3.1.2 索引失效](#3.1.2 索引失效)

①聚簇索引失效

②辅助索引失效

🔍如何判定索引失效?

[3.2 联合索引](#3.2 联合索引)

[3.2.1 底层原理(MySQL--InnoDB为例)](#3.2.1 底层原理(MySQL--InnoDB为例))

[1)核心原理:按顺序构建 "有序结构"](#1)核心原理:按顺序构建 “有序结构”)

[2)生效规则:"前缀匹配" 是关键](#2)生效规则:“前缀匹配” 是关键)

3.2.2

1)最左前缀原则

2)联合索引如何B+树中存储

四、事务

事务加锁机制

五、大表优化

①垂直分表

②水平分表

六、日志文件

七、MVCC(多版本并发控制)

八、SQL优化(思考题)


MySQL简介

最原始的计算器只是卡片输入,卡片输出,计算机只有计算能力,根本就没有数据库;后来随着发展,人人都能支付起一台电脑,想在计算机上衍生出来一些娱乐,那么此时存储就成了计算机的一大难题。
像记事本,world等原始存储数据的软件,慢,乱且不方便不安全;于是一些小型的数据库软件应运而生。
数据库研究出来就是为了管理数据而生,具备增删改查能力,并且能够保障断电后仍存储(也就是数据本质存储在硬盘中)

但是在国内,PostgreSQL的应用流行度并比不过MySQL(尤其是阿里)

一、MySQL存储引擎

①查看存储引擎(可以在软件中查看,或是在终端输入mysql后查看)--输入以下命令:
show engines;

②查看系统默认存储引擎
show variables like '%storage_engine%';

💡MyISAM是MySQL的默认数据库引擎(5.5版之前);不过,5.5版本之后,MySQL引入了InnoDB(事务性数据库引擎),MySQL 5.5版本后默认的存储引擎为InnoDB。
可以看见上面系统默认的就是InnoDB。

二、MySAM VS InnoDB

2.1 背景

  • MyISAM :MySQL 早期的默认存储引擎(MySQL 5.5 版本前),设计侧重于读取性能优化,但不支持事务和复杂并发控制。
  • InnoDB :目前 MySQL 的默认存储引擎(MySQL 5.5 及以后),由 Oracle 开发,以事务支持、崩溃恢复和高并发写性能为核心设计目标。

2.2 核心特性对比

特性 MyISAM InnoDB
事务支持 不支持(无 ACID 特性) 支持(完全符合 ACID:原子性、一致性、隔离性、持久性)
锁机制 仅支持表级锁(读锁 / 写锁) 支持行级锁(默认)+ 表级锁(特殊场景,如全表扫描)
外键支持 不支持 支持(可通过FOREIGN KEY定义关联)
存储结构 每个表对应 3 个文件: - .frm:表结构定义 - .MYD:数据文件(MyData) - .MYI:索引文件(MyIndex) 每个表默认对应 2 个文件(独立表空间模式): - .frm:表结构定义 - .ibd:数据 + 索引文件(InnoDB Data)
索引类型 非聚簇索引(索引与数据分离,索引指向数据物理地址) 聚簇索引(主键索引与数据存储在一起,二级索引指向主键)
崩溃恢复 不支持崩溃后自动恢复(可能因断电等导致数据文件损坏,需手动执行myisamchk修复) 支持崩溃自动恢复(依赖redo logundo log:崩溃后通过日志重放恢复数据一致性)
并发性能 写操作(插入 / 更新 / 删除)会加表级写锁,阻塞所有读 / 写请求(读操作加表级读锁,可并发读) 行级锁支持 "写不阻塞读、读不阻塞写"(仅冲突行阻塞),高并发写场景下性能更优
自动增长列(AUTO_INCREMENT) 需通过表级锁保证自增唯一性(高并发插入时可能卡顿) 通过 "自增锁优化"(innodb_autoinc_lock_mode)支持无锁自增(默认模式下,批量插入也可高效生成自增 ID)
全文索引 原生支持全文索引(早期唯一支持该功能的引擎) MySQL 5.6 及以后支持全文索引(功能与 MyISAM 类似,但结合事务特性更稳定)
空间索引 支持(如地理信息数据索引) 支持(且结合事务和行锁,更适合地理数据的并发操作)

2.3 适用场景

2.3.1 MyISAM 适用场景

  • 读多写少的场景(如新闻网站、博客的文章表,用户访问以读为主,更新频率低);
  • 无需事务和数据一致性的场景(如日志表、临时统计报表);
  • 对存储占用敏感的场景(如历史归档数据,可通过压缩表节省空间)。

2.3.2 InnoDB 适用场景

  • 需要事务支持的场景(如电商订单、支付系统,需保证 "下单 - 扣库存 - 支付" 的原子性);
  • 高并发写操作的场景(如用户信息表、商品库存表,频繁更新且需并发支持);
  • 对数据可靠性要求高的场景(如金融数据、用户核心数据,需崩溃自动恢复);
  • 需要外键约束的场景(如订单表与用户表的关联,通过外键保证数据完整性)。

三、索引(InnoDB)


**引入索引的主要目的:**加快查询速度。
MySQL索引主要使用的两种数据结构:BTree&&Hash

💡MySQL索引 主要使用两种数据结构,就是 BTree和Hash ,但是现在的MySQL使用InnoDB的引擎,而 InnoDB不支持Hash

  • InnoDB 表 → 只有 B+Tree(+AHI)
  • MySQL 整体 → 仍支持 HASH,但仅限 MEMORY/NDB 等引擎

3.1 聚簇索引&辅助索引

💡"聚簇索引"和"辅助索引"只是 InnoDB 中对主键索引和非主键索引的物理实现方式 (也就是说InnoDB中的非聚簇索引就是指辅助索引)

  • 聚簇索引:数据是存放在叶子节点上的。
  • 辅助索引:叶子节点上是不存放真实数据的,而是存放聚簇索引的索引值。

3.1.1 工作流程

  1. **聚簇索引(主键)查数据:**主键值 → 直接在聚簇索引 B+ 树找到叶子页 → 叶子页里就是完整行 → 取出返回。
  2. 辅助索引(二级索引)查数据: 索引键值 → 在辅助索引 B+ 树找到叶子页 → 叶子页只存主键值 → 拿主键值再回聚簇索引查一次 → 拿到完整行返回(若查询列全在辅助索引里,则省掉回表)。

🔍什么是回表?
在辅助索引中,拿到主键值去聚簇索引,这种二次回树的操作叫做"回表"。
🔍为什么能省掉回表呢?
这就要知道什么叫" 查询列全在辅助索引中",这边可以举一个例子:
比如把 (name, age) 设成联合索引,这两列就是键列,会被完整地 写进该索引的所有叶子节点 ;再加上 InnoDB 的"潜规则"------每一张辅助索引都 必须带主键 id ,于是 **叶子节点里最终有 (name, age, id)**三份数据。
此刻,执行"SELECT name, age FROM t WHERE name='A'; "语句时------ 不回表。

3.1.2 索引失效

简单来说就是:优化器经过成本估算后, 放弃使用索引 ,改为全表扫描或大范围扫描。
聚簇索引和辅助索引都会失效,只是触发的条件不一样

①聚簇索引失效

基本不会 ,因为它就是 主键索引,数据按主键顺序物理存放。
唯一可能"看起来失效"的场景:
• 写了 WHERE 非主键列 = ? ------ 本来就没用到聚簇索引,自然谈不上失效;
• 写了 WHERE 主键 = 非最左前缀(如 WHERE id+1 = 7)------ 表达式让主键索引无法直接定位,于是退化为全表。

②辅助索引失效

相较于聚簇索引,辅助索引失效的场景就很多了。

  1. 函数/运算 :WHERE DATE(create_time) = '2023-05-01' 或 age+1=20。
  2. 前模糊 :LIKE '%abc'。
  3. 最左前缀中断 :联合索引 (a,b,c) 却只写 WHERE b=1 AND c=1。
  4. OR 条件 :WHERE a=1 OR b=2(两列分别走不同索引或无法合并)。
  5. 隐式类型转换 :WHERE code = 123(code 是 varchar)。
  6. NULL 判断 :WHERE col IS NULL(普通索引对 NULL 支持有限)。
  7. 范围之后:(a,b,c) 中出现 a>10 AND b=5,b 用不上。
  8. 数据倾斜/选择性差:优化器认为扫表更快。
  9. 强制全表 :使用 FORCE INDEX 但成本高被忽略,或直接 IGNORE INDEX。
🔍如何判定索引失效?

explain关键字的使用详解:
SQL 调优第一步:EXPLAIN 关键字全解析_pgsql explain关键字-CSDN博客

3.2 联合索引

在同一个 B+Tree 中,把多列的值按" 指定的先后顺序"组织成一个复合键(composite key),这棵 B+Tree 就是联合索引(composite / compound / multi-column index)。

3.2.1 底层原理(MySQL--InnoDB为例)

1)核心原理:按顺序构建 "有序结构"

联合索引的底层通常以 B + 树 为数据结构(和单字段索引一致),但排序规则是 按索引定义的字段顺序逐级排序
例如,对表中 (A, B, C) 三个字段创建联合索引,B + 树的排序逻辑是:

  1. 先按字段 A 排序;
  2. 当 A 的值相同时,再按字段 B 排序;
  1. 当 A 和 B 的值都相同时,最后按字段 C 排序。
    这种排序方式使得索引树中,相同 A 值的记录会聚集在一起,且内部按 B 有序;相同 A+B 的记录又按 C 有序,类似 "字典先按首字母、再按第二个字母排序" 的逻辑。
2)生效规则:"前缀匹配" 是关键

联合索引的查询生效依赖 "前缀匹配原则":只有当查询条件中包含索引的 "前缀字段" 时,索引才可能被使用,且从第一个不匹配的字段开始,后续字段无法利用索引排序。
仍以 (A, B, C) 为例:

  • 有效场景
    • where A = ?(匹配前缀 A,可利用索引);
    • where A = ? and B = ?(匹配前缀 A+B,可利用索引);
    • where A = ? and B = ? and C = ?(匹配全部前缀,完全利用索引)。
  • 部分有效场景
    • where A = ? and C = ?:仅 A 能利用索引(C 不是前缀,无法通过索引定位 C,需扫描 A 相同的记录后过滤 C)。
  • 无效场景
    • where B = ? 或 where B = ? and C = ?(缺少前缀 A,无法利用索引,会全表扫描);
    • where A > ? and B = ?(A 是范围查询,后续 B 无法利用索引排序,仅 A 有效)。

💡【注】当索引为(a,b,c)时,下面的这俩个匹配都是有效的:

  • where a=xx and b>443 and c=32;
  • where c=32 and b =-123 and a =123;
    当查询条件中的所有判定都是 等值条件( = 时, 数据库通常会自动优化条件顺序,使其匹配联合索引的字段顺序 ,因此从结果上看,确实 "不严格要求查询条件的书写顺序"。但这并不意味着联合索引本身的顺序不重要,而是数据库通过 查询重写(Query Rewrite) 技术帮你调整了条件顺序。

3.2.2

1)最左前缀原则

简单而言就是:
从联合索引的左边开始, 连续匹配 到哪一列,索引就用到了哪一列;中间断掉的那一列之后的列就都用不上索引了,但 前面已经匹配的部分仍然有效

2)联合索引如何B+树中存储
  1. 存储规则 :按索引定义的列顺序(如col1→col2→col3)排序,先按首列排,首列相同则按次列排,以此类推;B + 树节点存储完整列组合及对应数据定位信息(如主键)。

  2. 查询特性:遵循 "最左前缀匹配",必须从首列开始查询,跳过中间列会导致后续列无法用索引;若查询列全在索引中,可直接从索引获取(索引覆盖),避免回表。

  3. 设计关键 :高频过滤、区分度高的列放前面;避免冗余(如(col1,col2)已包含col1单列索引功能);注意范围查询会使后续列索引失效。

四、事务

事务加锁机制

乐观锁+悲观锁+页锁(简单了解)
MySQL锁、加锁机制(超详细)------ 锁分类、全局锁、共享锁、排他锁;表锁、元数据锁、意向锁;行锁、间隙锁、临键锁;乐观锁、悲观锁-腾讯云开发者社区-腾讯云

五、大表优化

①垂直分表

垂直分表某种意义上来说没什么意义,所以这里不做过多赘述。

②水平分表

水平分库分表在高并发项目场景中比较常见,所以后面会有文章单独详解,这里先不做过多讲解。

六、日志文件

🔍MySAM没有事务,但是InnoDB有事务,所以在binlog,undolog,redolog中,它是缺少了哪一个?

|--------------|--------|------------|
| 日志类型 | MyISAM | InnoDB |
| undo log | ❌ 不支持 | ✅ 支持(事务回滚) |
| redo log | ❌ 不支持 | ✅ 支持(崩溃恢复) |
| binlog | ✅ 支持 | ✅ 支持 |

七、MVCC(多版本并发控制)

这个比较重要,后面会有文章单独讲解。

八、SQL优化(思考题)

🔍1.有没有排查过慢sql的问题?
2.如何定位慢SQL(也就是执行时间超过1s的sql)?

相关推荐
0xDevNull16 分钟前
MySQL数据冷热分离详解
后端·mysql
科技小花32 分钟前
数据治理平台架构演进观察:AI原生设计如何重构企业数据管理范式
数据库·重构·架构·数据治理·ai-native·ai原生
一江寒逸33 分钟前
零基础从入门到精通MySQL(中篇):进阶篇——吃透多表查询、事务核心与高级特性,搞定复杂业务SQL
数据库·sql·mysql
D4c-lovetrain35 分钟前
linux个人心得22 (mysql)
数据库·mysql
阿里小阿希1 小时前
CentOS7 PostgreSQL 9.2 升级到 15 完整教程
数据库·postgresql
荒川之神1 小时前
Oracle 数据仓库雪花模型设计(完整实战方案)
数据库·数据仓库·oracle
做个文艺程序员1 小时前
MySQL安全加固十大硬核操作
数据库·mysql·安全
不吃香菜学java2 小时前
Redis简单应用
数据库·spring boot·tomcat·maven
一个天蝎座 白勺 程序猿2 小时前
Apache IoTDB(15):IoTDB查询写回(INTO子句)深度解析——从语法到实战的ETL全链路指南
数据库·apache·etl·iotdb
不知名的老吴2 小时前
Redis的延迟瓶颈:TCP栈开销无法避免
数据库·redis·缓存