Java面试-数据库10问

1、说说MySQL和PgSQL的使用区别?

1、两者都是关系型数据库,前者隶属于Orcle公司迭代更加稳定,后者属于开发社区迭代更加迅速
2、PgSQL的存储引擎是堆表,支持事物的强一致性,保证ACID特性,MySQL只有在存储引擎是InnoDB,才支持事物,在ACID的支持性上略弱于PgSQL
3、PgSQL支持更多的索引类型,gin , gist , sp-gist , brin,MySQL只有BTree、Hash,有更丰富的统计函数并支持更多的编程语法
4、PgSQL的读写效率更高,更适应用于高并发强一致的业务场景,MySQL适用于并发一般,逻辑较为简单的业务场景,单机多核心PgSQL能充分利用多核心,
集群方面PgSQL的主备属于物理复制,MySQL是逻辑复制,MySQL的binlog仅可以做到异步复制,PgSQL的wal可以做到同步复制
5、实际使用PgSQL对字符更友好,支持表情字符、没有字符串长度限制,索引支持更强,查看执行计划略微复杂

2、说说MySQL数据库InnoDB和MyISAM的区别?

1、InnoDB支持事务+行锁,MyISAM不支持事务+表锁,所以MyISAM更适合读多写少,并发少,数据一致性要求不高的场景,反之,InnoDB更适合读少写多,并发高,数据一致性要求较高的场景
2、InnoDB支持外键,MyISAM不支持外键
3、索引区别:
	InnoDB的聚簇索引,即以ID或主键建立的B+树索引,叶子结点存放一条条数据,如果表没有创建主键,InnoDB会以隐藏字段row_id为主键,并创建一个聚簇索引
	InnoDB的非聚簇索引,即以非主键建立的B+树索引,叶子结点存放的是这一条条数据的主键,如果不能索引覆盖,即查询字段不在建立非聚簇索引树的字段内,则会涉及到回表查询   
	MyISAM的聚簇索引同样也是以主键建立的B+树索引,不同的是,叶子结点存放的是一条条数据的文件地址(指针)
	MyISAM的非聚簇索引同样也是以非主键建立的B+树索引,不同的是,叶子结点存放的是一条条数据的主键的文件地址(指针)
4、InnoDB必须要有主键(自己建表不建,也会有6byte的隐藏row_id主键),MyISAM可以没有主键

3、说说二叉树、平衡二叉树、B树、B+树、B*树的区别,以及MySQL的索引结构

1、普通的二叉树模型,即每一个结点都最多只有左、右两个结点(两个子树),并且左结点的值小于当前结点,右结点的值大于当前结点,顶端的结点我们称之为根结点,没有子结点的结点称之为叶子结点。(以二叉树为结构的索引树,每个结点只放一个索引值和一条数据)
2、平衡二叉树是一种特殊的二叉树,它要求一个结点的左右子树的阶数不能大于1,既然是一种特殊二叉树,做索引树和二叉树是一样的。
3、红黑树:结点只有黑、红两种颜色的平衡二叉树,根结点是黑色,红色结点的两个子结点一定是黑色,叶子结点都是NULL值的黑色
4、B树,B树与二叉树最大的区别是,从之前的两路变为多路,从之前的每一个结点变为默认大小为16K的每一页(磁盘上的每一小块儿)(以B树为结构的索引树,每一页可以存放更多的索引值和数据,但由于一条条数据都在页上,16K的空间也是有限的)
5、B+树,是在B树上的一种升级,升级之后的B+树用作索引结构(聚簇索引),非叶子结点只存放索引值,叶子结点存放一条条数据,同一叶子结点上数据,是一个有顺序的单向列表结构,相邻叶子结点是一个双向列表结构
6、B*树在上面B+树的基础上,在非叶子的页与页之间也增加了双向指针,形成一个双向列表(实际上,MySQL的B+树索引结构就已经是这种结构)

