一、事务

事务:由一系列对系统中数据进行访问与更新的操作所组成的一个程序执行逻辑单元,狭义上的事务特质数据库事务。

ACID:事务的四个特征,原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)

  1. 原子性:全部执行或全部不执行
  2. 一致性:事务的执行不能破坏数据库数据的完整性和一致性,一个事务在执行之前和执行之后,数据库偶读必须处于一致性状态
  3. 隔离性:并发的事务互相隔离,一个事务的执行不能被其他事务干扰。
  4. 持久性:指一个事务一旦提交,它对数据库中对应数据的状态变更就是永久性的。即使发生系统崩溃或机器宕机等故障,只要数据库能够重新启动,那么一定能够将其恢复到事务成功结束时的状态。

事务的隔离级别:

  1. 读未提交(未授权读取):允许脏读,隔离级别最低。换句话说,如果一个事务正在处理某一数据,并对其进行了更新,但同时尚未完成事务,因此还没有进行事务提交;而与此同时,允许另一个事务也能够访问该数据。
  2. 授权读取(读已提交):只允许读已经被提交的数据。
  3. 可重复读:在事务处理过程中,多次读取同一个数据时,其值都和事务开始时刻是一致的。因此该级别禁止了不可重复读取和脏读。可能出现幻读。
  4. 串行化:最严格。要求所有事务都被穿行执行。

幻读,并不是说两次读取获取的结果集不同,幻读侧重的方面是某一次的 select操作得到的结果所表征的数据状态无法支撑后续的业务操作。更为具体一些:select 某记录是否存在,不存在,准备插入此记录,但执行 insert 时发现此记录已存在,无法插入,此时就发生了幻读。

Redo、Undo日志

redo log 是重做日志,提供前滚操作;undo log 是回退日志,提供回滚操作。

  1. redo log 通常是 物理 日志,记录的是 数据页 的物理修改,而不是某一行或某几行修改成怎样怎样,它用来恢复提交后的物理数据页(恢复数据页,且只能恢复到最后一次提交的位置)。
  2. undo log 用来回滚行记录到某个版本。undo log 一般是逻辑日志,根据每行记录进行记录。

二、MySQL存储引擎

  • MyISAM 不支持事务,InnoDB 是事务类型的存储引擎;
  • MyISAM 只支持表级锁,BDB 支持页级锁和表级锁,默认为页级锁;而 InnoDB 支持行级锁和表级锁,默认为行级锁;
  • MyISAM 引擎不支持外键,InnoDB 支持外键;
  • MyISAM 引擎的表在大量高并发的读写下会经常出现表损坏的情况;
  • 对于 count( ) 查询来说 MyISAM 更有优势;
  • InnoDB 是为处理巨大数据量时的最大性能设计,它的 CPU 效率可能是任何其它基于磁盘的关系数据库引擎所不能匹敌的;
  • MyISAM 支持全文索引(FULLTEXT),InnoDB 不支持;
  • MyISAM 引擎的表的查询、更新、插入的效率要比 InnoDB 高。

最主要的区别是:MyISAM 表不支持事务、不支持行级锁、不支持外键。 InnoDB 表支持事务、支持行级锁、支持外键。(可直接回答这个)

三、三大范式

  1. 第一范式 原子性,属性不可再分
  2. 第二范式 主键,非主属性需完全依赖于主键(消除部分依赖,去掉联合主键)
  3. 第三范式 属性不依赖于其它非主属性(消除传递依赖)

四、集合运算

Union和UnionAll的区别

  1. Union:对两个结果集进行并集操作,不包括重复行,同时进行默认规则的排序;
  2. Union All:对两个结果集进行并集操作,包括重复行,不进行排序;

五、连接运算

  1. left join(左联接) 返回包括左表中的所有记录和右表中联结字段相等的记录
  2. right join(右联接) 返回包括右表中的所有记录和左表中联结字段相等的记录
  3. inner join(等值连接) 只返回两个表中联结字段相等的行

六、索引

索引是数据库中非常非常重要的概念,它是存储引擎能够快速定位记录的秘密武器,对于提升数据库的性能、减轻数据库服务器的负担有着非常重要的作用;索引优化是对查询性能优化的最有效手段,它能够轻松地将查询的性能提高几个数量级。

