Java面试八股文(2023最新)--MySQL面试题

目录

1. DDL,DML,DCL的区别?

2. ACID是什么?事务是什么?

3. InnoDB和MyISAM的区别

4. 索引有哪些类型?

5. 为什么InnoDB存储引擎选用B+树而不是B树?

6. 什么情况索引会失效?

7. MySQL排查问题的手段有哪些?

8. MySQL性能优化方式?

9. SQL内连接和外连接的区别?

10. MySQL有哪些搜索引擎?

11. 百万数据如何快速查询?

12. 数据库三范式?

13. 索引如何优化?

14. MySQL的事务隔离级别?        并发情况下引起的问题:

15. MySQL怎么恢复半月前的数据?

16. MySQL有哪些部分组成,分别用来做什么?

 17. MySQL中有哪几种锁?

18. char和varchar的区别?

19. 可以使用多少列创建索引

20. MySQL支持事务吗?

21. 简单描述下MySQL中,索引,主键索引,唯一索引,联合索引的区别,对数据库有什么影响(读写方面)

22. 哪种count性能最好?

23. MySQL存储IP地址?

24. select语句的完整执行流程顺序

25. 数据库设计规范

25. 聚簇索引和非聚簇索引的区别?


1. DDL,DML,DCL的区别?

  • DDL:数据定义语言: 一般用来堆数据库表进行结构调整,例如: Create, Drop, Alter
  • DML:数据操作语言: 对数据进行增删改查操作,Insert,Delete,Update,Select
  • DCL:数据控制语言: grant, commit, rollback

2. ACID是什么?事务是什么?

A(Atomictiy ): 原子性,  事务要么被全部执行,要么全不执行

C(Consistency): 一致性,  事务执行使得数据库从一种正确状态转换到另一种正确状态

I(ISolation): 隔离性,  在事务正确提交前, 不允许把该事务对数据的改变提供给其他事物

D(Durability): 持久性,  事务正确提交后,永久保存在数据库, 即使事务提交后有其他故障, 事务处理结果也会保存.

可以这么理解事务: 事务就是被绑定在一起作为一个逻辑工作单元的SQL语句分组 如果任何一个语句操作失败,那么整个操作被失败,以后操作就会有回滚到操作前的状态,或者上一节点. 为了确保要么执行,要么不执行,可以使用事务. 要将有组语句作为事务考虑,就需要通过ACID测试,即原子性,一致性,隔离性,持久性.

事务: 事务是作为一个单元的一组有序的数据库操作,组中所有的数据成功,则事务操作成功,组中有一个失败,则事务不成功. 所有操作完成,则事务提交,其修改将作用于所有其他数据库进程. 如果一个操作失败, 则事务回滚, 该事务的所有操作将被取消.

3. InnoDB和MyISAM的区别

Java面试八股文(2023最新)--MySQL面试题_第1张图片
MySQL默认InnoDB存储引擎,它的事务隔离级别为可重复读,适合比较庞大的应用场景.

4. 索引有哪些类型?

  • 数据结构角度
    • 树索引
    • Hash索引
  • 物理存储角度
    • 聚集索引
    • 非聚集索引
  • 逻辑角度
    • 普通索引
    • 唯一索引
    • 主键索引
    • 联合索引

5. 为什么InnoDB存储引擎选用B+树而不是B树?

  • B+树是基于B树和叶子节点顺序访问指针进行的,它具有B树的平衡性,并且通过顺序访问指针来提高区间查询的性能.
  • 在B+树中,一个节点中的key从左到右非递减排列,如果某个指针的左右相邻key分别是key i和key i+1,并且不为null,则该指针指向节点的所有key大于等于key i 且小于等于key i+1.
  • 进行查找操作时,首先在根节点进行二分查找,找到一个key所在的指针,然后递归地在指针所指向的节点进行查找.直到查到叶子节点,然后在叶子节点上进行二分查找,找出key所对应的data.
  • 总结:用B+树不用B树考虑的是IO对性能的影响,B树的每个节点都会存储数据,而B+树只有叶子节点才存储数据,所以查找相同的数据量的情况下,B树的高度就会更高,IO更加频繁,数据库索引是存储在磁盘上的,当数据量大时,就不能把整个索引全部加载到内存了,只能逐一加载每一个磁盘页(对应索引树的节点)