4、说说数据库的三范式、ACID、隔离级别以及相应出现的问题,MySQL又是如何解决的

三范式:
	第一范式:确保每列的原子性,即每列的字段值都是不可分解的原子值。
	第二范式(满足第一范式):确保每列都和主键相关,即每张表只能保存一种数据(冗余、拆分)
	第三范式(满足第二范式):确保每列都和主键直接相关,而不能间接相关
ACID:
	A:Atomicity:事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。(事务:访问并可能更新数据库中各项数据的一个程序执行单元)
	C:Consistency:事务执行前后,数据的完整性没有被破坏。
	I:Isolation:事务操作之间相互隔离,互不干扰。
	D:Durability:事务一旦提交之后,对数据的改变就是永久的
数据库事务的隔离级别:
	读未提交:一个事务可以读取另一个事务未提交的数据(问题:脏读:读到了脏数据,即无效的数据(事务A读到了事务B 修改的 未提交的 数据,一旦事务B回滚,那事务A读到的都为 脏数据))
	读已提交:一个事务只能读到另一个事务提交后的数据(问题:不可重复读:读到的数据前后不一致(事务A两次读取数据时,事务B对数据做了 修改 并提交,于是导致前后读到的数据不同了 ))
	可重复读:一个事务可以读到另一个事务提交前的数据(问题:幻读:两次独到的数量不一致(事务A两次读取数据时,事务B对数据做了 增加/删除 并提交,于是导致前后读取到的数量不一致了))
	串行读:事务严格编排顺序执行,解决上面所有问题,但效率也最低
数据库的锁:
   共享锁(读锁)、排他锁(写锁)、表锁、行锁、间隙锁(next-key lock)
数据库的读:
   快照读:普通的select查询都是快照读
   当前读:加锁的select … lock in share mode、select … for update、insert、update、delete 都是当前读
MySQL在RR隔离级别下如何解决脏读、不可重复读以及幻读:
	不加锁的情况下:即快照读,MySQL使用MVCC机制在事务并发的情况下,解决脏读、不可重复读以及幻读(具体使用undo log和read view来实现,RC级别下,每次Select都会生成一个read view;RR隔离级别下,只有第一Select会生成read view,但如果在两次Select之间,执行一次修改,会重新生成read view,所以在RR隔离级别下,快照读(MVCC)只能解决部分不可重复读和幻读)
	加锁的情况下:即当前读,RR隔离级别下,MySQL会使用next-key lock解决幻读,即行锁+间隙锁,RC的隔离级别下,加lock in share mode(共享锁:可再加共享锁,只允许读),或者for update(排他锁:不可再加锁,不许读写)来解决可重复读

5、说说什么会导致索引失效?以及如何查看执行计划

索引失效:
  1、使用条件OR可能会导致索引失效,OR条件的列没有索引就会导致全表扫描
  2、对索引字段使用函数、存在类型转换以及数学运算会引起索引失效
  3、使用LIKE关键字,使用前百分号会引起索引失效
  4、使用组合索引时索引失效的情况(A、B、C)
     1、条件里没有A字段,会导致组合索引全部失效;没有B字段,会导致B、C索引值失效;A、B、C都有只是乱序,查询优化器会进行优化
     2、某个字段使用范围查找、否定条件、like使用前百分号、字段上使用函数、字段上存在类型转换,都会使这个字段或这个字段之后的字段索引值失效
使用Explain查看执行计划:
1、ID:值越大代表语句越先执行
2、TYPE:
	system:表里只有一行记录,const的特例
	const:主键索引、唯一索引一次命中(where id = ?)
	eq_ref:两表联查,唯一性索引一次命中
	ref:普通索引一次性命中(select * from user where name = ‘?’ 使用name字段建立“普通索引”)
	range:遍历索引的某个范围(select * from user where name like ‘?%’)
	index:遍历整个索引结构(select name from user where name like ‘%?%’ 索引覆盖)
	all:全表扫描(select name from user where name like ‘%?%’)

