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
原文地址:https://www.cnblogs.com/technical-life/p/14606449.html