6. 什么情况索引会失效?

  • 索引列参与表达式计算: select   'sname'   from   'stu'   where  'age'+10 = 50;
  • 函数运算: select   'sname'   from   'stu'   where  left('date',4) >  2000;
  • %在前的 模糊查询:  select  'sname'  from   'stu'  where  'sname'  like  '%张';  -- 不走索引
  • 字符串与数字比较:  select  *   from   'stu'  where  'phone'  =  1888   --不走索引
  • 查询条件中有or,即使其中有条件字段带索引也不会走索引,除非所有条件字段都带索引:  
  • 正则表达式不走索引
  • MySQL优化器不使用索引

7. MySQL排查问题的手段有哪些?

  • 使用Explain 查询SQL执行计划
  • 开启慢查询日志,查看慢查询的SQL
  • 使用show processlist  查看当前所有的连接信息

8. MySQL性能优化方式?

  • 服务器优化(更换高性能cpu,内存,网络,磁盘等硬件)
  • 表设计的优化: 字段长度控制.增加必要的索引
  • SQL优化:  避免SQL不命中索引的情况
  • 架构部署优化: 一主多从集群的方式部署
  • 编码优化实现读写分离

9. SQL内连接和外连接的区别?

  • 内连接: inner join 或 join 利用了where子句对多表连接形成的笛卡尔积进行筛选,说白了内连接就是获取两个表之间的公共部分
  • 左外连接: 获取左表的内容使用左外
  • 右外连接: 获取右表的内容使用右外

10. MySQL有哪些搜索引擎?

  • InnoDB: 它是一个事务安全的存储引擎,它具备提交,回滚以及崩溃恢复的功能用于保护用户数据,InnoDB的行级锁定以及Oracle风格的一致性无锁读提升了它的多用户并发数及性能.InnoDB将用户数据存储在聚集索引以减少查询带来的IO开销,为了保证数据的完整性,InnoDB还支持外键约束
  • MyISAM:它既不支持事务也不支持外键,优点是访问速度快,但是表级别的锁定限制了它在读写负载方面的性能,因此它经常用于只读或者以读为主的数据场景
  • Memory: 在内存中存储所有的数据,应用于非关键数据快速查找的场景,它的表访问非常快,因为存放在内存中,并且默认使用HASH索引,但是服务一旦关闭,表中数据丢失

11. 百万数据如何快速查询?

  • 方式一:  直接使用数据库提供的SQL语句    select   *  from   表名   limit  x,y ;
  • 方式二:  建立主键索引或唯一索引,利用索引
  • 方式三:  基于索引再排序
    • 此方法需要用到limit分页,MySQL大数据量使用limit分页,随着页码增大,效率会越低下.后续对limit分页优化:
    • 优化方案:  对于有where条件又走limit的,必须设计一个索引,将where放在第一位,limit主键放到第二位,并且只能select 主键  select* from 表 where id  > #{id} limit  #{limit}  (有序id)
    • 方案二: 分表:  按数据库id分成多个小表,每个小表设置索引.查询接口根据id指向小表.如果数据量非常大,考虑分库

12. 数据库三范式?

  • 第一范式: 属性不可再分
  • 第二范式:  在第一范式的基础上,要求每行必须唯一,通常需要加一列,存储唯一标识 被称为主键
  • 第三范式:  在第二范式基础,数据库中不包含其他表存在的非主键信息;
    1. 每列只有一个值,
     2.每行都能被区分
    3. 每个表都不包含其他表非主键信息

13. 索引如何优化?

  • 尽量使用主键查询,聚簇索引上存储了全部数据,相比普通索引,减少了回表消耗
  • mysql5.6以后引入了索引下推优化, 通过适当的联合索引减少回表消耗
  • 频繁查询某些数据,考虑使用覆盖索引
  • 联合索引将高频字段放在最左边

14. MySQL的事务隔离级别?
        并发情况下引起的问题:

  • 脏读(Dirty read): 当一个事务正在访问数据并且对其进行了修改,但是还没提交事务,这时另外一个事务也访问了这个数据,然后使用了这个数据,因为这个数据还没提交到数据库,所以另外一个事务读取的数据就是"脏数据", 这种行为就是"脏读", 依据"脏数据"所做的操作可能是会出现问题的.
  • 修改丢失(Lost of modify):是指一个事务读取一个数据时,另外一个数据也访问了该数据,那么在第一个事务修改了这个数据之后,第二个事务也修改了这个数据.这样第一个事务内的修改结果就被丢失,这种情况被称为修改丢失.  例如: 事务A从表中读取a=10,事务B也读取a=10,事务A修改a=a+1,事务B也修改a=a+1,最终结果都是11,但是A的修改记录丢失了.
  • 不可重复读(Unrepeatableread): 在一个事务内多次读取同一个数据,在这个事务还没结束时,另一个事务也访问了这个数据并对这个数据进行了修改,那么就可能造成第一个事务两次读取的数据不一致,这种情况被称为不可重复读.
  • 幻读(Phantom read): 幻读与不可重复读类似,幻读是指一个事务读取了几行数据,这个事务还没结束,接着另外一个事务插入了一些数据,随后的查询中,事务读取到了的数据就会比原本读的多,就好像发生幻觉一样,所以称之为幻读.

