JAVA面试核心知识点(二):数据库
二·数据库
2.1 数据库架构
考点思维导视
关系数据库:架构、索引、锁、语法、理论范式
如何设计一个关系性数据库:RDBMS
程序实例
存储管理,缓存机制,SQL解析,日志管理(beanLog),权限划分,容灾机制,索引管理,锁模块
存储(文件系统)
索引模块
为什么要使用索引
快速查询数据
什么样的信息能成为索引
主键、唯一键以及普通键
索引的数据结构
生成索引,建立二叉查找树进行二分查找
生成索引,建立B-Tree结构进行查找
生成索引,建立B+-Tree结构进行查找
生成索引,建立Hash结构进行查找
理论范式:
第一范式:数据库列具有原子性,不可再分割
第二范式:属性完全依赖于主键
第三范式:数据库表中不能含有另外一张表的非主属性字段
2.2 优化你的索引
二叉查找树 :二分查找法
查询效率 O(logn)
可能会成为线性导致查询效率降低为O(logn)
B-Tree 平衡多路查找树O(logn)
定义:
根节点至少包括两个孩子
树中每个节点最多包含m个孩子(m>=2)
除根节点和叶节点外,其他每个节点至少有ceil(m/2)个孩子
所有叶子节点都位于同一层
假设每个非终端节点包含有n个关键字信息,其中
a)Ki(i=1..n)为关键字,且关键字按顺序升序排序K(i-1)<>Ki
b)关键字得个数n必须满足:[ceil(m/2)-1]<=n<=m-1
c)非叶子节点得指针:P[1],p[2]..P[m];其中P[1]指向关键字小于K[1]得字数
P[M]指向关键字大于K[M-1]的子树,其他P[i]指向关键字属于(K[i-1],k[i])的子树
B+-Tree
非叶子节点的子树指针与关键字个数相同
非叶子节点的子树指针P[i],指向关键字值[K[i],K[i+1])的子树
非叶子节点仅用来索引,数据都保存在叶子节点中
所有叶子节点均有一个链指针指向下一个叶子结点
结论 B+Tree更适合来做数据存储
B+树的磁盘读写代价更低
B+树的查询效率更加稳定
B+树更有利于对数据库的扫描
运用Hash以及BitMap
Hash索引:
缺点:仅仅能满足 = IN ,不能使用范围查询
无法被用来避免数据的排序操作
不能利用部分索引键查询
不能避免表扫描
遇到大量Hash值相等的情况后性能不一定会比B-Tree索引高
BitMap 位图索引
高效统计
2.3 密集索引和稀疏索引的区别
密集索引和稀疏索引
密集索引文件中的每个搜索码值都对应一个索引值
稀疏索引文件只为索引码的某些值建立索引项
InnoDB 有且仅有一个密集索引
若一个主键被定义,该主键则作为密集索引
若没有主键被定义,该表的第一个唯一非空索引则作为密集索引
若不满足以上条件,innodb内部会生成一个隐藏主键(密集索引)
非主键索引存储相关键位和其对应的主键值,包含两次查找
MyISAM 稀疏索引
索引与数据分开存储
为什么要使用索引?
避免全表扫描,增加检索查询速度
什么样的信息能够成为索引?
主键,唯一键等
索引的数据结构?
B+-Tree,二叉树,B-Tree,Hash,BitMap(mysql不支持)
密集索引和稀疏索引的区别?
每个索引码对应一个索引值,只为某些索引码建立索引值
2.4 索引额外问题
如何定位并优化慢查询SQL?
具体场景具体分析,只提出大致思路
根据慢日志定位慢查询sql
使用explain等工具分析sql
修改sql或者尽量让sql走索引
show variables like '%quer%' 查看数据库慢查询
slow_quer_log 打开关机慢查询记录
slow_query_log_file 慢日志存储地址
long_quer_time 超过这个时间才会记录
explain + 查询语句。分析查询语句执行过程
type:mysql找的数据行的方式 range>index>all
index和all代表全表扫描,需要优化
extra:Using filesort 表示mysql会对结果使用一个外部排序,而不是按照表里索引次序读到相关内容。Using temporary 标识mysql在对查询结构排序时使用临时表
windows: my.ini 永久保存
show status like '%slow_queries%' 查看慢sql数量
alter table table_name add index idx_name(xxx);
联合索引的最左匹配原则的成因?
最左匹配原则,mysql会一直响右匹配知道遇到范围查询(>,<,between,like)就停止匹配,比如a=3 and b=4 and c > 5 and d = 6如果建立(a,b,c,d)顺序的索引,d使用不到索引的,如果建立(a,b,d,c)索引则都可以用到,a,b,d的顺序可以任意调整。其中=和in可以乱序,比如a=1 and b=2 and c=3建立(a,b,c)索引可以任意顺序。
2.5 锁模块之MyISAM与InooDB关于锁方面的区别
MyISAM与InnoDB关于锁方面的区别是什么
MyISAM默认用表级锁,不支持行级锁
InnoDB默认用表级锁,也支持行级锁
读锁也叫共享锁,写锁也叫排它锁
读锁可以加读锁不可加写锁
写锁不可加读锁也不可加写锁
mysql的事务默认为自动提交
MyISAM适合场景:
频繁执行全表count语句
对数据进行增删改的频率不高,查询非常频繁
没有事务
InnoDB适合场景:
数据增删改查都相当频繁
可靠性比较高,要求支持事务
数据库锁的分类
按照锁的粒度划分,可分为表级锁,行级锁,页级锁
按所级别划分,可分为共享锁,排它锁
按照枷锁方式划分,可分为自动锁,显式锁
按照操作划分,可分为DML锁,DDL锁
按使用方式划分,可分为乐观锁(认为数据一般情况下不会造成冲突),悲观锁(对数据被外界修改持保守态度)
实现乐观锁的方式,记录数据版本,实现数据版本,获取版本号或者记录时间戳
数据库事务的四大特性(ACID)
原子性,一致性,隔离性,持久性
事务隔离级别以及各级别下的并发访问问题
第一种隔离级别:Read uncommitted(读未提交)解决了更新丢失,但还是可能会出现脏读
第二种隔离级别:Read committed(读提交)解决了更新丢失和脏读问题
第三种隔离级别:Repeatable read(可重复读取)解决了更新丢失、脏读、不可重复读、但是还会出现幻读
第四种隔离级别:Serializable(可序化)解决了更新丢失、脏读、不可重复读、幻读(虚读)
事务并发访问引起的问题以及如何避免
更新丢失---mysql所有事务与隔离级别在数据库层面上均可避免
脏读(read-uncommitted发生)---READ-COMMITTED事务隔离级别以上可避免
不可重复读---REPEATABLE-READ事务隔离级别以上可避免
幻读---SERIALIZABLE事务隔离级别可避免
InnoDB可重复读隔离级别下如何避免幻读
表象:快照读(非阻塞读)--伪MVCC
内在:next-key锁(行锁+gap锁)
当前读:加了锁的增删改查语句
快照读:不加锁的非阻塞读
2.6 关键语法
group by
满足select子句中的列名必须为分组列或列函数(如果用group by,那么你的Select语句中选出的列要么是你groupby里用到的列,要么就是带有SUM MIN等函数的列)
列函数对于group by子句定义的每个组返回一个结果
having
通常与GROUP BY子句一起使用
where过滤行,having过滤组
出现在同一sql的顺序,WHERE>GROUP BY>HAVING
统计相关:count,sum,max,min,avg