Skip to content

MySQL面试题

1. MySQL的基本概念

问题:什么是MySQL?

答案

  • MySQL:开源的关系型数据库管理系统。
  • 特点
    • 开源免费
    • 性能优异
    • 跨平台
    • 支持多种存储引擎
    • 支持事务
    • 支持复制和集群

2. MySQL的存储引擎

问题:MySQL有哪些存储引擎?有什么区别?

答案

  • InnoDB
    • 支持事务
    • 支持外键
    • 支持行级锁
    • 支持崩溃恢复
    • 适合OLTP应用
  • MyISAM
    • 不支持事务
    • 不支持外键
    • 支持表级锁
    • 读取速度快
    • 适合OLAP应用
  • Memory
    • 数据存储在内存中
    • 访问速度快
    • 数据不持久化
    • 适合临时表
  • Archive
    • 压缩存储
    • 只支持插入和查询
    • 适合归档数据

3. InnoDB和MyISAM的区别

问题:InnoDB和MyISAM有什么区别?

答案

  • 事务:InnoDB支持事务,MyISAM不支持。
  • 外键:InnoDB支持外键,MyISAM不支持。
  • :InnoDB支持行级锁,MyISAM只支持表级锁。
  • 崩溃恢复:InnoDB支持崩溃恢复,MyISAM不支持。
  • 索引:InnoDB使用聚簇索引,MyISAM使用非聚簇索引。
  • 适用场景:InnoDB适合OLTP,MyISAM适合OLAP。

4. MySQL的索引

问题:MySQL有哪些索引类型?

答案

  • 主键索引:唯一标识表中的每一行。
  • 唯一索引:确保列中的值唯一。
  • 普通索引:提高查询速度。
  • 全文索引:用于全文搜索。
  • 组合索引:多个列组成的索引。
  • 空间索引:用于空间数据。

5. 聚簇索引和非聚簇索引

问题:聚簇索引和非聚簇索引有什么区别?

答案

  • 聚簇索引
    • 索引和数据存储在一起。
    • 一个表只能有一个聚簇索引。
    • 查询速度快。
    • 插入、更新、删除速度慢。
  • 非聚簇索引
    • 索引和数据分开存储。
    • 一个表可以有多个非聚簇索引。
    • 查询速度慢。
    • 插入、更新、删除速度快。

6. 索引的优缺点

问题:索引有什么优缺点?

答案

  • 优点
    • 提高查询速度。
    • 减少IO操作。
    • 提高排序和分组效率。
  • 缺点
    • 占用存储空间。
    • 降低插入、更新、删除速度。
    • 需要维护索引。

7. 索引的使用原则

问题:使用索引的原则有哪些?

答案

  • 在经常查询的列上创建索引。
  • 在经常作为WHERE条件的列上创建索引。
  • 在经常作为JOIN条件的列上创建索引。
  • 在经常作为ORDER BY的列上创建索引。
  • 在经常作为GROUP BY的列上创建索引。
  • 避免在频繁更新的列上创建索引。
  • 避免在区分度低的列上创建索引。
  • 避免创建过多的索引。

8. 索引失效的情况

问题:什么情况下索引会失效?

答案

  • 使用函数或表达式。
  • 使用LIKE '%xxx'。
  • 使用OR连接条件。
  • 使用NOT、!=、<>。
  • 类型不匹配。
  • 隐式类型转换。
  • 使用子查询。
  • 使用全表扫描更优时。

9. MySQL的事务

问题:MySQL的事务特性是什么?

答案

  • 原子性(Atomicity):事务是不可分割的工作单位,要么全部成功,要么全部失败。
  • 一致性(Consistency):事务执行前后,数据库从一个一致性状态变换到另一个一致性状态。
  • 隔离性(Isolation):事务的执行不受其他事务的干扰。
  • 持久性(Durability):事务一旦提交,对数据库的修改是永久的。

10. MySQL的事务隔离级别

问题:MySQL有哪些事务隔离级别?

