Java面试复习---MySQL

2 篇文章 0 订阅


前言

本文是Java面试复习系列中的MySQL,后面会陆续有该系列其他篇章,并且会一直维护。本系列都为网上资源整理而来,如有问题,及时联系。


MySQL

  • 说说自己对于 MySQL 常见的两种存储引擎:MyISAM与 InnoDB的理解

    • MyISAMInnoDB
      count没有
      事务和崩溃后的安全恢复没有
      强调性能,查询具有原子性

      具有事务、回滚、崩溃修复的事务安全型表
      外键不支持支持
    • 总结:

      • MyISAM更适合读密集的表
        InnoDB更适合写密集的的表。
      • 在数据库做主从分离的情况下,经常选择MyISAM作为主库的存储引擎。
      • 一般来说,如果需要事务支持,并且有较高的并发读取频率(MyISAM的表锁的粒度太大,所以当该表写并发量较高时,要等待的查询就会很多了),InnoDB是不错的选择。
        如果你的数据量很大(MyISAM支持压 缩特性可以减少磁盘的空间占用),而且不需要支持事务时,MyISAM是最好的选择。
  • 当MySQL单表记录数过大时,数据库的CRUD性能会明显下降,一些常见的优化措施

    • 限定数据的范围

    • 读写分离:主库负责写,从库负责读

    • 垂直分区:根据数据库里面数据表的相关性进行拆分。

      • 简单来说垂直拆分是指数据表列的拆分, 把一张列比较多的表拆分为多张表。
      • 优点:可以使得行数据变小,在查询时减少读取的Block数,减少I/O次数。此外,垂直分区可以简 化表的结构,易于维护
      • 缺点:主键会出现冗余,需要管理冗余列,并会引起Join操作,可以通过 在应用层进行Join来解决。此外,垂直分区会让事务变得更加复杂;
    • 水平分区: 保持数据表结构不变,通过某种策略存储数据分片。

      • 水平拆分是指数据表行的拆分。
      • 优点:水平拆分能 够 支持非常大的数据量存储,应用端改造也少
      • 缺点:但分片事务难以解决 ,跨界点Join性能较差,逻辑复杂
  • 数据库分片常见方案

    • 客户端代理: 分片逻辑在应用端,封装在jar包中,通过修改或者封装JDBC层来实现。
    • 中间件代理: 在应用和数据中间加了一个代理层。分片逻辑统一维护在中间件服务中。

事务

  • 概念:

    • 事务是逻辑上的一组操作,要么都执行,要么都不执行
  • 特性:

    • 原子性:事务是最小的执行单位,不允许分割。事务的原子性确保动作要么全部完成,要么完全不起作用
    • 一致性: 执行事务前后,数据保持一致,多个事务对同一个数据读取的结果是相同的
    • 隔离性:并发访问数据库时,一个用户的事务不被其他事务所干扰,各并发事务之间数据库是独立的
    • 持久性:一个事务被提交之后。它对数据库中数据的改变是持久的,即使数据库发生故障也不应该对其有任何影 响。

并发事务带来的影响

  • 脏读(Dirty read): 当一个事务正在访问数据并且对数据进行了修改,而这种修改还没有提交到数据库中,这时另外一个事务也访问了这个数据,然后使用了这个数据。因为这个数据是还没有提交的数据,那么另外一个 事务读到的这个数据是“脏数据”,依据“脏数据”所做的操作可能是不正确的。 (读取了修改未保存的数据)
  • 丢失修改(Lost to modify): 指在一个事务读取一个数据时,另外一个事务也访问了该数据,那么在第一个事务中修改了这个数据后,第二个事务也修改了这个数据。这样第一个事务的修改结果就被丢失,因此称为丢失修改。(丢失第一个事务的修改)
  • 不可重复读(Unrepeatableread): 指在一个事务内多次读同一数据。在这个事务还没有结束时,另一个事务也访问该数据。那么,在第一个事务中的两次读数据之间,由于第二个事务的修改导致第一个事务两次读取的数据可能不太一样。这就发生了在一个事务内两次读到的数据是不一样的情况,因此称为不可重复读。(由于修改,第一个事务两次读取结果不一样)
  • 幻读(Phantom read): 幻读与不可重复读类似。它发生在一个事务(T1)读取了几行数据,接着另一个并发事务(T2)插入了一些数据时。在随后的查询中,第一个事务(T1)就会发现多了一些原本不存在的记录,就好像发生了幻觉一样,所以称为幻读。(由于更新,第一个事务两次读取结果不一样)
    • 不可重复读和幻读的区别:
      • 不可重复读的重点是修改,幻读的重点在于新增或者删除。