6、数据库是读写分离的吗?如何保证数据的一致性

读写分离。
采用binlog逻辑复制完成异步的主从复制。主从数据库版本尽量相同或主<从,并且服务的服务器时间相同
1、master服务会将每一次数据改变,记录到本服务的、顺序写的二进制文件binlog当中
2、slave服务会每隔一段时请求master服务的binlog文件,查看其是否发生改变,如果发生改变,则启动一个I/O线程去请求获取二进制事件
3、接到请求的master服务,会启动一个dump线程,将binlog的改变以二进制事件形式发送给slave的I/O线程
4、slave的I/O线程接到二进制事件后,将其保存到本服务的relaylog中继日志当中,再启动SQL线程将二进制文件转译成SQL语句在slave服务执行
5、完成复制后,slave服务会见将执行过的relaylog删除
追问:主从复制延时该怎么办?
1、将一主一从,改为一主多从,主写从读,多主多从分散压力
2、在业务服务和数据库之间加入缓存,降低数据库读压力
3、提升硬件设备,读的压力更大的话,优先提升从服务设备

7、数据量大如何进行 分库、分表

   分库分表有两种实现方式,分别为水平拆分、垂直拆分。
   水平拆分是指将一张表里的数据按照一定的拆分规则(id、时间、区域、字段Hash值)(分区键)分成若干张表来存储(t_order01、t_order02、t_order03)
   垂直拆分是指将一张表里的字段分两张表来存储,两张表做好关联关系,保证能匹配到同一条数据
   水平拆分时单纯的range策略会造成冷热数据问题,单纯的Hash策略会有扩容导致的数据迁移问题,最好的办法是range策略➕Hash策略,设计好每张表的容量、设计好取模基数,如果数据持续增加,再加group,保证数据冷热均匀且不用数据迁移。

8、为什么MySQL索引遵循最左匹配原则

这要从MySQL建立的索引树所用到的结构来说,如果是Hash索引,精确查找才用到索引,范围查找不走索引,也就没什么最左匹配原则
再拿最常用的B+树来说,索引树的建立都是按照从上到下一级一级,从左到右一页一页,从小到大一个一个的顺序排列,那在使用时自然要拿实际值与页上索引值进行比较,实际值左边第一位先在树上定位后,再查找便可以利用这棵索引树,如果从左边第一位就开始模糊搜索,索引树也就不会被用到
使用组合索引也是一个道理,使用A、B、C三个字段做联合索引,建立的是一棵索引树,只不过每个索引值分为A、B、C三部分,起到的效果涵盖A;A、B;A、B、C三种索引效果,比较会先从A开始,A相同再比较B,再比较C,同样满足最左匹配原则,才能充分利用组合索引树,所以遵循最左匹配原则,一是遵循索引树的排列规则,二是遵循索引树的查找规则。

9、MySQL的索引类型有哪几种?

 按数据类型分:
 	普通索引
  	唯一索引
  	联合索引
  	主键索引
  	全文索引
按结构类型分:
  	B+树索引:常用的索引结构
  	Hash索引:不支持范围、排序、模糊查询,不支持联合索引,会有Hash冲突问题

10、order by、group by会走索引吗?

假设建立索引key a_b_c(a,b,c):
order by:
	1、order by 能使用最左前缀原则(以下四种情况索引生效):
		order by a
		order by a,b
		order by a,b,c
		order by a desc, b desc, c desc
	2、where+order by符合最左前缀原则,则索引生效
		where a=1 order by b,c
		where a=1 and b=2 order by c
		where a=1 and b>2 order by b,c
	3、以下情况索引失效:
		order by a asc, b desc, c desc 	//排序不一致
		where d=1 order by b,c 			//丢失a索引
		where a=1 order c 				//丢失b索引
		where a>1 order b,c 			//范围之后失效
group by:
	group by实际是先进行排序,再进行分组。所以遵循order by的索引机制。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值