答案

  • READ UNCOMMITTED:读取未提交的数据,可能导致脏读、不可重复读、幻读。
  • READ COMMITTED:读取已提交的数据,可能导致不可重复读、幻读。
  • REPEATABLE READ:可重复读,可能导致幻读。
  • SERIALIZABLE:串行化,最严格的隔离级别,避免所有并发问题。

11. MySQL的锁机制

问题:MySQL有哪些锁?

答案

  • 全局锁:锁定整个数据库实例。
  • 表级锁:锁定整个表。
  • 行级锁:锁定一行记录。
  • 共享锁(S锁):允许读,不允许写。
  • 排他锁(X锁):不允许读和写。
  • 意向锁:表级锁,用于协调行级锁和表级锁。
  • 间隙锁:锁定索引记录之间的间隙。
  • 临键锁:锁定索引记录和间隙。

12. MySQL的MVCC

问题:什么是MVCC?

答案

  • MVCC(Multi-Version Concurrency Control):多版本并发控制。
  • 作用
    • 提高并发性能。
    • 避免读写冲突。
    • 实现事务隔离级别。
  • 实现方式
    • 使用Undo Log保存历史版本。
    • 使用Read View判断可见性。

13. MySQL的慢查询

问题:如何分析慢查询?

答案

sql
-- 开启慢查询
SET GLOBAL slow_query_log = ON;
SET GLOBAL long_query_time = 1;
SET GLOBAL slow_query_log_file = '/var/log/mysql/slow.log';

-- 使用EXPLAIN分析查询
EXPLAIN SELECT * FROM users WHERE name = 'John';

-- 使用EXPLAIN ANALYZE分析查询
EXPLAIN ANALYZE SELECT * FROM users WHERE name = 'John';

14. MySQL的优化

问题:如何优化MySQL?

答案

  • SQL优化
    • 使用索引。
    • 避免SELECT *。
    • 使用EXPLAIN分析查询。
    • 避免子查询。
    • 使用JOIN代替子查询。
    • 使用LIMIT限制返回行数。
    • 避免使用OR。
    • 使用EXISTS代替IN。
  • 表设计优化
    • 选择合适的数据类型。
    • 规范化设计。
    • 适当反范式化。
    • 分区表。
    • 分表分库。
  • 配置优化
    • 调整缓冲池大小。
    • 调整连接数。
    • 调整日志大小。
    • 调整缓存大小。

15. MySQL的主从复制

问题:MySQL的主从复制原理是什么?

答案

  1. 主库:将数据变更记录到二进制日志。
  2. 从库:连接主库,请求二进制日志。
  3. 主库:发送二进制日志给从库。
  4. 从库:将二进制日志写入中继日志。
  5. 从库:重放中继日志,应用数据变更。

16. MySQL的读写分离

问题:如何实现MySQL的读写分离?

答案

  • 应用层:在应用中实现读写分离。
  • 中间件:使用中间件实现读写分离。
  • 代理:使用代理实现读写分离。

示例

java
// 使用Sharding-JDBC实现读写分离
spring:
  shardingsphere:
    datasource:
      names: master,slave
      master:
        type: com.zaxxer.hikari.HikariDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        jdbc-url: jdbc:mysql://master:3306/mydb
      slave:
        type: com.zaxxer.hikari.HikariDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        jdbc-url: jdbc:mysql://slave:3306/mydb
    rules:
      readwrite-splitting:
        data-sources:
          mydb:
            static-strategy:
              write-data-source-name: master
              read-data-source-names: slave

17. MySQL的分库分表

问题:如何实现MySQL的分库分表?

答案

  • 垂直分库:按业务分库。
  • 垂直分表:按字段分表。
  • 水平分库:按数据量分库。
  • 水平分表:按数据量分表。

示例