事务隔离级别

  • READ-UNCOMMITTED(读取未提交): 最低的隔离级别,允许读取尚未提交的数据变更,可能会导致脏读、幻读或不可重复读

  • READ-COMMITTED(读取已提交): 允许读取并发事务已经提交的数据,可以阻止脏读,但是幻读或不可重复读仍有可能发生

  • REPEATABLE-READ(可重复读): 对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,可以阻止脏读和不可重复读,但幻读仍有可能发生。

  • SERIALIZABLE(可串行化): 最高的隔离级别,完全服从ACID的隔离级别。所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,该级别可以防止脏读、不可重复读以及幻读。

    • 隔离级别脏读不可重复读幻读
      READ-UNCOMMITTED
      READ-COMMITTED×
      REPEATABLE-READ××
      SERIALIZABLE×××

MySQL InnoDB

MySQL InnoDB 存储引擎的默认支持的隔离级别是 REPEATABLE-READ(可重读),可以通过 SELECT @@tx_isolation; 命令来查看。

这里需要注意的是:与 SQL 标准不同的地方在于InnoDB 存储引擎在 REPEATABLE-READ(可重读)事务隔离级别下使用的是Next-Key Lock 锁算法,因此可以避免幻读的产生。即达到了 SQL标准的SERIALIZABLE(可串行化)隔离级别。

视图

  • 视图实际上是在数据库中通过Select查询语句从多张表中提取的多个表字段所组成的虚拟表。
    • 视图并不占据物理空间,所以通过视图查询出的记录并非保存在视图中,而是保存在原表中。
    • 通过视图可以对指定用户隐藏相应的表字段,起到保护数据的作用。
    • 在满足一定条件时,可以通过视图对原表中的记录进行增删改操作。
    • 创建视图时,只能使用单条select查询语句。

索引

什么是索引?

  • 索引是对数据库表中一列或多列的值进行排序的一种结构,使用索引可快速访问数据库表中的特定信息。
    • 索引分为:聚集索引、非聚集索引、唯一索引等。
      • 一张表可以有多个唯一索引和非聚集索引,但最多只能有一个聚集索引。
    • 索引可以包含多列。
    • 合理的创建索引能够提升查询语句的执行效率,但降低了新增、删除操作的速度,同时也会消耗一定的数据库物理空间。 是一种快速查询表中内容的机制,类似于字典。
    • 运用在表中某个些字段上,但存储时,独立于表外。
    • 索引一旦建立,Oracle管理系统会对其进行自动维护,而且由Oracle管理系统决定何时使用索引。 用户不用再查询语句中指定使用哪个索引。
    • 在定义primary key或unique约束后系统自动在想印的列上创建索引用户也能按自己的需求,对指定单个字段或多个字段,添加索引。

为什么要使用索引?

  • 通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。
  • 可以大大加快数据的检索速度(大大减少的检索的数据量), 这也是创建索引的最主要的原因
  • 帮助服务器避免排序和临时表
  • 将随机IO变为顺序IO
  • 可以加速表和表之间的连接,特别是在实现数据的参考完整性方面特别有意义。

索引这么多优点,为什么不对表中的每一个列创建一个索引呢?

  • 当对表中的数据进行增加、删除和修改的时候,索引也要动态的维护,这样就降低了数据的维护速度。
  • 索引需要占物理空间,除了数据表占数据空间之外,每一个索引还要占一定的物理空间,如果要建立聚簇索引,那么需要的空间就会更大。
  • 创建索引和维护索引要耗费时间,这种时间随着数据量的增加而增加。

索引是如何提高查询速度的?

  • 将无序的数据变成相对有序的数据(就像查目录一样)

说一下使用索引的注意事项

  • 避免 where 子句中对字段施加函数,这会造成无法命中索引。
  • 在使用InnoDB时使用与业务无关的自增主键作为主键,即使用逻辑主键,而不要使用业务主键。
  • 将打算加索引的列设置为 NOT NULL ,否则将导致引擎放弃使用索引而进行全表扫描
  • 删除长期未使用的索引,不用的索引的存在会造成不必要的性能损耗 MySQL 5.7 可以通过查询 sys 库的 chema_unused_indexes 视图来查询哪些索引从未被使用
  • 在使用 limit offset 查询缓慢时,可以借助索引来提高性能

Mysql索引主要使用的哪两种数据结构

  • 哈希索引:对于哈希索引来说,底层的数据结构就是哈希表,因此在绝大多数需求为单条记录查询的时候,可以选择哈希索引,查询性能最快,其余大部分场景,建议选择BTree索引。
  • BTree索引:Mysql的BTree索引使用的是B树中的B+Tree。但对于主要的两种存储引擎(MyISAM和InnoDB) 的实现方式是不同的。

什么是覆盖索引?

  • 如果一个索引包含(或者说覆盖)所有需要查询的字段的值,我们就称 之为“覆盖索引”。

