面试篇:MySQL
基础概念
什么是MySQL?它有哪些特点?
MySQL是一个开源的关系型数据库管理系统(RDBMS),由瑞典MySQL AB公司开发,现属于Oracle旗下产品。主要特点包括:
- 开源免费(社区版)
- 支持多平台(Windows/Linux/macOS等)
- 使用标准SQL语言
- 支持多种存储引擎(如InnoDB、MyISAM等)
- 性能高、可靠性好
- 支持事务处理
- 提供丰富的API接口
MySQL的体系结构是怎样的?
MySQL采用分层架构,主要包含以下组件:
- 连接层:处理客户端连接、授权认证等
- 服务层:SQL接口、查询解析、优化、缓存等
- 存储引擎层:负责数据的存储和提取(插件式架构)
- 文件系统层:数据文件、日志文件的物理存储
存储引擎
InnoDB和MyISAM的区别是什么?
特性 | InnoDB | MyISAM |
---|---|---|
事务支持 | 支持 | 不支持 |
锁机制 | 行锁 | 表锁 |
外键支持 | 支持 | 不支持 |
崩溃恢复 | 支持 | 不支持 |
全文索引 | MySQL 5.6+支持 | 支持 |
存储结构 | 聚簇索引 | 非聚簇索引 |
缓存 | 缓冲池缓存数据和索引 | 只缓存索引 |
表空间 | 共享表空间/独立表空间 | 每个表存储为单独的文件 |
适用场景 | 高并发、事务处理 | 读多写少、不需要事务的场景 |
MySQL有哪些常见的存储引擎?
- InnoDB:默认引擎,支持事务、行锁、外键
- MyISAM:不支持事务,表锁,适合读多写少
- Memory:数据存储在内存中,速度快但易丢失
- Archive:高压缩比,适合存储归档数据
- CSV:以CSV格式存储数据
- NDB:集群存储引擎
索引
什么是索引?MySQL有哪些索引类型?
索引是帮助MySQL高效获取数据的数据结构,类似于书籍的目录。MySQL主要索引类型包括:
-
按数据结构分类:
• B+Tree索引(默认)• Hash索引(Memory引擎)
• Full-text全文索引
• R-Tree空间索引
-
按功能分类:
• 普通索引:最基本的索引• 唯一索引:列值必须唯一
• 主键索引:特殊的唯一索引,不允许NULL
• 组合索引:多列组合的索引
• 覆盖索引:查询的列都在索引中
B+树索引的原理是什么?
B+树是MySQL InnoDB引擎默认的索引结构,特点包括:
- 多路平衡查找树,保持数据有序
- 非叶子节点只存储键值,不存储数据
- 叶子节点存储所有数据,并通过指针连接形成链表
- 树的高度通常为3-4层,可支持千万级数据高效查询
- 适合范围查询和排序操作
什么情况下索引会失效?
- 违反最左前缀原则(组合索引)
- 在索引列上使用函数或计算
- 使用不等于(!=或<>)查询
- 使用LIKE以通配符开头('%abc')
- 类型转换(隐式类型转换)
- 使用OR条件且部分条件无索引
- 索引列使用IS NULL/IS NOT NULL
事务
什么是事务?事务的四大特性是什么?
事务是数据库操作的最小工作单元,具有ACID特性:
- 原子性(Atomicity):事务是不可分割的整体,要么全部成功,要么全部失败回滚
- 一致性(Consistency):事务执行前后数据库状态保持一致
- 隔离性(Isolation):并发事务之间互不干扰
- 持久性(Durability):事务提交后对数据的修改是永久性的
MySQL的事务隔离级别有哪些?
- 读未提交(Read Uncommitted):最低级别,可能读到未提交的数据(脏读)
- 读已提交(Read Committed):只能读到已提交的数据(解决脏读)
- 可重复读(Repeatable Read):MySQL默认级别,保证同一事务多次读取结果一致(解决不可重复读)
- 串行化(Serializable):最高隔离级别,完全串行执行(解决幻读)
什么是脏读、不可重复读和幻读?
- 脏读:读取到其他事务未提交的数据
- 不可重复读:同一事务内多次读取同一数据,结果不同(被其他事务修改)
- 幻读:同一事务内多次查询,返回的记录数不同(其他事务新增/删除了数据)
锁机制
MySQL有哪些锁类型?
-
按锁粒度分:
• 表锁:锁定整张表(MyISAM默认)• 行锁:锁定单行记录(InnoDB默认)
• 页锁:锁定一页数据(BDB引擎)
-
按锁性质分:
• 共享锁(S锁):读锁,允许多个事务同时读取• 排他锁(X锁):写锁,独占资源
• 意向锁:表级锁,表明事务准备对表中的行加锁
-
特殊锁:
• 记录锁:锁定索引中的一条记录• 间隙锁:锁定索引记录间的间隙
• 临键锁:记录锁+间隙锁的组合
什么是死锁?如何避免死锁?
死锁是指两个或多个事务互相持有对方需要的锁,导致都无法继续执行的情况。避免死锁的方法:
- 按固定顺序访问表和行
- 减少事务持有锁的时间
- 使用较低的隔离级别
- 合理设计索引,减少锁的覆盖范围
- 设置锁等待超时参数(innodb_lock_wait_timeout)
- 启用死锁检测(innodb_deadlock_detect)
性能优化
如何优化SQL查询性能?
-
合理设计索引:
• 为常用查询条件创建索引• 遵循最左前缀原则
• 避免过度索引
-
SQL语句优化:
• 避免SELECT *• 避免使用OR条件
• 合理使用JOIN
• 避免在WHERE子句中使用函数
-
数据库设计优化:
• 适当的数据类型• 合理的表结构设计
• 必要时进行分表分库
-
配置优化:
• 调整缓冲池大小(innodb_buffer_pool_size)• 优化查询缓存
• 合理设置连接数
EXPLAIN命令有什么用?
EXPLAIN用于分析SQL语句的执行计划,主要关注以下列:
- type:访问类型(从好到差:system > const > eq_ref > ref > range > index > ALL)
- key:实际使用的索引
- rows:预估需要检查的行数
- Extra:额外信息(如Using filesort、Using temporary等)
什么是慢查询?如何定位慢查询?
慢查询是指执行时间超过指定阈值的SQL查询。定位方法:
- 开启慢查询日志(slow_query_log)
- 设置慢查询阈值(long_query_time)
- 使用mysqldumpslow工具分析慢查询日志
- 使用Performance Schema监控查询性能
- 使用SHOW PROCESSLIST查看当前执行的查询
高可用与备份
MySQL有哪些备份方式?
-
逻辑备份:
• mysqldump:导出SQL语句• mysqlpump:并行备份工具
• mydumper:第三方并行备份工具
-
物理备份:
• 直接复制数据文件• Percona XtraBackup:热备份工具
-
备份策略:
• 全量备份• 增量备份
• 差异备份
什么是主从复制?工作原理是什么?
主从复制是将主数据库的数据同步到一个或多个从数据库的过程。工作原理:
- 主库记录所有数据更改到二进制日志(binlog)
- 从库I/O线程连接主库获取binlog
- 从库SQL线程重放binlog中的事件
- 通过配置可以实现读写分离、数据备份等功能
什么是读写分离?如何实现?
读写分离是将读操作和写操作分发到不同的数据库服务器。实现方式:
-
基于主从复制架构
-
使用中间件:
• MySQL Router• ProxySQL
• MyCat
• ShardingSphere
-
应用层实现:在代码中区分读写操作
分库分表
什么情况下需要考虑分库分表?
- 单表数据量过大(一般超过500万行)
- 数据库服务器性能达到瓶颈
- 业务有明显的分区特性(如按地区、时间)
- 需要更高的并发处理能力
分库分表有哪些策略?
-
水平分表:按行拆分,表结构相同
• 范围分片(如按时间、ID范围)• 哈希分片(如按用户ID哈希)
-
垂直分表:按列拆分,将不常用字段分离
-
分库:将表分布到不同数据库实例
• 业务分库(不同业务使用不同库)• 水平分库(相同表结构分布到不同库)
分库分表会带来哪些问题?如何解决?
常见问题及解决方案:
-
跨库JOIN问题:
• 应用层多次查询合并• 冗余字段
• 使用全局表
-
分布式事务问题:
• 使用XA协议• 最终一致性方案
• TCC模式
-
全局ID生成:
• UUID• 雪花算法
• 数据库自增序列
• Redis生成
-
跨库排序分页:
• 各库查询后内存合并• 使用ES等搜索引擎
新特性
MySQL 8.0有哪些重要新特性?
- 数据字典:元数据存储在事务性数据字典中
- 窗口函数:支持OVER子句
- 公用表表达式(CTE):WITH语法
- 原子DDL:DDL操作具有原子性
- 隐藏索引:可以"隐藏"索引进行测试
- 降序索引:支持真正的降序索引
- JSON增强:更多JSON函数和优化
- 角色管理:简化权限管理
- 性能提升:直方图统计信息,不可见索引等
MySQL的JSON类型有什么特点?
-
原生支持JSON数据类型(MySQL 5.7+)
-
提供丰富的JSON函数:
• JSON_EXTRACT/->:提取值• JSON_SET:设置值
• JSON_REMOVE:删除值
• JSON_SEARCH:查找值
-
支持JSON路径表达式
-
自动验证JSON格式
-
优化存储格式,提高查询效率
-
支持JSON列建立虚拟列和索引