数据库基础知识
事务的特性
事务具备4个特性:原子性、一致性、隔离性和持久性。
其中,原子性即Atomicity,一致性即Consistency,隔离性即Isolation,持久性即Durability,
所以这四个特性也简称为ACID特性。
原子性
一致性
隔离性
持久性
事务的隔离级别
事务的四种隔离级别
未提交读(Read uncommitted)
已提交读(Read committed)
可重复读(Repeatable read)
可串行化(Serializable )
未提交读(Read Uncommitted):允许脏读,也就是可能读取到其他会话中未提交事务修改的数据
提交读(Read Committed):只能读取到已经提交的数据。Oracle等多数数据库默认都是该级别 (不重复读)
可重复读(Repeated Read):可重复读。在同一个事务内的查询都是事务开始时刻一致的,InnoDB默认级别。在SQL标准中,该隔离级别消除了不可重复读,但是还存在幻象读
串行读(Serializable):完全串行化的读,每次读都需要获得表级共享锁,读写相互都会阻塞
Read Uncommitted这种级别,数据库一般都不会用,而且任何操作都不会加锁,这里就不讨论了。
在数据库操作中,为了有效保证并发读取数据的正确性,提出的事务隔离级别。我们的数据库锁,也是为了构建这些隔离级别存在的。
MySQL中锁的种类
MySQL中锁的种类很多,有常见的表锁和行锁,也有新加入的Metadata Lock等等,表锁是对一整张表加锁,虽然可分为读锁和写锁,但毕竟是锁住整张表,会导致并发能力下降,一般是做ddl处理时使用。
行锁则是锁住数据行,这种加锁方法比较复杂,但是由于只锁住有限的数据,对于其它数据不加限制,所以并发能力强,MySQL一般都是用行锁来处理并发事务。这里主要讨论的也就是行锁。
悲观锁和乐观锁
悲观锁
正如其名,它指的是对数据被外界(包括本系统当前的其他事务,以及来自外部系统的事务处理)修改持保守态度,因此,在整个数据处理过程中,将数据处于锁定状态。悲观锁的实现,往往依靠数据库提供的锁机制(也只有数据库层提供的锁机制才能真正保证数据访问的排他性,否则,即使在本系统中实现了加锁机制,也无法保证外部系统不会修改数据)。
在悲观锁的情况下,为了保证事务的隔离性,就需要一致性锁定读。读取数据时给加锁,其它事务无法修改这些数据。修改删除数据时也要加锁,其它事务无法读取这些数据。
乐观锁
相对悲观锁而言,乐观锁机制采取了更加宽松的加锁机制。悲观锁大多数情况下依靠数据库的锁机制实现,以保证操作最大程度的独占性。但随之而来的就是数据库性能的大量开销,特别是对长事务而言,这样的开销往往无法承受。
而乐观锁机制在一定程度上解决了这个问题。乐观锁,大多是基于数据版本( Version )记录机制实现。何谓数据版本?即为数据增加一个版本标识,在基于数据库表的版本解决方案中,一般是通过为数据库表增加一个 “version” 字段来实现。读取出数据时,将此版本号一同读出,之后更新时,对此版本号加一。此时,将提交数据的版本数据与数据库表对应记录的当前版本信息进行比对,如果提交的数据版本号大于数据库表当前版本号,则予以更新,否则认为是过期数据。
数据库
Mysql存储引擎中索引的实现机制
倒序索引
为了更好的建立被搜索的关键字和含有这些关键字的页面之间的映射关系,倒序索引产生了。简单的说,倒序索引的倒序,指的是这个索引是从关键词中查找对应的源的,而不是从源中检索对应的关键词。
举例如下:为了检索关键词 A,首先从倒序索引的索引表中,找到关键词 A,然后查找 A 所在的页。由于倒序索引表排序后,在其中查找一个关键词可以使用二分查找,特别是在采用分布式数据、服务器集群、多线程技术等条件下,效率极高,所以,查找含有某个关键词的页变得非常简单。
假设数据库中含有1000000条记录,其中有 10 条记录符合搜寻条件,如果使用倒序索引,可以很快找到这些关键词,并且定位到含有这些关键词的十条记录;否则,需要遍历1000000条记录,效率的差异可想而知。
所以,倒序索引相当于一本出处大字典,查阅其中的每个词汇,都可以告诉你它的所有出处。