JAVA面试之数据库篇
1.什么是存储过程?优缺点?
类似编程语言中函数一样的东西,封装我们的代码
优点:*代码封装
*保存在数据库中
*让编程语言调用
*预编译代码块,执行效率高
*可以替代大量sql语句,降低网络通信量,提高通信速率
缺点:*每个数据库的存储过程语法都不一样,难以维护,不通用
*业务逻辑放在数据库上,难以迭代
2.数据库设计范式
1)第一范式:属性不可再拆分(原子性)
2)第二范式:消除非主属性对码的函数依赖
就是对记录的唯一性有要求,即实体的唯一性,不存在部分依赖,每一列都与主键相关
应该做如下改进:
3)第三范式:消除非主属性对码的传递函数依赖
就是任何字段不能由其他字段推导派生出来
学号可以推导出学院,而学院又可以推导出学院电话,所以学号和学院电话存在传递函数依赖,应该做如下改进
3.数据库索引
什么是索引?
索引是对数据库表中一个或多个值进行排序的数据结构,以协助快速查询,更新数据库表中的数据
通俗理解:索引就是加快检索数据库表中数据的方法,数据库的索引类似于书的索引,在书中,索引允许用户不必翻遍整个书就能找到需要的信息,在数据库中,索引也允许数据库程序能快速找到表中数据,而不必扫描整个数据库
索引的底层数据结构是什么?
1.底层数据结构是B+树
在数据结构中,我们最常见的搜索结构就是二叉搜索树和ALV树(高度平衡的二叉搜索树,为了提高二叉搜索树的效率,减少树的平均搜索长度),然而无论是二叉搜索树还是ALV树,当数据量比较大时,都会由于树的深度过大而造成IO读写过于频繁,进而导致查询效率低下,因此对于搜索来说,多叉树结构成为不二选择,特别的,B树的各种操作能使得B树保持较低的高度,从而保证查找的效率
2.讲讲B树和B+树,为什么索引要使用B+树呢?
B树
B树的特点:m阶的B树
1)根结点至少有两个子女
2)每个非根结点至少有[m/2]个孩子,最多有m个孩子
3)每个非根结点至少有[m/2]-1个关键字,最多有m-1个关键字
4)结点的关键字都是升序排序的,方便二分查找
5)所有叶子结点都在同一层
6)如果一个结点有n-1个关键字,那么它有n个分支
7)每个结点的结构:结点个数,关键字数组,孩子指针数组
B树的高度与复杂度:
B树的高度是,而不是其它几种树的H=log2n,其中T为度数(每个节点包含的元素个数),即所谓的阶数,n为总元素个数或总关键字数。
B树查找的时间复杂度为O(Log2-N),下面是参考推导过程:
其中M为设定的非叶子结点最多子树个数,N为关键字总数;所以B-树的性能总是等价于二分查找(与M值无关),也就没有AVL树平衡的问题。
3.索引的分类,优缺点,什么字段适合创建索引以及创建索引需要注意什么?
索引的分类:
1)唯一索引:不允许两行具有相同索引值,允许空
2)主键索引:定义主键会自动创建主键索引,主键索引是唯一索引的特殊类型,主键索引要求主键中的值唯一且不空
3)聚集索引
聚集索引中键值的逻辑顺序决定了表中相应行的物理顺序,聚集索引确定表中的物理顺序,聚集索引类似于电话簿,电话簿按照姓氏排列数据,由于聚集索引规定表中存储的物理顺序,因此一张表只能有一个聚集索引,但该索引可以包含多个列,就像电话簿按照姓氏和名字进行组织一样,
聚集索引对于那些经常要搜索范围值的列特别有效,使用聚集索引找到包含第一个值的行后,便可以确保包含后续索引值的行在物理相邻,例如应用程序执行的一个查询经常检索某一日期范围内的记录,则使用聚集索引可以迅速找到包含开始日期的行,直到到达日期结束,这样有助于提高此类查询的性能,同样,如果对表中检索的数据进行排序时经常要用到某一列,则可以将该表在该列上聚集(物理顺序),避免每次查询该列时都进行排序,从而提高效率
当索引值唯一时,使用聚集索引查找特定的行也很有效率,例如学生ID查找学生最快速的方法就是在ID列上创建主键或者聚集索引
4)非聚集索引
非聚集索引必须先在目录中查到每一页数据对应的页面,然后根据页码查到具体内容,该索引中索引的逻辑顺序与磁盘上行的物理存储顺序不同,非聚集索引一张表可以创建多个
优点:
1)大大加快数据检索速度:B+树啊
2)加速表和表之间的连接:扫描表的整个索引需要的时间远小于扫描整个表需要的时间
3)通过创建唯一索引,可以保证表中每一行数据的唯一性
4)在使用分组和排序子句进行检索时,同样可以显著减少查询中分组和排序时间,原因同2
5)通过使用索引,可以在查询过程中,使用优化隐藏器,提高系统性能:原因未知
缺点:
1)时间方面:创建和维护索引需要耗费时间,比如对表中数据进行增删改的时候,索引也需要动态维护
2)空间方面:索引需要占用物理空间
什么字段适合创建索引?
1)经常做查询的字段
2)经常做表连接的字段
3)经常出现在order by,group by,distinct(过滤重复的)后面的字段
创建索引需要注意什么?
1)非空字段,因为非空字段很难进行优化,可以用0或者特殊值代替空
2)取离散值大的字段:离散值大就是各个变量之间的差异大,唯一字段多
3)索引字段越小越好:数据库的存储以页为单位,一页存储的数据越多,一次I/O操作获得目标数据的概率越大,效率越高
事物的定义,特性,
事物的并发问题有哪几种?
事物隔离的级别有哪几种?
事物的定义:一系列操作的集合,这些操作要么都执行,要么都不执行
事物的四种特性(ACID特性):
1)原子性(Atomicity)
当事物结束,它对所有资源状态的改变都被视为一个操作,这些操作要么都执行,要么都不执行
2)一致性(Consistency)
事物把系统从一个一致状态转变为另外一个一致状态,即事物完成后,所有数据必须符合业务规范
3)隔离性(Isolation)
多个事物并发执行时,一个事物的执行不应该影响其他事物的执行,即事物以相互隔离的方式执行,事物以外的实体无法知道事物过程的中间状态,防止数据损坏
4)持久性(Durable)
事物提交以后,事物必须以一种持久性方式存储起来,一旦事物完成,无论发生什么系统错误,它的结果都不应该受到影响,这样就能从任何系统崩溃中恢复过来,通常情况下,事物结果被写到持久化存储器中
事物的并发可能会导致的问题:
1)丢失更新:一个事物的更新覆盖了另外一个事物的更新
2)脏读:一个事物读取了另外一个事物改写但是未提交的数据
3)不可重复读:不可重复读的重点是修改,同样条件下两次读取结果不同,也就是说,被读取的数据可以被其他事物修改,也就是两次查询期间数据被其他事物修改了
4)幻读:幻读的重点在于新增或删除,同样条件下读取出的记录数不一样,发现新增或者减少了一些记录
事物隔离的级别有哪几种?
隔离级别一个session中的事物可能对另外一个session中的事物的影响,有4个隔离级别:
1)读未提交:最低级别,允许一个事物读取另外一个事物还未提交的数据,可提高性能,但存在脏读问题
2)读已提交:在一个事物中只允许其他事物对其已经提交的记录可见,不能避免不可重复读问题
3)可重复读:在一个事物开始后,其他事物对数据库的修改在本事物中不可见,直到本事物提交或者回滚,但是其他事物的insert/delete操作对该事物是可见的,也就是说不能避免幻读问题,在一个事物中select结果一样,除非本事物中update数据库
4)序列化:最高级别隔离,只允许事物串行执行
Mysql的默认隔离级别是可重复读
什么是视图?以及视图的使用场景有哪些?
视图的定义:
视图是一种虚拟的表,具有和物理表相同的功能,可以对视图进行增删改查,视图通常是有一个表或者多个表的行或列的子集,dui视图的修改不影响基本表,相对多表查询,使得我们获取数据更加容易
视图的使用场景:
1)不希望访问者获取整个表的信息,值暴露部分字段给访问者,所以建一个虚拟表,也就是视图
2)查询数据来源于不同的表,而查询者希望以统一的方式查询,这样可以建立一个视图,把多个表的查询结果联合起来,查询者只需要从视图中获取数据,不必考虑数据来源于不同的表带来的差异
drop,delete,truncate各自的区别?
drop:直接删除整张表
1)属于DDL,数据定义语言
2)不可回滚
3)删除速度快,表内容和结构都删除了
4)不可带where,直接带表名
delete:删除某些行
1)属于DML,数据操作语言
2)可回滚
3)可带where(删除条件)
4)表结构在,表内容where后面的条件
5)删除速度慢,需要逐行删除
truncate:清空表中所有数据
1)属于DDL,数据定义语言
2)不可回滚
3)表内容和结构删除,实质是删除整张表包括数据和表结构,然和重建表结构
4)删除速度快
DDL和DML的区别就是DDL会自动提交,而DML不会
触发器的作用?
触发器是与表相关的数据库对象,在满足定义条件时触发,并执行触发器中定义的语句集合,触发器这种特性可以协助应用在数据库端保持数据库的完整性
数据库的乐观锁和悲观锁是什么?
数据库管理系统DBMS中并发控制的任务是确保在多个事物同时存取数据库中同一数据时不破坏事物的隔离性和统一性以及数据库的统一性
悲观锁:假定会发生冲突,屏蔽一切可能违反数据完整性的操作
就是对更新的数据加锁,这个并发期间一个事物获取了该锁,其他事物也就不能获取该锁
优缺点:悲观锁是先取锁再访问的保守策略,虽然为数据安全提供了保证,但是开销大,还有可能产生死锁,而且读的时候是没有冲突的,没必要使用锁,这样效率更低了,降低了并行性,
乐观锁:假设不会发生并发冲突,只在提交操作时检查是否违反数据的完整性
乐观锁是一种不会阻塞的并发控制,不会引起线程频繁的挂起和恢复,这样系统开销小
实现方式就是采用CAS机制,采取版本号或者时间戳的方式解决ABA问题
优缺点:优点是不会产生任何锁和死锁,但是直接这么做会造成不可预期的后果,比如两个事物都读取了某一行,经过修改以后写回数据库,这时就遇到了问题
超键,候选键,主键,外键分别是什么?
假设这样一张表:学号,姓名,性别,年龄,系别,专业
1)超键:含有学号或者身份证号的任意组合都是超键
2)候选键:不存在多余属性的超键
3)主键:候选键中的一个,唯一标识元组
4)外键:其他表中的键,比如老师id
sql约束有哪几种?
1)not null:不空约束
2)unique:唯一约束
3)主键约束
4)外键约束
5)check:字段范围约束
char和varchar的区别以及性能分析
char:固定长度
varchar:可变长度
定义一个char[10]和varchar[10],如果存进去的是 'test',那么char所占的长度依然为10,除了字符 'test' 外,后面跟六个空格,varchar就立马把长度变为4了,取数据的时候,char类型的要用trim()去掉多余的空格,而varchar是不需要的
1.存取速度与空间效率方面
char的存取速度快得多,但是这是以牺牲空间为代价的
varchar存取速度就慢一点,但是空间效率高
2.储存方式上
char:英文字符一个字节,汉字两个字节
varchar:都是两个字节
数据库的优化方式?
1)sql语句优化
*优化insert语句:一次插入多值
*避免在where子句中使用>=或者!=,否则引擎将放弃使用索引而进行全局扫描
*避免在where子句中进行null判断,否则引擎将放弃使用索引而进行全局扫描
*优化嵌套查询:子查询可以被更有效率的join连接代替
*用exists代替in
*避免select中使用*
2)索引优化
在经常做查询,进程做表连接的字段以及经常出现在order by,group by,distinct后面的字段建立索引
3)数据库表结构优化
*合适的数据类型
*应该遵循三大范式
*表的垂直拆分:把含有多个列的表拆分成多个表(过胖),解决表宽度问题,具体包括以下几种拆分手段:
不常用字段单独放一个表
大字段独立放一个表
经常使用的字段放一起
垂直拆分的好处:拆分后业务清晰,系统整合扩展任意,数据维护简单
*表的水平拆分:解决表中数据过多问题(过高),水平拆分的每一个表的结构都是一样的,具体操作:
对Id进行hash计算,如果要存到5个表里面,将hash值模5,得到0~4的结果,存到不同表lim
水平拆分的好处:降低了在查询时需要读的数据和索引的页数,降低了索引层数,把数据放到多个库中,提高系统总体可用性(分库,鸡蛋不能放在同一个篮子里)
4)配置系统的优化
操作系统配置的优化:增加TCP支持的队列数
mysql配置文件优化:缓存池大小和个数设置
5)硬件优化
多核心高主频的cpu
大的内存
高性能的磁盘