java
// 使用Sharding-JDBC实现分库分表
spring:
  shardingsphere:
    datasource:
      names: db0,db1
      db0:
        type: com.zaxxer.hikari.HikariDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        jdbc-url: jdbc:mysql://db0:3306/mydb
      db1:
        type: com.zaxxer.hikari.HikariDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        jdbc-url: jdbc:mysql://db1:3306/mydb
    rules:
      sharding:
        tables:
          user:
            actual-data-nodes: db$->{0..1}.user_$->{0..1}
            database-strategy:
              standard:
                sharding-column: id
                sharding-algorithm-name: database-inline
            table-strategy:
              standard:
                sharding-column: id
                sharding-algorithm-name: table-inline
        sharding-algorithms:
          database-inline:
            type: INLINE
            props:
              algorithm-expression: db$->{id % 2}
          table-inline:
            type: INLINE
            props:
              algorithm-expression: user_$->{id % 2}

18. MySQL的备份和恢复

问题:如何备份和恢复MySQL?

答案

bash
# 使用mysqldump备份
mysqldump -u root -p mydb > backup.sql

# 使用mysqldump恢复
mysql -u root -p mydb < backup.sql

# 使用mysqlhotcopy备份
mysqlhotcopy -u root -p mydb /backup

# 使用XtraBackup备份
xtrabackup --backup --target-dir=/backup

19. MySQL的集群

问题:MySQL有哪些集群方案?

答案

  • 主从复制:一主多从,读写分离。
  • 双主复制:双主多从,高可用。
  • Galera Cluster:多主集群,同步复制。
  • MGR(MySQL Group Replication):多主集群,自动故障转移。
  • MySQL Cluster:分布式集群,内存存储。

20. MySQL的性能监控

问题:如何监控MySQL的性能?

答案

sql
-- 查看连接数
SHOW STATUS LIKE 'Threads_connected';

-- 查看慢查询
SHOW STATUS LIKE 'Slow_queries';

-- 查看缓冲池大小
SHOW VARIABLES LIKE 'innodb_buffer_pool_size';

-- 查看缓冲池命中率
SHOW STATUS LIKE 'Innodb_buffer_pool_read%';

-- 查看锁等待
SHOW ENGINE INNODB STATUS;

-- 使用Performance Schema
SELECT * FROM performance_schema.events_statements_summary_by_digest;

21. MySQL的数据类型

问题:MySQL有哪些数据类型?

答案

  • 数值类型:INT、BIGINT、FLOAT、DOUBLE、DECIMAL等。
  • 字符串类型:CHAR、VARCHAR、TEXT等。
  • 日期时间类型:DATE、TIME、DATETIME、TIMESTAMP等。
  • 二进制类型:BINARY、VARBINARY、BLOB等。
  • 布尔类型:BOOLEAN、BIT等。

22. MySQL的字符集

问题:MySQL有哪些字符集?

答案

  • utf8:UTF-8编码,最多3个字节。
  • utf8mb4:UTF-8编码,最多4个字节,支持emoji。
  • latin1:Latin-1编码。
  • gbk:GBK编码。
  • gb2312:GB2312编码。

23. MySQL的存储过程

问题:如何创建存储过程?

答案

sql
DELIMITER //
CREATE PROCEDURE get_users_by_department(IN dept_name VARCHAR(50))
BEGIN
    SELECT * FROM users WHERE department = dept_name;
END //
DELIMITER ;

-- 调用存储过程
CALL get_users_by_department('IT');

-- 删除存储过程
DROP PROCEDURE get_users_by_department;

24. MySQL的触发器

问题:如何创建触发器?

答案

sql
-- 创建触发器
DELIMITER //
CREATE TRIGGER before_user_insert
BEFORE INSERT ON users
FOR EACH ROW
BEGIN
    SET NEW.create_time = NOW();
END //
DELIMITER ;

-- 删除触发器
DROP TRIGGER before_user_insert;

25. MySQL的最佳实践

问题:使用MySQL的最佳实践有哪些?

答案

  • 选择合适的存储引擎。
  • 选择合适的数据类型。
  • 合理使用索引。
  • 使用事务保证数据一致性。
  • 使用主从复制提高可用性。
  • 使用读写分离提高性能。
  • 使用分库分表提高扩展性。
  • 定期备份数据。
  • 监控数据库性能。
  • 优化SQL语句。