面经总结:数据库
-
事务的四个特性?
四大特性是:ACID 原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)+介绍四个特性概念;
原子性:整个事务中的所有操作,要么全部完成,要么全部不完成,不可能停滞在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。
一致性:在事务开始之前和事务结束以后,数据库的完整性约束没有被破坏。
隔离性:当两个或者多个事务并发访问(此处访问指查询和修改的操作)数据库的同一数据时所表现出的互相关系。事务隔离分为不同的级别,包括读未提交(Read uncommitted)、读提交(Read committed)、可重复读(Repeatable read)和串行化(Serializable)。隔离状态执行事务,使它们好像是系统在给定时间内执行的唯一操作。如果有两个事务,运行在相同的时间内,执行 相同的功能,事务的隔离性将确保每一事务在系统中认为只有该事务在使用系统。这种属性有时称为串行化,为了防止事务操作间的混淆,必须串行化或序列化请求,使得在同一时间仅有一个请求用于同一数据。
持久性:在事务完成以后,该事务对数据库所作的更改便持久的保存在数据库之中,并不会被回滚。
-
事务的隔离级别
读未提交(Read uncommitted)、读已提交(Read committed)、可重复读(Repeatable read)和串行化(Serializable)
① Serializable (串行化):可避免脏读、不可重复读、幻读的发生。
SERIALIZABLE可以防止除更新丢失外所有的一致性问题,即:
1.语句无法读取其它事务已修改但未提交的记录。
2.在当前事务完成之前,其它事务不能修改目前事务已读取的记录。
3.在当前事务完成之前,其它事务所插入的新记录,其索引键值不能在当前事务的任何语句所读取的索引键范围中。
② Repeatable read (可重复读):可避免脏读、不可重复读的发生。
REPEATABLE READ事务不会产生脏读,并且在事务完成之前,任何其它事务都不能修改目前事务已读取的记录。其它事务仍可以插入新记录,但必须符合当前事务的搜索条件——这意味着当前事务重新查询记录时,会产生幻读(Phantom Read)。
③ Read committed (读已提交):可避免脏读的发生。
语句无法读取其它事务已修改但未提交的记录。
④ Read uncommitted (读未提交):最低级别,任何情况都无法保证。
-
四大冲突问题
1、脏读
某个事务读取的数据是另一个事务正在处理的数据。而另一个事务可能会回滚,造成第一个事务读取的数据是错误的。
2、不可重复读
在一个事务里两次读入数据,但另一个事务已经更改了第一个事务涉及到的数据,造成第一个事务读入旧数据。
3、幻读
幻读是指当事务不是独立执行时发生的一种现象。例如第一个事务对一个表中的数据进行了修改,这种修改涉及到表中的全部数据行。同时,第二个事务也修改这个表中的数据,这种修改是向表中插入一行新数据。那么,以后就会发生操作第一个事务的用户发现表中还有没有修改的数据行,就好象发生了幻觉一样。
4、更新丢失
多个事务同时读取某一数据,一个事务成功处理好了数据,被另一个事务写回原值,造成第一个事务更新丢失。
-
乐观锁和悲观锁?使用场景?
乐观锁:默认读数据的时候不会修改,所以不会上锁;
悲观锁:默认读数据的时候会修改,所以会上锁;
乐观锁适用于多读写比较少的情况,省去锁的开销,加大系统的吞吐量。
-
MySQL引擎的区别?
1).MyISAM是非事务安全型的,而InnoDB是事务安全型的。
2).MyISAM锁的粒度是表级,而InnoDB支持行级锁定。
3).MyISAM相对简单,所以在效率上要优于InnoDB,小型应用可以考虑使用MyISAM。
4).MyISAM管理非事务表。它提供高速存储和检索,以及全文搜索能力。如果应用中需要执行大量的SELECT查询,那么MyISAM是更好的选择。
5).InnoDB用于事务处理应用程序,具有众多特性,包括ACID事务支持。如果应用中需要执行大量的INSERT或UPDATE操作,则应该使用InnoDB,这样可以提高多用户并发操作的性能。由于锁的粒度更小,写操作不会锁定全表,所以在并发较高时,使用Innodb引擎会提升效率。
-
数据库索引有哪些类型?
普通索引、唯一索引、主键索引、组合索引;
普通索引:没有任何限制;
唯一索引:索引列的值必须唯一,但允许有空值;
主键索引:特殊的唯一索引,不允许有空值;一个表只能有一个主键;
组合索引:多个字段组合作为索引;
-
数据库索引原理?
索引:数据库索引,是数据库管理系统中一个排序的数据结构,以协助快速查询、更新数据库表中数据。索引的实现通常使用B树及其变种B+树。
在数据之外,数据库系统还维护着满足特定查找算法的数据结构,这些数据结构以某种方式引用(指向)数据,这样就可以在这些数据结构上实现高级查找算法。这种数据结构,就是索引。
-
B树和B+树原理?
动态查找树主要有:二叉查找树(Binary Search Tree),平衡二叉查找树(Balanced Binary Search Tree),红黑树(Red-Black Tree ),B-tree/B+-tree/ B*-tree (B~Tree)。前三者是典型的二叉查找树结构,其查找的时间复杂度O(log2N)与树的深度相关,那么降低树的深度自然会提高查找效率。
但是咱们有面对这样一个实际问题:就是大规模数据存储中,实现索引查询这样一个实际背景下,树节点存储的元素数量是有限的(如果元素数量非常多的话,查找就退化成节点内部的线性查找了),这样导致二叉查找树结构由于树的深度过大而造成磁盘I/O读写过于频繁,进而导致查询效率低下(为什么会出现这种情况,待会在外部存储器-磁盘中有所解释),那么如何减少树的深度(当然是不能减少查询的数据量),一个基本的想法就是:采用多叉树结构(由于树节点元素数量是有限的,自然该节点的子树数量也就是有限的)。
也就是说,因为磁盘的操作费时费资源,如果过于频繁的多次查找势必效率低下。那么如何提高效率,即如何避免磁盘过于频繁的多次查找呢?根据磁盘查找存取的次数往往由树的高度所决定,所以,只要我们通过某种较好的树结构减少树的结构尽量减少树的高度,那么是不是便能有效减少磁盘查找存取的次数呢?那这种有效的树结构是一种怎样的树呢?
这样我们就提出了一个新的查找树结构——多路查找树。根据平衡二叉树的启发,自然就想到平衡多路查找树结构,也就是这篇文章所要阐述的第一个主题B~tree,即B树结构(后面,我们将看到,B树的各种操作能使B树保持较低的高度,从而达到有效避免磁盘过于频繁的查找存取操作,从而有效提高查找效率)。
B树的特性:关键字分布在整棵树中;搜索性能等价于在关键字全集内做一次二分查找;
什么是B+树?
B+树是B树的变体,也是多路搜索树;B+树的特点是:
1)非叶子结点的子树指针P[i],指向关键字值属于[K[i], K[i+1])的子树(B-树是开区间)
2)所有关键字都在叶子结点出现;
3)所有的非叶子节点相当于是叶子节点的索引;
4)为所有叶子结点增加一个链指针;
B+的搜索与B树也基本相同,区别是B+树只有达到叶子结点才命中(B-树可以在非叶子结点命中),其性能也等价于在关键字全集做一次二分查找;
B+树和B+树的区别:
1.所有关键字都出现在叶子结点的链表中(稠密索引),且链表中的关键字恰好是有序的;
2.只会在叶子结点命中;
3.非叶子结点相当于是叶子结点的索引(稀疏索引),叶子结点相当于是存储(关键字)数据的数据层;
B+树相比B树的优点:
(1) B+树改进了B树, 让内结点只作索引使用, 去掉了其中指向data的指针, 使得每个结点中能够存放更多的key, 这样访问叶节点的数据的磁盘读写次数就更低;
(2) 由于底部的叶子结点是链表形式, 因此也可以实现更方便的顺序遍历, 而B树则需要对整个树的每一层遍历,需要更多的磁盘读写;
参考:索引、树
-
为什么用数据库连接池?
-
数据库连接池配置/驱动参数?如何防止失效?
url: 连接数据库的 URL
username: 登陆数据库所用的帐号
testOnReturn:返回对象时是否进行验证,检查对象是否有效,默认为false
-
数据库查询优化?
-
死锁产生的原因?必要条件?
产生死锁原因?
死锁:指多个进程因竞争共享资源而造成的一种僵局,若无外力作用,这些进程都将永远不能再向前推进。
1)竞争系统资源;2)进程推进顺序不当;
产生死锁必要条件?
(1) 互斥条件:一个资源每次只能被一个进程使用。
(2) 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。
(3) 不剥夺条件:进程已获得的资源,在末使用完之前,不能强行剥夺。
(4) 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。
-
死锁的避免?如何解决死锁?
避免死锁:资源有序分配(避免循环等待)、避免事务交互(减少持有资源的时间)、保持事务简短并处于一个批处理中(减少持有资源时间)
解决死锁?
剥夺资源:从其它进程剥夺足够数量的资源给死锁进程,以解除死锁状态;
撤消进程:可以直接撤消死锁进程或撤消代价最小的进程,直至有足够的资源可用,死锁状态消除为止;所谓代价是指优先级、运行代价、进程的重要性和价值等。
-
红黑树的实现?
红黑树本质是二叉搜索树,满足二叉搜索树的基本性质——即树中的任何节点的值大于它的左子节点,且小于它的右子节点。
红黑树节点的基本属性有:颜色、左子节点指针、右子节点指针、父节点指针、节点值;
一颗红黑树必须满足以下几点条件:
1)根节点必须是黑色。
2)父子节点之间不包含连续的红色节点。
3)任意节点到叶子的路径的黑色节点总数相同。
这些约束确保了红黑树的关键特性:对树的插入和删除操作时会维持树的平衡。从根到叶子的最长的可能路径不多于最短的可能路径的两倍长。结果是这个树大致上是平衡的。
因为操作比如插入、删除和查找某个值的最坏情况时间都要求与树的高度成比例,这个在高度上的理论上限允许红黑树在最坏情况下都是高效的,而不同于普通的二叉查找树。
RBTree的查找操作就是BST的查找操作,插入和删除操作时间复杂度是O(logN);
RBTree的旋转操作:
右旋:节点的左子树上升到父节点; 左旋:节点的右子树上升到父节点;
RBTree的插入操作:
RBTree的插入与BST的插入方式是一致的,只不过是在插入过后,可能会导致树的不平衡,这时就需要对树进行旋转操作和颜色修复(在这里简称插入修复),使得它符合RBTree的定义。
新插入的节点是红色的,插入修复操作如果遇到父节点的颜色为黑则修复操作结束。也就是说,只有在父节点为红色节点的时候是需要插入修复操作的。
插入修复操作分为以下的三种情况,而且新插入的节点的父节点都是红色的:
- 叔叔节点也为红色。
- 叔叔节点为空,且祖父节点、父节点和新节点处于一条斜线上。
- 叔叔节点为空,且祖父节点、父节点和新节点不处于一条斜线上。