不可重复读和幻读的区别:

  • 不可重复读重点是修改,幻读重点是新增或者删除.    
    • 例一:  事务1的A员工读取自己的工资为4100的操作还没结束,事务2的B员工修改A员工的工资为3000,A员工再读自己工资的时候就变成3000,这就是不可重复读.
    • 例二:  例如工资表中大于2000的有10人, 事务1读取大于2000的人查询到10条记录. 事务2查询大于2000的人,事务1再查询就有11条记录,这就是幻读.

事务的特性:

  • 读未提交(RU): 一个事务还没提交,它做的变更就能被别的事物看到 (可能造成脏读,不可重复读,幻读)
  • 读提交(RC): 一个事务提交后,做的变更才会被其他事务看到 (避免脏读,但是可能造成不可重复读,幻读)
  • 可重复读(RR): 一个事务执行过程中看到的数据,总是跟这个事务在启动时看到的数据一致,当然在可重复读隔离级别下,未提交变更对其他事务也是不可见的 (避免脏读,不可重复读,可能造成幻读)
  • 串行化(S): 对于同一行记录,读写都会加锁,出现读写锁冲突时,后访问的事务必须等待前面的事务执行完成才能执行 (避免脏读,不可重复读,幻读 )
  • 隔离级别 脏读 不可重复读 幻读
    读未提交
    读提交 ×
    可重复读 × ×
    可串行化 × × ×

15. MySQL怎么恢复半月前的数据?

通过整库的备份+binlog进行恢复,前提要有定期整库备份且保存了binlog日志

16. MySQL有哪些部分组成,分别用来做什么?

  • Service: 
    • 连接器: 管理连接,权限验证
    • 分析器: 词法分析, 语法分析
    • 优化器: 执行计划生成,索引的选择
    • 执行器:操作存储引擎,返回执行结果
  • 存储引擎: 存储数据,提供读写接口

 17. MySQL中有哪几种锁?

  • 表级锁: 开销小,加锁快,不会出现死锁;锁粒度大,发生锁冲突概率最高,并发度低
  • 行级锁: 开销大,加锁慢,会出现死锁,锁粒度小,冲突概率最低,并发度最高
  • 页面锁: 开销和加锁时间介于表锁和行锁之间,会出现死锁;粒度介于之间,并发度一般

18. char和varchar的区别?

  • char和varchar类型存在存储的检索的不同
  • char为声明时固定长度,范围是1到255,当char值被存储,会用空格填充到特定长度.

19. 可以使用多少列创建索引

  • 任何标准表可以创建16个索引列

20. MySQL支持事务吗?

  • 默认模式下,mysql是autocommit模式,所有数据库更新操作自动提交,不支持事务
  • MySQL表类型是InnoDB Tables或者BDB tables 可以使用事务,使用Set,autocommit = 0就可以使用MySQL允许非autocommit模式,在非autocommit模式下,必须使用commit提交更改,或者使用rollback回滚.

21. 简单描述下MySQL中,索引,主键索引,唯一索引,联合索引的区别,对数据库有什么影响(读写方面)

  • 索引是一种特殊文件(InnoDB数据表上的索引是表空间的组成部分),包含对数据表里所有数据的指针
  • 普通索引(由key或者index定义的索引)的唯一任务是加快数据访问速度
  • 主键,是一种特殊的唯一索引, 在一张表中只能定义一个主键索引,主键用于标识一条记录,使用关键字primary key创建
  • 索引可以覆盖多个数据列,如index(A,B)索引,这就是联合索引
  • 索引可以极大的提高查询速度,降低插入,删除,更新表的速度,因为执行这些操作,还需要操作所索引文件

22. 哪种count性能最好?

