1.Mybatis的优缺点有哪些?
优点
1.基于SQL语句编程,比较灵活,不会对应用程序或数据库现有设计产生影响,SQL写在XML里,解除SQL与程序代码耦合,便于统一管理。提供xml标签,支持编写动态SQL语句,并可重用。
2.与JDBC相比,减少了大量冗余代码量,不需要手动开关连接
3.很好的与多种数据库兼容
4.提供映射标签,支持对象与数据库的ORM字段关系进行映射;提供对象关系映射标签,支持对象关系组件维护。
缺点
1.SQl语句的编写工作量很大,当字段多、关联表多时,对开发人员编写SQL语句的功底有一定的要求。
2.SQL语句依赖于数据库,导致数据库移植性差,不能随意更换数据库。
2.Mybatis与Hibernate有哪些不同?
1.MyBatis不完全是一个ORM框架,因为MyBatis要求程序员自己写SQL语句;Hibernate对象映射能力强,数据库无关性较好,对于关系模型要求高的软件,使用Hibernate开发能节省很多代码,提高效率。
2.MyBatis直接写原生态SQL,可以严格控制SQL执行性能,灵活度高,非常适合对关系数据模型要求不高的软件开发。但是MyBatis无法做到数据库无关性,如果需要实现支持多种数据库的软件,则工作量大。
3.#{}与${}的区别是什么?
#{}是预编译处理,MyBatis在处理时,会将SQL中的#{}替换为?号,调用PreparedStateme的set方法来赋值,能够有效防止SQL注入,提高系统安全性
${}是字符串替换进行直接赋值,无法阻止SQL注入
4.Mybatis缓存中一级缓存与二级缓存
Mybatis有一级缓存与二级缓存,默认情况下一级缓存是开启的,而且不能关闭。一级缓存指的是sqlSession级别的缓存,当在同一个 SqlSession 中进行相同的 SQL 语句查询时,第二次以后的查询不会从数据库查询,而是直接从缓存中获取。当 SqlSession关闭之后,默认将数据放入二级缓存,二级缓存是可以跨 SqlSession 的缓存,是 mapper 级别的缓存。
对于缓存数据更新机制,当某一个作用域进行了C/U/D操作之后,默认该作用域下的缓存被清除,下次查询只能从数据库中进行查询。
===========================================
大厂面试题
1.索引的基本原理
索引是存储引擎中用于快速找到记录的一种数据结构.
索引的原理:将无序的数据变成有序的查询
1.把创建了索引的内容进行排序
2.对排序结果生成倒排表
3.在倒排表上拼上数据地址链
4.查询时,先拿到倒排表内容,在取出数据地址链,从而拿到具体数据
2.MySQL聚簇索引与非聚簇索引的区别
聚簇索引:数据与索引都存放在叶子结点中,并且按照一定顺序组织,找到索引也就找到了数据,数据的物理存放顺序位置与索引顺序一致。
非聚簇索引:叶子结点中不存放数据,存放的是数据的地址,查询数据时,先根据索引查找到数据存放的地址,在根据地址从磁盘中查找数据,需要二次查询。
聚簇索引与非聚簇索引的优劣对比
优势:
1.聚簇索引查找数据可以直接获取数据,而非聚簇索引需要二次查询,效率比较低
2.聚簇索引对范围查询效率很高,因为数据根据大小排序
3.聚簇索引适合用在排序场合
劣势:
1.维护索引代价昂贵,特别是在插入新行或主键被更新导致要分页时。
2.如果主键较大,辅助索引会变大,因为辅助索引存储的是主键的值,从而占用较大的物理空间
3.表使用UUID作为主键,数据存储稀疏,会出现聚簇索引有可能比全表扫描更慢
InnoDB中一定有主键,主键一定是聚簇索引,不手动设置则会用unique索引,没有unique索引则会使用数据库内部的一个行的隐藏id当做主键索引。在聚簇索引之上创建的索引为辅助索引,辅助索引存储的是主键值。
MyISM使用的是非聚簇索引,非聚簇索引的叶子结点中不存放数据,存放的是数据的地址。
3.MySQL索引的数据结构,各自优劣
MySQL中使用较多的索引有hash索引,B+树索引。
哈希索引:底层数据结构就是哈希表
哈希索引就是采用一定的哈希算法,将键值换算为新的哈希值,检索时不像B+树从根节点扫描到叶子结点逐级查找,只需一次哈希算法即可定位到相应位置,速度快。
如果是等值查询,哈希索引有绝对优势,一次算法即可找到相应键值,若键值不唯一,则需先找到该键所在位置,在根据链表往后扫描,直到找到相应数据。
如果是范围查询,由于需要通过哈希算法计算,原先有序的键值,计算之后有可能变成不连续的,无法用索引进行范围查询搜索。
B+树索引:平衡多叉树
B+树是一个平衡多叉树,非叶子结点不存储数据,数据只出现在叶子结点,每个叶子结点增减了一个链指针,方便进行范围查询。
B+树的中间节点不存放数据,所以与B树相比,同样的磁盘页可以容纳更多的节点元素,访问叶子结点上关联的数据具有更好的缓存命中率。
B树
自平衡多叉树,每个节点都存储关键字。左子节点的关键字值小于该节点关键字值,右子节点的关键字值大于该节点关键字值。
搜索可能在非叶子节点结束
其搜索性能相当于在关键字集内做一次二分查找
4.索引设计的原则
查询更快、占用空间更小
1.适合建立索引的是出现在where子句中的列,或者连接子句中的索引
2.基数较小的表,不适合建立索引
3.使用短索引,当索引过长时,应制定一个前缀长度,节省大量的索引空间
4.不要过度索引。索引过多会降低写操作的性能,且需要额外的磁盘空间。
5.区分性不高的字段不适合创建索引
6.更新频繁的字段不适合创建索引
7.尽量扩展索引,不要新建索引。如表中已有a的索引,现在要加(a,b)的索引,只需修改原来的索引
5.MySQL中锁的类型有哪些?
基于锁的属性:共享锁、排他锁
基于锁的粒度:行级锁(InnoDB)、表级锁(MyISAM)、页级锁、记录锁、间隙锁、临键锁
基于锁的状态:意向共享锁、意向排他锁
共享锁:又称读锁,当一个事务为数据加上读锁之后,其他事务只能对该数据加读锁,不能对数据加写锁,直到所有的读锁释放之后其他事务才能对其进行加写锁。共享锁的特性是支持并发的读取数据,读取数据时不允许修改。
排他锁:又称写锁,当一个事务为数据加上写锁,其他请求不能再为数据加任何锁,直到该锁释放锁,其他事务才能加锁。目的是不允许修改,不允许读取,避免出现脏数据和脏读。
表锁:上锁时锁住整个表。
特性:粒度大,加锁简单,容易冲突
行锁:上锁时锁住的是表的一行或多行记录。
特性:粒度小,不容易冲突,并发度较高
记录锁:行锁的一种,不过记录的锁的范围是表中的某一条记录。
精准条件命中,命中的条件字段是唯一索引
页锁:介于表锁与页锁之间,锁的粒度也介于两者之间。
间隙锁:行锁的一种,事务加锁锁住的是表记录的一个区间,遵循左开右闭原则
临键锁:记录锁与间隙锁的组合,会把查询出来的记录锁住,同时把该范围查询的所有间隙空间锁住。
**意向锁:**当事务为数据加锁之后设置一个状态告诉后边的人,已经对表中的行加了排他锁,就不能再对整个表进行加锁了,后边的人只需要获取这个状态,避免了对整个索引树的每个节点扫描是否加锁,这个状态就是意向锁。
6.mysql主从复制的原理
mysql主从同步过程:
MySQL主从同步复制有三个线程:Master(binlog dump thread)、Slave(I\O thread、SQL thread),Master中一条线程,Slave中两条线程。
主节点binlog,主从同步复制的基础是主库记录数据库表中所有变更记录都会记录到binlog中。
当binglog中有变动时,log dump线程会读取其内容并发送给从节点
从节点I/O线程读取binlog变更内容,写入到 relay log中
从节点的SQL线程读取relay log并更新数据,保持主从数据库的一致性
注:主从节点使用binlog + position偏移量记录主从同步的位置。
MySQL中默认主从复制是异步的,即主库将日志发送给从库之后就不关心从库是否已经处理。
全同步复制:
主库写入binlog后强迫同步日志到从库,所有从库执行完之后才返回给客户端,性能很低。
半同步复制:
从库写入日志成功之后返回确认给主库,主库只要收到一个从库确认就认为写操作完成。
7.谈谈你对数据库读写分离的理解
读写分离是基于代理模式的,代理服务器接收应用层传来的请求,决定转发到那个服务器。
主服务器处理写操作以及实时性要求比较高的读操作,从服务器处理读操作。
读写分离提高性能的原因:
主从服务器负责各自的读和写,极大缓解了锁的争用
从服务器可以使用MyISAM,提高查询性能节约开销
增加冗余,提高可用性
8.MyISAM与InnoDB的区别
存储引擎:表组织/存储数据的方式
InnoDB:
支持ACID事务,支持事务的四种隔离级别
支持行级锁及外键约束,可以支持写并发
不存储总行数
一个InnoDB存储引擎存储在一个文件空间(共享表空间,表的大小不受操作系统控制),也可能为多个(独立表空间,表的大小受操作系统文件限制,一般为2G)
主键索引采用聚簇索引,辅助索引存储主键的值,因而查询时先从辅助索引查找主键值,在访问数据存放地址。
MyIsam:
不支持事务,但每次查询是原子的
支持表级锁,每次操作都是对表加锁
存储表的总行数
一个MyISAM表有三个文件:索引文件、数据文件、表结构文件
采用非聚簇索引,索引文件的数据域存放指向数据文件的指针
9.简述mysql中索引类型及对数据库性能的影响
普通索引:允许被索引的数据列包含重复的值
唯一索引:确保被索引的数据列都是唯一的
主键索引:特殊的唯一索引,一张表只能有一个主键
联合索引:索引可以覆盖多个数据列
全文索引:通过建立倒排索引,极大提升检索效率。
回表查询:通过辅助索引查询,先查到聚集索引,再从聚集索引查对应的值,需要两次查询,称为回表查询
Hash索引:对于每一行数据计算一个哈希码,存储到索引中,同时在哈希表中保存指向每个数据行的指针。
自适应Hash索引:InnoDB中对于某些频繁使用的索引值,会在基于B树的基础之上在创建一个Hash索引,称为自适应Hash索引
覆盖索引:一个索引包含了所有要查询的字段的值,不需要回表查询,即索引本身包含对应的值
对数据库的影响
索引可以极大提高数据查询速度
通过使用索引,可以在查询过程中,使用优化隐藏器,提高系统性能
会降低删除、插入、更新表的速度,因为在执行这些写操作时,需要操作索引文件
索引需要占据物理空间,建立过多的索引会增加物理空间的使用
10.MySQL执行计划
执行计划:就是sql的执行查询的顺序,就是如何使用索引查询,返回结果集的行数
type:优化sql的重要字段,也是判断sql性能和优化程度的重要指标。取值类型范围:
const:通过索引一次命中,匹配一行数据
system:表中只有一行数据,相当于系统表
eq_ref:唯一性索引扫描,对于每个索引键,只有一条记录与之相配
ref:非唯一索引扫描,返回匹配某个值的所有
range:检索给定范围的行,使用一个索引来选择行,一般用于between
index:只遍历索引树
ALL:全表扫描,效率最低。
执行效率:
const > system > eq_ref > ref > range > index > ALL
11.怎么处理慢查询?
1.首先分析语句,看是否加载了额外的数据,可能查询了多余的行并且抛弃了,对语句进行分析并重写
2.分析语句的执行计划,获得其使用索引情况,之后修改语句或索引,使得语句尽可能的命中索引
3.对语句无法进行优化,考虑是否数据量太大,可以进行横向或纵向分表。
12.事务的ACID是怎么保证的?
A:原子性是由undo log日志保证,记录了需要回滚的日志信息,事务回滚撤销已经执行成功的sql
C:一致性由其它三大特性保证
I:隔离性由MVCC保证
D:持久性由内存与redo log日志保证,mysql修改数据会在内存与日志中记录这次操作,宕机时可以从redo log中恢复
InnoDB redo log写盘,InnoDB事务进入prepare状态
如果prepare成功,binlog写盘,再将事务日志持久化到binlog中,如果持久化成功,那么InnoDB事务进入commit状态。
13.什么是MVCC?
多版本并发控制:读取数据时通过类似快照的方式将数据保存下来,这样读锁与写锁就不冲突,不同的事务session会看到自己特定版本的版本链、数据
MVCC只在已提交读与可重复读两个隔离级别下工作。
聚簇索引记录中有两个必要的隐藏列:
trx_id:存储对某条聚簇索引记录进行修改时的事务id
roll_pointer:存了一个指针,指向这条聚簇索引记录的上一个版本的位置
1.开始事务时创建readView,readView维护当前活动的事务id,即未提交事务的id,排序生成一个数组
2.访问数据,获取数据中事务id(事务id的最大记录),对比readView
3.如果在readView的左边看,可以访问,表明该事务已提交
4.如果在右边或者中间,不可以访问,表名该事务未提交,获取roll_pointer,取上一个版本进行重新对比
已提交读与可重复读的MVCC区别:
已提交读下的事务在每次查询时都会生成一个独立的readView
可重复读下的事务在第一次查询时生成一个readView,之后的每次查询都复用之前的readView
14.数据库设计三范式
第一范式:每个表必须有主键,每个字段都是原子性不可再分
第二范式:在第一范式的基础上,非主键字段必须完全依赖主键,不能部分依赖
第三范式:在第二范式的的基础上,非主键字段必须直接依赖主键,不能产生传递依赖
在设计数据库结构的时候,要尽量遵守三范式,如果不遵守,必须有⾜够的理由.⽐如性能. 事实上 我们经常会为了性能⽽妥协数据库的设计。
15.约束有哪些?
非空约束:not null
唯一性约束:unique
主键约束:primary key
外键约束:foreign key 外键值可以为空,被引用的字段必须要有唯一性
感谢阅读,点赞收藏+关注!更多的java课程学习路线,笔记,面试等架构资料,想要学习的同学可以私信(资料)即可免费获取!