事务的概念来自于两个独立的需求:并发数据库访问,系统错误恢复。数据库
一个事务是能够被看做一个单元的一系列SQL语句的集合。并发
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数据类型的列不该该增长索引。这是由于,这些列的数据量要么至关大,要么取值不多。
当修改性能远远大于检索性能时,不该该建立索引,由于修改性能和检索性能是矛盾的。
建立索引的方法:直接建立和间接建立(在表中定义主键约束或者惟一性约束时,同时也建立了索引)。
索引的特征:
惟一性索引保证在索引列中的所有数据是惟一的,不会包含冗余数据。
复合索引就是一个索引建立在两个列或者多个列上。能够减小在一个表中所建立的索引数量。