按照性能排序:  count(*) = count(1) > count(主键) > count(字段)

23. MySQL存储IP地址?

可以将IP地址转换成整形数据存储,性能更好,占用更小.

mysql提供两个方法处理ip :

  • INET_ATON(); 把ip转为无符号整型(4--8位)
  • INET_NTOA(): 把整形ip转换为地址

插入数据前,先用INET_ATON()把ip转换为整型,显示数据,使用INET_NTOA()把整型ip转为地址

24. select语句的完整执行流程顺序

  1. from 子句组装来自不同数据源的数据
  2. where子句基于指定的条件对记录进行筛选
  3. group by子句将数据划为多个分组
  4. 使用聚合数进行计算
  5. 使用having子句筛选分组
  6. 计算所有表达式
  7. select 的字段
  8. 使用order by 排序

25. 数据库设计规范

  • 基础规范
    • 表存储引擎必须使用InnoDB,表字符默认utf8,必要的时候使用utf8mb4(存储表情符号)
    • 禁止使用存储过程,视图,触发器,Event
    • 禁止数据库存大文件,譬如照片,可以在数据库中存储路径
    • 禁止线上做压力测试
    • 测试,开发,线上数据库环境必须隔离
  • 命名规范
    • 库名,表名,列名必须小写,采用下划线分隔
    • 库名,表名,列名长度不要超过32字符
    • 库备份必须以bak为前缀,日期为后缀
    • 从库必须-s为后缀
    • 备份库以-ss为后缀
  • 表设计规范
    • 单实例表个数控制在2000以内
    • 单表个数控制在1024以内
    • 表必须有主键,推荐使用UNSIGNED整数为主键(无符号整数)
    • 禁止使用外键
    • 建议将大字段,访问频度低的字段拆分到单独的表存储
  • 列设计规范
    • 根据业务区分使用tinying/int/bigint,分别占用1/4/8字节
    • 根据业务使用char/varchar(字段长度基本固定推荐char,字段长度相差大用varchar)
    • 必须把字段定义为notnull并设置默认值
    • 根据业务使用datetime/timestamp
    • 使用int unsigned存储ipv4地址
    • 使用varchar(20)存储手机号
  • 索引规范
    • 唯一索引使用 uniq_[字段名] 来命名
    • 非唯一索引使用 idx_[字段名] 
    • 单张表索引控制在5个内
    • 组合索引字段不超过5个
    • 不建议在频繁更新的字段上加索引
    • 非必要不join查询,如果join查询,被join的字段必须类型相同,并建立索引
  • SQL规范
    • 禁止使用select * 
    • insert必须指定字段, 禁止insert into T values()
    • 隐式类型转换使索引失效,导致全表扫描
    • 禁止where条件使用函数或表达式
    • 禁止负向查询以及%开头的模糊查询
    • 禁止大表join和子查询
    • 同一字段or必须改为in,in的值必须少于50个
    • 应用程序必须捕获SQL异常

25. 聚簇索引和非聚簇索引的区别?

都是B+树的数据结构

  • 聚簇索引: 将数据存储与索引放在一块,并且按照一定顺序组织的,找到索引也就找到了数据,数据的物理存放顺序与索引顺序一致,即: 只要索引是相邻的,那么对应的数据也一定是相邻的存放在磁盘上
  • 非聚簇索引: 叶子节点不存放数据,存储的是数据行地址,也就是说根据索引查找到数据行的位置再取磁盘查找数据,这个类似书的目录.我们要找哪一章的哪一节 就找到页码再去寻找
  • 优点: 
    • 查询通过聚簇索引可以直接获取数据,相比非聚簇索引需要第二次查询效率高.
    • 聚簇索引对于范围查询效率很高,因为数据是按照大小排列的
    • 聚簇索引适合在排序的场合,非聚簇索引不适合
  • 缺点; 
    • 维护索引很昂贵,特别是插入新行或主键被更新导致需要分页的时候.建议大量插入后,选择在负载较低的时间段,通过OPTIMIZETABLE优化表,因为必须移动的行数据可能造成碎片
    • 表因为使用uuid(随机id)作为主键,使数据存储稀疏, 就会出现聚簇索引可能比全表扫描更慢,所以建议使用int的auto_increment作为主键
    • 如果主键比较大,那么辅助索引会更大,因为辅助索引的叶子存储的使主键值,过长的主键会导致非叶子节点占用更多的物理空间.

你可能感兴趣的:(面试,java,面试,数据库)