数据库面试题型

事务处理

  • 事务的概念来自于两个独立的需求:并发数据库访问系统错误恢复数据库

  • 一个事务是能够被看做一个单元的一系列SQL语句的集合。并发

事务的特性(ACID)

  • atomacity 原子性 :事务必须是原子工做单元;对于其数据修改,要么全都执行,要么全都不执行。一般,与某个事务关联的操做具备共同的目标,而且是相互依赖的。若是系统只执行这些操做的一个子集,则可能会破坏事务的整体目标。原子性消除了系统处理操做子集的可能性。性能

  • consistency 一致性事务将数据库从一种一致状态转变为下一种一致状态。也就是说,事务在完成时,必须使全部的数据都保持一致状态(各类 constraint 不被破坏)。优化

  • isolation 隔离性由并发事务所做的修改必须与任何其它并发事务所做的修改隔离。事务查看数据时数据所处的状态,要么是另外一并发事务修改它以前的状态,要么是另外一事务修改它以后的状态,事务不会查看中间状态的数据。换句话说,一个事务的影响在该事务提交前对其余事务都不可见。atom

  • durability 持久性事务完成以后,它对于系统的影响是永久性的。该修改即便出现致命的系统故障也将一直保持。排序

事务的隔离级别

若是不对数据库进行并发控制,可能会产生异常状况:索引

脏读(Dirty Read)事务

  • 当一个事务读取另外一个事务还没有提交的修改时,产生脏读。ci

  • 一个事务开始读取了某行数据,可是另一个事务已经更新了此数据但没有可以及时提交。这是至关危险的,由于极可能全部的操做都被回滚,也就是说读取出的数据实际上是错误的。资源

非重复读(Nonrepeatable Read)

  • 一个事务对同一行数据重复读取两次,可是却获得了不一样的结果。同一查询在同一事务中屡次进行,因为其余提交事务所作的修改或删除,每次返回不一样的结果集,此时发生非重复读。

幻像读(Phantom Reads)

  • 事务在操做过程当中进行两次查询,第二次查询的结果包含了第一次查询中未出现的数据(这里并不要求两次查询的SQL语句相同)。这是由于在两次查询过程当中有另一个事务插入数据形成的。

  • 当对某行执行插入或删除操做,而该行属于某个事务正在读取的行的范围时,会发生幻像读问题。

丢失修改(Lost Update)

  • 第一类:当两个事务更新相同的数据源,若是第一个事务被提交,第二个却被撤销,那么连同第一个事务作的更新也被撤销。

  • 第二类:有两个并发事务同时读取同一行数据,而后其中一个对它进行修改提交,而另外一个也进行了修改提交。这就会形成第一次写操做失效。

为了兼顾并发效率和异常控制,在标准SQL规范中,定义了4个事务隔离级别,( Oracle 和 SQL Server 对标准隔离级别有不一样的实现 )

未提交读(Read Uncommitted)

  • 直译就是读未提交,意思就是即便一个更新语句没有提交,可是别的事务能够读到这个改变。

  • Read Uncommitted容许脏读。

已提交读(Read Committed)

  • 直译就是读提交,意思就是语句提交之后,即执行了 Commit之后别的事务就能读到这个改变,只能读取到已经提交的数据。Oracle等多数数据库默认都是该级别。

  • Read Commited 不容许脏读,但会出现非重复读。

可重复读(Repeatable Read):

  • 直译就是能够重复读,这是说在同一个事务里面前后执行同一个查询语句的时候,获得的结果是同样的。

  • Repeatable Read 不容许脏读,不容许非重复读,可是会出现幻象读。

串行读(Serializable)

  • 直译就是序列化,意思是说这个事务执行的时候不容许别的事务并发执行。彻底串行化的读,每次读都须要得到表级共享锁,读写相互都会阻塞。

  • Serializable 不容许不一致现象的出现。

事务隔离的实现——锁

共享锁(S锁)

  • 用于只读操做(SELECT),锁定共享的资源。共享锁不会阻止其余用户读,可是阻止其余的用户写和修改。

更新锁(U锁)

  • 用于可更新的资源中。防止当多个会话在读取、锁定以及随后可能进行的资源更新时发生常见形式的死锁。

独占锁(X锁,也叫排他锁)

  • 一次只能有一个独占锁用在一个资源上,而且阻止其余全部的锁包括共享缩。写是独占锁,能够有效的防止“脏读”。

Read Uncommited 若是一个事务已经开始写数据,则另一个数据则不容许同时进行写操做,但容许其余事务读此行数据。该隔离级别能够经过“排他写锁”实现。

Read Committed 读取数据的事务容许其余事务继续访问该行数据,可是未提交的写事务将会禁止其余事务访问该行。能够经过“瞬间共享读锁”和“排他写锁”实现。

Repeatable Read 读取数据的事务将会禁止写事务(但容许读事务),写事务则禁止任何其余事务。能够经过“共享读锁”和“排他写锁”实现。

Serializable 读加共享锁,写加排他锁,读写互斥。

索引

数据库建立索引可以大大提升系统的性能。

  • 经过建立惟一性的索引,能够保证数据库表中每一行数据的惟一性。

  • 能够大大加快数据的检索速度,这也是建立索引的最主要的缘由。

  • 能够加速表和表之间的链接,特别是在实现数据的参考完整性方面特别有意义。

  • 在使用分组和排序子句进行数据检索时,一样能够显著的减小查询中分组和排序的时间。

  • 经过使用索引,能够在查询的过程当中,使用优化隐藏器,提升系统的性能。

增长索引也有许多不利的方面。

  • 建立索引和维护索引须要消耗时间,这种时间随着数量的增长而增长。

  • 索引须要占物理空间,除了数据表占据数据空间以外,每个索引还要占必定的物理空间,若是要创建聚簇索引,那么须要额空间就会更大。

  • 当对表中的数据进行增长,删除和修改的时候,索引也要动态的维护,这样就下降了数据的维护速度。

应该对以下的列创建索引

  • 在做为主键的列上,强制该列的惟一性和组织表中数据的排列结构。

  • 在常常用在链接的列上,这些列主要是一些外键,能够加快链接的速度。

  • 在常常须要根据范围进行搜索的列上建立索引,由于索引已经排序,其指定的范围是连续的。

  • 在常常须要排序的列上建立索引,由于索引已经排序,这样查询能够利用索引的排序,加快排序查询时间。

  • 在常用在where子句中的列上面建立索引,加快条件的判断速度。

有些列不该该建立索引

  • 在查询中不多使用或者做为参考的列不该该建立索引。

  • 对于那些只有不多数据值的列也不该该增长索引(好比性别,结果集的数据行占了表中数据行的很大比例,即须要在表中搜索的数据行的比例很大。增长索引,并不能明显加快检索速度)。

  • 对于那些定义为text,image和bit数据类型的列不该该增长索引。这是由于,这些列的数据量要么至关大,要么取值不多。

  • 当修改性能远远大于检索性能时,不该该建立索引,由于修改性能和检索性能是矛盾的。

建立索引的方法:直接建立和间接建立(在表中定义主键约束或者惟一性约束时,同时也建立了索引)。

索引的特征:

  • 惟一性索引保证在索引列中的所有数据是惟一的,不会包含冗余数据。

  • 复合索引就是一个索引建立在两个列或者多个列上。能够减小在一个表中所建立的索引数量。

相关文章
相关标签/搜索