数据库面试题

目录

目录

MySQL八股文

一. InnoDB和MyISAM功能上的区别

二. InnoDB和MyISAM索引上的区别

三.哈希索引,B树,B+树的区别:

四.为什么使用多叉树不使用二叉树:

五.事务的特性ACID,如何实现:

六.并发问题:

七.隔离级别:

八.悲观锁和乐观锁:

九.表锁和行锁:

十.死锁的产生和避免:

Redis八股文

1.redis和MySQL数据一致性的问题,双删策略

2.redis缓存雪崩,击穿,穿透


MySQL八股文

一. InnoDB和MyISAM功能上的区别

  1. InnoDB支持事务,MyISAM不支持,对于InnoDB每一条SQL语言都默认封装成事务,自动提交,这样会影响速度,所以最好把多条SQL语言放在begin和commit之间,组成一个事务;

  2. InnoDB支持外键,而MyISAM不支持。对一个包含外键的InnoDB表转为MYISAM会失败;

  3. InnoDB不保存表的具体行数,执行select count(*) from table时需要全表扫描。而MyISAM用一个变量保存了整个表的行数,执行上述语句时只需要读出该变量即可,速度很快;

  4. Innodb不支持全文索引,而MyISAM支持全文索引,查询效率上MyISAM要高

二. InnoDB和MyISAM索引上的区别

        相同点:都是用B+树

        不同点:

        1.InnoDB主键使用聚簇索引数据文件是和索引(叶子节点)绑在一起的。必须要有主键,主键索引直接存记录的内容,通过主键索引效率很高。非主键索引(辅助索引)的叶子节点只存当前列数据和主键ID。因此需要两次查询,先查询到主键,然后再通过主键查询到数据(称为回表)。但如果select语句只查询索引列,那么也不用回表。因此,主键不应该过大,因为主键太大,其他索引也都会很大。

        为什么InnoDB的辅助索引的叶子节点不直接存储数据的物理地址呢?因为InnoDB在移动行时,无需维护辅助索引,因为叶子节点中存储的是主键值,而不是指针。

        2.MyISAM是非聚集索引,数据文件是分离的,索引保存的是数据文件的指针,是数据的物理地址。主键索引和辅助索引唯一的区别是:主键索引不能重复。

三.哈希索引,B树,B+树的区别:

1.哈希索引:简单,快捷,直接哈希就可以以O(1)的速度搜索数据,但是无法进行范围查询

2.B树和B+树:都是平衡多叉树。但是B+树的非叶子节点不保存关键字记录的指针,只进行数据索引;B+树叶子节点保存了父节点的所有关键字记录的指针,所有数据地址必须要到叶子节点才能获取到。使得树的高度更矮。B+树的叶子节点使用双向链表链接,进行快速范围查找以及全节点扫描。

四.为什么使用多叉树不使用二叉树:

        减少磁盘IO

五.事务的特性ACID,如何实现:

1.原子性:要么都做,要么都不做。使用undoLog。undo log主要记录了数据的逻辑变化。出错时进行回滚。

2.持久性

    只要事务提交成功,那么对数据库做的修改就被永久保存下来了,不可能因为任何原因再回到原来的状态 。

    使用redo log .包括两部分:一个是内存中的日志缓冲( redo log buffer ),另一个是磁盘上的日志文件( redo logfile)。mysql 每执行一条 DML 语句,先将记录写入 redo log buffer,后续某个时间点再一次性将多个操作记录写到 redo log file。这种 先写日志,再写磁盘 的技术就是 MySQL。

3.一致性:

        一致性是指事务必须使数据库从一个一致性状态变换到另一个一致性状态,也就是说一个事务执行之前和执行之后都必须处于一致性状态。举例来说,假设用户A和用户B两者的钱加起来一共是1000,那么不管A和B之间如何转账、转几次账,事务结束后两个用户的钱相加起来应该还得是1000,这就是事务的一致性。通过写代码保证。

4.隔离性:

        不同事务之间互相独立,互不干扰,引申出四个隔离级别。

六.并发问题:

详细见:mysql的事务四个特性以及事务的四个隔离级别 - java界的小python - 博客园

1.脏读:

        事务B修改一个数据,事务A读这个数据,但是事务B回滚了。那么A读到的数据就是脏数据。设置隔离级别为:读取已提交的数据可解决问题。使用写锁排它锁即可。

