主要内容:
- 存储结构
- 索引
- 锁
- 事务
存储结构
- 表
- 索引组织表:表是根据主键顺序组织存放的。若是表中没有非空唯一索引,引擎会自动建立一个6字节大小的指针。
- 主键的索引是定义索引的顺序,而不是建表时列的顺序。
- 表空间:逻辑结构的最高层,全部的数据都存放在表空间中。
- 段:表空间由各个段组成,常见的段有数据段、索引段、回滚段等。
- 数据即索引 ,索引即数据。
- 区:区是由连续页组成的空间,在任何状况下每一个区的大小都为1MB。
- 引擎页的大小为16KB,即一个区中一共有64个连续的页。
- 页(也叫块):是InnoDB磁盘管理的最小单位。默认每一个页的大小为16KB.新版本中能够设置为4,8,16k。
- 行:数据是按行存储。每一个页最多容许存放7992行记录。
- 行记录格式
- Compact行记录是在MySQL5.0中引入。一个页中存放的数据越多,其性能就越高。
- 变长字段的长度不能超过2字节,由于VARCHAR类型的最大长度为65535。
- 行溢出数据:通常认为,BLOB、LOB这类的大对象列类型的存储会把数据存放在数据页面以外。
- 经过实际测试发现能存放VARCHAR类型的最大长度为65532.
- MySQL官方手册中定义的65535长度是指全部VARCHAR列的长度总和,若是列的长度总和超过这个长度,依然没法建立
- VARCHAR(N),CHAR(N) N是指字符的长度,不是字节的长度。
- 页结构
- B+树索引自己并不能找到具体的一条记录,能找到的只是该记录所在的页。
- 约束和索引的区别:结束是一个逻辑的概念,用来保证数据的完整性,而索引是一个数据结构,既有逻辑上的概念,在数据库中还表明着物流存储的方式。
索引
- B+树中的B表明的是balance(平衡),而不是binary(二叉),由于B+树是从最先的平衡二叉树演化而来,可是B+树不是一个二叉树。
- 对于某一条具体的记录的查询是经过对Page Directory进行二分查找获得的。
- 平衡二叉树的定义以下:首先符合二叉树查找 的定义,其次必须知足任何节点的两个子树的高度最大差为1。
- 汇集索引就是按照每张表的主键构造一棵B+树,同时叶子节点中存入的即为整张表的行记录数据,也将汇集索引的叶子节点称为数据页。
- 索引组织表中的数据也是索引的一部分。每一个数据页都经过一个双向链表来进连接 。
- 辅助索引:叶子节点并不包含行记录的所有数据。叶子节点除了包含键值之外,每一个叶子节点中的索引 行中还包含了一个书签,用来告诉InnoDB存储引擎哪里能够找到与索引 相对应的行数据。
- 当经过辅助索引来查找数据时,InnoDB会遍历辅助索引并经过叶级别指针得到指向主键索引的主键,再经过主键索引 来找到一个完整的行记录。
- Microsoft SQL Server 有一种称为堆表的表类型,即行数据的存储按照插入的顺序存放。
- Cardinality:表示索引 中唯一值(不重复记录)的数目的估计值。这个值很是关键,优化器会根据这个值来判断是否使用这个索引 。可是这个值不是实时更新的,即并不是每次索引的更新都会更新该值,缘由是代价过大,因此这个值是一个估计值。 也把这个值称为
可选择性
。引擎一般经过采样的方式来完成Cardinality的统计。 -
覆盖索引:即从辅助索引就能够等到查询的记录,不须要查询汇集索引中的记录。算法
一般查询索引列或者count值会用覆盖索引数据库
- 优化器不使用索引:在范围查找或者JOIN连接操做时,有可能不使用索引 。
- 强制使用索引 :
FORCE INDEX
- 索引提示:
USE INDEX
- 若是肯定指定某个索引来完成查询,那么最可靠的是
FORCE INDEX
,而不是USE INDEX
- Multi-Range Read(MRR):为了减小磁盘的随机访问,而且将随机访问转化为较为顺序的数据访问。具体作法:在查询辅助索引时,首先根据等到的查询结果,按照主键进行的顺序,并按照主键排序的顺序进行书签查找 (explain 会有Using MRR)
- Index Condition Pushdown(ICP)优化:优化以前-查询索引,先根据索引来查找 记录,而后再根据where条件来过滤记录。 优化以后-在取出 索引的同时,判断是否能够进行where条件的过滤,即将where的部分过滤操做放在地了存储引擎层。在一些查询条件下,能够大大减小上层SQL层对记录的索取(fetch),从而提升数据库性能。(explain 会有 Using index condition)
- 哈希算法:采用链表的方式解决冲突,除法散列。
-
自适应哈希索引:是数据库自身建立并使用的,不能对其进行干预。markdown
锁
- 锁机制:是数据库系统区别于文件系统的一个关键特性。提供数据的完整性与一致性。
- InnoBD存储引擎不须要锁升级,由于一个锁和多个锁的开销是相同的。
- InnoDB实现了两种锁:共享锁(S Lock)与排他锁(X Lock)。
- 共享锁:容许事务读一行数据。排他锁:容许事务删除或者更新一行数据。X与S都是行锁
- InnoDB存储引擎支持意向锁设计比较简练,即
意向锁就是表级别的锁
。设计目的就是为了在一个事务中提示下一行将被请求的锁类型。分为:意向共享锁(IS Lock,事务想要 得到一张表中某几行的共享锁),意向排他锁(IX Lock事务想要 得到一张表中某几行的排他锁) - 由于InnoDB存储引擎支持的是行级别的锁,因此意向锁不会阻塞除全表扫之外的任何请求。
- 一致性非锁定读:经过多版本控制 的方式来读取当前执行时间数据库中行的数据。若是读取的行正在执行DELETE或者UPDATE操做,这里读取操做不会所以等待行上的锁释放。引擎会读取行的一个快照数据。
- 一致性锁定读:
SELECT ... FOR UPDATE
(对读取的行记录加一个X锁)或者SELECT ... LOCK IN SHARE MODE
(对读取的行记录加一个S锁,其它事务能够向被锁的行加S锁,若是加X锁,则会被阻塞) - 行锁3种算法:Record Lock-单个行记录上锁。Gap Lock-间隙锁,锁定一个范围,但不包含记录自己。Next-Key Lock:Gap+Record
- Gap Lock:为了阻止多个事务将记录插入到同一范围内,这个致使Phantom Problem(幻读)产生。能够经过:事务隔离级别设置为RC关闭Gap Lock.
- Phantom Problem:
指在同一事务下,连续执行两次一样的SQL语句,可能致使不一样的结果 ,第二次的SQL语句可能会返回以前不存在的行。
- 脏页:在缓冲池中已经被修改的页,可是尚未提交刷新到磁盘中。日志都已经写入到重作日志文件中。脏数据 :指事务对缓冲池中的行记录的修改,而且尚未被提交。
- 不可重复读:在一个事务内读取一组数据,在这个事务尚未结束时,另外的事务对这组数据 进行了修改并提交了事务,此时,第一个事务再次读取数据,可能和第一次读取的数据 不一致。
- 不可重复读与脏读的区别:脏读是读取未提交的数据 ,不可重复读是读取已经提交的数据。
- InnoDB不会回滚超时引起的错误异常。可是发现死锁后会回滚。
事务
- ACID:原子性(automicity)、一致性(consistency)、隔离性(isolation)、持久性(durability)。
- 原子性、一致性、持久性经过数据库的redo log 和undo log来完成。redo log是重作日志,保证事务的原子性和持久性。undo 保证事务的一致性。redo恢复提交事务修改的页操做,undo回滚行记录到某个待定版本。二者记录的内容不一样,redo经过是物理操做,记录的是页的物流修改操做。undo是逻辑日志,根据系统自动记录进行记录。
- binlog与redo log的不一样:binlog是在MySQL数据库的上层产生,不只针对InnoDB,任何存储引擎对于数据的更改都会产生binlog. binlog是一种逻辑日志,记录的是对应的SQL语句。redo log是物理格式日志,记录的是对每一个页的修改。
- binlog只在事务提交时一次写入,redo log是不停地写入,与事务提交顺序不一样。
- undo是逻辑日志,只是将数据库
逻辑地
恢复到原来的样子。全部修改被取消了,可是数据结构和页自己在回滚以后可能大不同了。除了回滚,undo的另一个做用是MVCC,undo log会伴随着redo log产生,由于undo log须要持久化。 - 四种隔离级别:READ UNCOMMITTED / READ COMMITTED / REPEATABLE READ /SERIALIZABLE
- MySQL老是自动提交的。