剑指java offer数据库面试
设计一个关系型数据库
程序实例
存储管理,缓存机制,SQL解析,日志管理、权限划分、容灾机制、索引管理、锁管理
存储(文件系统)
索引模块
常见问题
为什么要使用索引
快速查询数据
什么样的信息能成为索引
主键、唯一键以及普通键等
索引的数据结构
生成索引,建立二叉查找树进行二分查找
生成索引,建立B-Tree结构进行查找
生成索引,建立B+-Tree结构进行查找
生成索引,建立Hash结构进行查找
二叉查找树 --很容易变得像链表了
B-Tree
定义
根节点至少包括两个孩子
树中每个节点最多含有m个孩子(m>=2)
除根节点和叶节点外,其他每个节点至少有ceil(m/2)个孩子
所有叶子节点都位于同一层
B+Tree
B+树是B树的变体,其定义基本与B树相同,除了:
非叶子节点的子树指针与关键字个数相同
非叶子节点的子树指针P[i],指向关键字值[K[i],K[i+1]]的子树
非叶子节点仅用来索引,数据都保存在叶子节点中
所有叶子节点均有一个链指针指向下一个叶子结点
B+Tree更适合用来做存储索引
B+树的磁盘读写代价更低
B+树的查询效率更加稳定
B+树更有利于对数据库的扫描
Hash索引
缺点
仅仅能满足 "=","IN",不能使用范围查询
无法被用来避免数据的排序操作
不能利用部分索引键查询
不能避免表扫描
遇到大量Hash值相等的情况后性能并不一定会比B-Tree索引高
为什么mysql用B+树做索引而不用B-树或红黑树
B-树、B+树、红黑树,都是平衡查找树,那么查询效率上讲,平均都是O(logn)。使用什么哪种数据结构,肯定是出于提高数据库的查询效率的考虑。
一、B+树做索引而不用B-树
那么Mysql如何衡量查询效率呢?– 磁盘IO次数。
一般来说索引非常大,尤其是关系性数据库这种数据量大的索引能达到亿级别,所以为了减少内存的占用,索引也会被存储在磁盘上。B-树/B+树 的特点就是每层节点数目非常多,层数很少,目的就是为了减少磁盘IO次数,但是B-树的每个节点都有data域(指针),这无疑增大了节点大小,说白了增加了磁盘IO次数(磁盘IO一次读出的数据量大小是固定的,单个数据变大,每次读出的就少,IO次数增多,一次IO多耗时),而B+树除了叶子节点其它节点并不存储数据,节点小,磁盘IO次数就少。
优点一: B+树只有叶节点存放数据,其余节点用来索引,而B-树是每个索引节点都会有Data域。
优点二: B+树所有的Data域在叶子节点,并且所有叶子节点之间都有一个链指针。 这样遍历叶子节点就能获得全部数据,这样就能进行区间访问啦。在数据库中基于范围的查询是非常频繁的,而B树不支持这样的遍历操作。
二、B+树做索引而不用红黑树
AVL 树(平衡二叉树)和红黑树(二叉查找树)基本都是存储在内存中才会使用的数据结构。在大规模数据存储的时候,红黑树往往出现由于树的深度过大而造成磁盘IO读写过于频繁,进而导致效率低下的情况。为什么会出现这样的情况,我们知道要获取磁盘上数据,必须先通过磁盘移动臂移动到数据所在的柱面,然后找到指定盘面,接着旋转盘面找到数据所在的磁道,最后对数据进行读写。磁盘IO代价主要花费在查找所需的柱面上,树的深度过大会造成磁盘IO频繁读写。根据磁盘查找存取的次数往往由树的高度所决定,所以,只要我们通过某种较好的树结构减少树的结构尽量减少树的高度,B树可以有多个子女,从几十到上千,可以降低树的高度。
数据库系统的设计者巧妙利用了磁盘预读原理,将一个节点的大小设为等于一个页,这样每个节点只需要一次I/O就可以完全载入。为了达到这个目的,在实际实现B-Tree还需要使用如下技巧:每次新建节点时,直接申请一个页的空间,这样就保证一个节点物理上也存储在一个页里,加之计算机存储分配都是按页对齐的,就实现了一个node只需一次I/O。
索引模块
密集索引和稀疏索引的区别
密集索引文件中的每个搜索码值都对应一个索引值
稀疏索引文件只为索引玛的某些值建立索引项
InnoDB
若一个主键被定义,该主键则作为密集索引
若没有主键被定义,该表的第一个唯一非空索引则作为密集索引
若不满足以上条件,innodb内部会生成一个隐藏主键(密集索引)
非主键索引存储相关键位和其对应的主键值,包含两次查找
索引衍生出来的问题,以mysql为例
如何定位并优化慢查询Sql
1.根据慢日志定位慢查询sql
2.使用explain等工具分析sql
3.修改sql或者尽量走sql走索引
联合索引的最左匹配原则的成因
xxx不会
索引是建立得越多越好吗
数据量小的表不需要建立索引,建立会增加额外的索引开销
数据变更需要维护索引,因此更多的索引意味着更多的维护成本
更多的索引意味着也需要更多的空间
锁模块
MyISAM与InnoDB关于锁方面的区别是什么
MyISAM默认用的是表级锁,不支持行级锁
InnoDB默认用的是行级锁,也支持表级锁
数据库事务的四大特性
事务隔离级别以及各级别下的并发访问问题
InnoDB可重复读隔离级别下如何避免幻读
RC、RR级别下的InnoDB的非阻塞读如何实现
数据库锁的分类
按锁的粒度划分,可分为表级锁、行级锁、页级锁
按锁级别划分,可分为共享锁、排它锁
按加锁方式划分,可分为自动锁、显示锁
按操作划分,可分为DML锁,DDL锁
按使用方式划分,可分为乐观锁、悲观锁
数据库事务四大特性
ACID
-----------------------------------------------------------------
关键语法
group by
having
count sum max min avg