Innodb存储引擎在绝大多数情况下使用B+树简历索引,但是B+树索引并不能找到一个给定键对应的具体值,它只能找到数据行对应的页,然后把整个页读进内存,并在内存中查找具体的数据行。

聚集索引和辅助索引

数据库中的 B+ 树索引可以分为聚集索引(clustered index)和辅助索引(secondary index),它们之间的最大区别就是,聚集索引中存放着一条行记录的全部信息,而辅助索引中只包含索引列和一个用于查找对应行记录的『书签』

聚集索引

  1. InnoDB 存储引擎中的表都是使用索引组织的,也就是按照键的顺序存放;聚集索引就是按照表中主键的顺序构建一颗 B+ 树,并在叶节点中存放表中的行记录数据。
  2. 一般默认B+ 树会使用表的 id(主键)作为聚集索引的键,并在叶子节点中存储一条记录中的所有信息。
  3. 正常的表应该有且仅有一个聚集索引(绝大多数情况下都是主键),表中的所有行记录数据都是按照聚集索引的顺序存放的。
  4. 当我们使用聚集索引对表中的数据进行检索时,可以直接获得聚集索引所对应的整条行记录数据所在的页,不需要进行第二次操作。

非聚集索引(辅助索引)

数据库将所有的非聚集索引都划分为辅助索引;辅助索引也是通过 B+ 树实现的,但是它的叶节点并不包含行记录的全部数据,仅包含索引中的所有键和一个用于查找对应行记录的『书签』,在 InnoDB 中这个书签就是当前记录的主键。

辅助索引的存在并不会影响聚集索引,因为聚集索引构成的 B+ 树是数据实际存储的形式,而辅助索引只用于加速数据的查找,所以一张表上往往有多个辅助索引以此来提升数据库的性能。

七、锁

1、悲观锁

悲观锁是一种真正的锁了,它会在获取资源前对资源进行加锁,确保同一时刻只有有限的线程能够访问该资源,其他想要尝试获取资源的操作都会进入等待状态,直到该线程完成了对资源的操作并且释放了锁后,其他线程才能重新操作资源;

2、乐观锁

乐观锁是一种思想,它其实并不是一种真正的『锁』,它会先尝试对资源进行修改,在写回时判断资源是否进行了改变,如果没有发生改变就会写回,否则就会进行重试,在整个的执行过程中其实都没有对数据库进行加锁;

3、读写锁

  • 共享锁(读锁):允许事务对一条行数据进行读取;
  • 互斥锁(写锁):允许事务对一条行数据进行删除或更新;

共享锁之间是兼容的,而互斥锁与其他任意锁都不兼容:因为共享锁代表了读操作、互斥锁代表了写操作,所以我们可以在数据库中并行读,但是只能串行写,只有这样才能保证不会发生线程竞争,实现线程安全。

4、意向锁

为了支持多粒度锁定,InnoDB 存储引擎引入了意向锁(Intention Lock),意向锁就是一种表级锁。

  • 意向共享锁:事务想要在获得表中某些记录的共享锁,需要在表上先加意向共享锁;
  • 意向互斥锁:事务想要在获得表中某些记录的互斥锁,需要在表上先加意向互斥锁;

意向锁其实不会阻塞全表扫描之外的任何请求,它们的主要目的是为了表示是否有人请求锁定表中的某一行数据。

有的人可能会对意向锁的目的并不是完全的理解,我们在这里可以举一个例子:如果没有意向锁,当已经有人使用行锁对表中的某一行进行修改时,如果另外一个请求要对全表进行修改,那么就需要对所有的行是否被锁定进行扫描,在这种情况下,效率是非常低的;不过,在引入意向锁之后,当有人使用行锁对表中的某一行进行修改之前,会先为表添加意向互斥锁(IX),再为行记录添加互斥锁(X),在这时如果有人尝试对全表进行修改就不需要判断表中的每一行数据是否被加锁了,只需要通过等待意向互斥锁被释放就可以了。

5、两阶段锁

6、三阶段锁

参考文章

  1. mysql 幻读的详解、实例及解决办法
  2. 《从Paxos到Zookeeper》读书笔记(一)
  3. 『浅入浅出』MySQL 和 InnoDB

results matching ""

    No results matching ""