2.不可重复读:

        事务A读取数据等于100,事务B修改数据为200并提交。事务A再读取数据发现等于200,一次事务内的两次读取结果不同,称为不可重复读。 

        设置隔离级别:重复读可解决问题。设置读时只能自己这个事务进行修改即可。

3.幻读:

        两次执行同一条 select 语句会出现不同的结果,第二次读会增加一数据行。设置串行化可以解决。MySQL使用了next-key,在读取数据时,将该数据一定范围内的行都加了锁,解决这个问题。

七.隔离级别:

        数据库事务的隔离级别有4个,由低到高依次为Read uncommitted(未授权读取、读未提交)、Read committed(授权读取、读提交)、Repeatable read(可重复读取)、Serializable(序列化),这四个级别可以逐个解决脏读、不可重复读、幻象读这几类问题。

        大多数数据库的默认级别就是Read committed,比如Sql Server , Oracle。MySQL的默认隔离级别就是Repeatable read。

八.悲观锁和乐观锁:

        乐观锁是一种思想,不是真的一个锁。

        乐观锁认为当前场景不容易发生冲突,所以查询数据时不加锁,更改数据时查看是否和自己之前查看的值是相同的(例如使用版本号),如果相同就更改,不同则重试。如果当前场景冲突很多,那么就不适合采用这个思想。

        悲观锁认为当前场景容易发生冲突,所以在一开始查询数据的时候就加锁。使用:select…for update

九.表锁和行锁:

        mysiam使用表锁,InnoDB两个都用。如果有索引就是行锁,没有索引就是表锁。

        表锁冲突多,实现简单。行锁冲突少,但是容易有死锁。

十.死锁的产生和避免:

原因:

        互斥条件:进程要求对所分配的资源(如打印机)进行排他性控制,即在一段时间内某 资源仅为一个进程所占有。此时若有其他进程请求该资源,则请求进程只能等待。
        不剥夺条件:进程所获得的资源在未使用完毕之前,不能被其他进程强行夺走,即只能 由获得该资源的进程自己来释放(只能是主动释放)。
        请求和保持条件:进程已经保持了至少一个资源,但又提出了新的资源请求,而该资源 已被其他进程占有,此时请求进程被阻塞,但对自己已获得的资源保持不放。
        循环等待条件:存在一种进程资源的循环等待链,链中每一个进程已获得的资源同时被 链中下一个进程所请求。

避免:

        1.破坏“请求和保持”条件:让进程在申请资源时,一次性申请所有需要用到的资源,不要一次一次来申请,当申请的资源有一些没空,那就让线程等待。不过这个方法比较浪费资源,进程可能经常处于饥饿状态。

        2.破坏“不可抢占”条件:允许进程进行抢占,方法一:如果去抢资源,被拒绝,就释放自己的资源。方法二:操作系统允许抢,只要你优先级大,可以抢到。

        3.破坏“循环等待”条件:将系统中的所有资源统一编号,进程可在任何时刻提出资源申请,但所有申请必须按照资源的编号顺序(升序)提出.

Redis八股文

1.redis和MySQL数据一致性的问题,双删策略

答:我们可以在读数据的时候,如果缓存没有数据,那么就读数据库,之后更新缓存。

写数据时,我们先修改数据库,之后删除缓存。删除缓存而不是更新缓存,是因为

        1.缓存的值不一定是数据库里面的值直接算出来的。

        2.而且我们可能写多读少,每次写都去修改缓存不划算。删缓存比较快

问:如果先修改数据库,后更新缓存,那么在修改数据库之前,别的请求过来了,那不就读到错误的的缓存了吗?

答:那我们可以:先删除缓存,再修改数据库。

问:那如果我们在删除缓存后,但修改数据库,还没有提交事务时,别的请求读数据,那就会读到旧数据,并更新一个错误的缓存。该怎么办?

答:那我们可以:先删除缓存,再修改数据库,修改完数据库之后等一会儿再删除一下缓存。

问:为什么要等一会儿?

答:第一个请求执行到了修改数据库,马上要提交的时候,请求2过来读数据库,更新缓存。我们要把这段时间空出来,不然有可能咱们删除了缓存,请求2又更新了一个错误缓存。

问:这样就绝对数据一致了嘛?

答:还没有绝对一致,因为请求2更新完缓存后,到我们延迟删除缓存之间,还是会有一点数据不一致。

2.redis缓存雪崩,击穿,穿透

什么是缓存雪崩、击穿、穿透? | 小林coding

雪崩指的是好多key集体失效或者redis宕机

击穿指的是热点数据失效。

穿透是指的非法请求。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值