什么时候需要创建索引?

  • 表经常进行 SELECT 操作
  • 表很大(记录超多),记录内容分布范围很广
  • 列名经常出现在WHERE字句或连接条件中

什么时候不要创建索引

  • 表经常进行 INSERT/UPDATE/DELETE 操作
  • 表很小(记录超少)
  • 列名不经常作为连接条件或出现在 WHERE 子句中

索引的优缺点

  • 索引加快数据库的检索速度
  • 索引降低了插入、删除、修改等维护任务的速度(虽然索引可以提高查询速度, 但是它们也会导致数据库系统更新数据的性能下降,因为大部分数据更新需要同时更新索引)
  • 唯一索引可以确保每一行数据的唯一性,通过使用索引,可以在查询的过程中使用优化隐藏器,提高系统的性能
  • 索引需要占物理和数据空间

索引分类

  • 唯一索引:唯一索引不允许两行具有相同的索引值
  • 主键索引:为表定义一个主键将自动创建主键索引,主键索引是唯一索引的特殊类型。主键索引要求主键中的每个值是唯一的,并且不能为空
  • 聚集索引(Clustered):表中各行的物理顺序与键值的逻辑(索引)顺序相同, 每个表只能有一个
  • 非聚集索引(Non-clustered):非聚集索引指定表的逻辑顺序。数据存储在一个位置,索引存储在另一个位置,索引中包含指向数据存储位置的指针。可以有多个,小于249个

聚集索引和非聚集索引区别

  • 聚集索引表记录的排列顺序和索引的排列顺序一致,所以查询效率快。
  • 聚集索引指定了表中记录的逻辑顺序,但是记录的物理和索引不一定一致。
  • 聚集索引和非聚集索引的根本区别是表记录的排列顺序和与索引的排列顺序是否一 致。

存储过程

  • 存储过程是一个预编译的SQL语句
    • 存储过程的优点: 能够将代码封装起来保存在数据库之中,让编程语言进行调用存储过程执行效率比较高, 一个存储过程替代大量T_SQL语句 ,可以降低网络通信量,提高通信速率
    • 存储过程的缺点: 每个数据库的存储过程语法几乎都不一样,十分难以维护(不通用) ,业务逻辑放在数据库上,难以迭代
  • 预编译又称为预处理,是做些代码文本的替换工作。 处理#开头的指令。

触发器

  • 触发器是一种特殊的存储过程,主要是通过事件来触发而被执行的。它可以强化约束 ,来维护数据的完整性和一致性,可以跟踪数据库内的操作从而不允许未经许可的更新和变化。可以联级运算。

数据库约束

  • 数据库约束用于保证数据库表数据的完整性(正确性和一致性)。可以通过定义约束\ 索引\触发器来保证数据的完整性。
    • 主键约束:primary key;
    • 外键约束:foreign key;
    • 唯一约束:unique;
    • 检查约束:check;
    • 空值约束:not null;用于控制字段的值范围。
    • 默认值约束:default

列举几种常用的聚合函数?

  • Sum:求和
  • Avg:求平均数
  • Max:求最大值
  • Min:求最小值
  • Count:求记录数

什么是内联接、左外联接、右外联接?

  • 在判定左表和右表时,要根据表名出现在Outer Join的左右位置关系。
    • 内联接(Inner Join):匹配2张表中相关联的记录。
    • 左外联接(Left Outer Join):除了匹配2张表中相关联的记录外,还会匹配左表中剩余的记录,右表中未匹配到的字段用NULL表示。
    • 右外联接(Right Outer Join):除了匹配2张表中相关联的记录外,还会匹配右表中剩余的记录,左表中未匹配到的字段用NULL表示。

非关系型数据库和关系型数据库区别,优势比较

  • 非关系型数据库的优势:
    • 性能:NOSQL是基于键值对的,可以想象成表中的主键和值的对应关系, 而且不需要经过SQL层的解析,所以性能非常高。
    • 可扩展性:同样也是因为基于键值对,数据之间没有耦合性,所以非常容易水平扩展。
  • 关系型数据库的优势:
    • 复杂查询:可以用SQL语句方便的在一个表以及多个表之间做非常复杂的数据查询。
    • 事务支持:使得对于安全性能很高的数据访问要求得以实现。

like %和-的区别

  • %百分号通配符:表示任何字符出现任意次数(可以是0次)
  • _下划线通配符: 表示只能匹配单个字符,不能多也不能少就是一个字符

B+Tree索引和Hash索引

B+Tree索引和Hash索引的区别

  • Hash索引结构的特殊性,其检索效率非常高,索引的检索可以一次定位
  • B+树索引需要从根节点到枝节点,最后才能访问到页节点这样多次的IO访问

为什么不都用Hash索引而使用B+树索引

  • Hash索引仅仅能满足"=",“IN"和”"查询,不能使用范围查询
  • Hash索引遇到大量Hash值相等的情况后性能并不一定就会比B+树索引高

为什么说B+比B树更适合实际应用中操作系统的文件索引和数据库索引

  • B+的磁盘读写代价更低
    • B+的内部结点并没有指向关键字具体信息的指针。因此其内部结点相对B树更小。如果把所有同一内部结点的关键字存放在同一盘块中,那么盘块所能容纳的关键字数量也越多。一次性读入内存中的需要查找的关键字也就越多。相对来说IO读写次数也就 降低了
  • B+tree的查询效率更加稳定
    • 由于非终结点并不是最终指向文件内容的结点,而只是叶子结点中关键字的索引。所以任何关键字的查找必须走一条从根结点到叶子结点的路。所有关键字查询的路径长度相同,导致每一个数据的查询效率相当。

  • 概念:
    • 当并发事务同时访问一个资源时,有可能导致数据不一致,因此需要一种机制来将数 据访问顺序化,以保证数据库数据的一致性。多个事务同时读取一个对象的时候,是不会有冲突的。同时读和写,或者同时写才会产生冲突
  • 共享锁(Shared Lock,也叫S锁)
    • 共享锁(S)表示对数据进行读操作。因此多个事务可以同时为一个对象加共享锁
  • 排他锁(Exclusive Lock,也叫X锁)
    • 排他锁表示对数据进行写操作。如果一个事务对对象加了排他锁,其他事务就不能再 给它加任何锁了
  • 锁的粒度:就是通常我们所说的锁级别。
    • MySQL有三种锁的级别:页级、表级、行级。
    • 表级锁:开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最高,并发度最低。
      • 表锁(Table Lock) 对整个表加锁,影响标准的所有记录。通常用在DDL语句中,如DELETE TABLE,ALTER TABLE等。 很明显,表锁影响整个表的数据,因此并发性不如行锁好。
    • 行级锁:开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高。
      • 行锁(Row Lock) 对一行记录加锁,只影响一条记录。 通常用在DML语句中,如INSERT,,UPDATE,DELETE等。
    • 页面锁:开销和加锁时间界于表锁和行锁之间;会出现死锁;锁定粒度界于表锁和行锁之间,并发度一般。
  • 乐观锁
    • 总是假设最好的情况,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号机制和CAS算法实现。
    • 乐观锁适用于多读的应用类型,这样可以提高吞吐量。
  • 悲观锁
    • 总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻塞直到它拿到锁(共享资源每次只给一 个线程使用,其它线程阻塞,用完后再把资源转让给其它线程)。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。

MySQL主从复制

  • 概念:数据可以从一个MySQL数据库服务器主节点复制到一个或多个从节点。MySQL 默认采用异步复制方式,这样从节点不用一直访问主服务器来更新自己的数据,数据的更新可以在远程连接上进行,从节点可以复制主数据库中的所有数 据库或者特定的数据库,或者特定的表
  • 主从复制的方式:
    • 同步复制
    • 异步复制
    • 半同步复制
  • 主要用途:
    • 读写分离
    • 数据实时备份
    • 高可用HA
    • 框架扩展

Hibernate 有哪 5 个核心接口?

  • Configuration 接口:配置 Hibernate,根据其启动hibernate,创建 SessionFactory 对象;
  • SessionFactory 接口:初始化 Hibernate,充当数据存储源的代理,创建 session 对象,sessionFactory 是线程安全的,意味着它的同一个实例可以被应 用的多个线程共享,是重量级、二级缓存;
  • Session 接口:负责保存、更新、删除、加载和查询对象,是线程不安全的, 避免多个线程共享同一个 session,是轻量级、一级缓存;
  • Transaction 接口:管理事务;
  • Query 和 Criteria 接口:执行数据库的查询。

什么是重量级?什么是轻量级?

  • 轻量级是指它的创建和销毁不需要消耗太多的资源,意味着可以在程序中经常创建和销毁 session 的对象;
  • 重量级意味不能随意的创建和销毁它的实例,会占用很多的资源

事务处理?

  • Connection 类中提供了 3 个事务处理方法:
    • setAutoCommit(Boolean autoCommit):设置是否自动提交事务,默认为自动提交事务,即为 true,通过设置 false 禁止自动提交事务;
    • commit():提交事务;
    • rollback():回滚事务。

Java中访问数据库的步骤?Statement和 PreparedStatement之间的区别?

  • Java 中访问数据库的步骤如下:
    • 注册驱动
    • 建立连接
    • 创建 Statement
    • 执行 sql 语句
    • 处理结果集(若 sql 语句为查询语句)
    • 关闭连接
  • PreparedStatement 被创建时即指定了 SQL 语句,通常用于执行多次结构相同的 SQL 语句。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值