存储引擎
数据库存储引擎是数据库底层软件组织,数据库管理系统(DBMS)使用数据引擎进行创建、查询、更新和删除数据。不同的存储引擎提供不同的存储机制、索引技巧、锁定水平等功能,使用不同的存储引擎,还可以获得特定的功能。现在许多数据库管理系统都支持多种不同的数据引擎。
存储引擎主要有: 1. MyIsam , 2. InnoDB, 3. Memory, 4. Archive, 5. Federated 。
MyIASM
MyIASM是 MySQL5.5版本之前默认的引擎,但是它没有提供对数据库事务的支持,也不支持行级锁和外键.
非聚集索引
索引文件和数据文件是分离的.
优点
能够保证让树的高度变的更小,小于等于3,高度越低,磁盘IO次数越少,查询效率越高,并且不占用大量的内存和存储资源.
缺点
不支持事务,事务操作的是索引,而MyIASM的索引文件和数据文件是分离的.
插入或更新数据时,需要锁定整个表,效率低一些。
InnoDB
MySQL5.5版本之后默认的存储引擎,支持事务.
这里说的是默认,也就是说还是可以使用MyIASM
创建表的时候,在末尾增加ENGINE=MYIASM,就可以使用MYIASM存储引擎.
它的索引和数据在同一个文件中(聚集索引)
聚集索引
聚集索引就是索引和数据在同一个文件中,包含了整个表的数据,而不是只有索引.因此在Innodb中,聚集索引就是表,所以不像myisam那样需要独立的行存储。聚集索引的每一个叶子节点都包含了主键值,事务ID,MVCC的回滚指针以及所有剩余字段的值,如果主键是一个列前缀索引,innodb也会包含完整的主键列和剩下的列的值。
优点
最大限度地提高了IO密集型应用的性能.
因为InnoDB将索引列与相关数据行保存在一起。这意味着,当你访问同一数据页不同行记录时,已经把页加载到了Buffer中,再次访问的时候,会在内存中完成访问,不必访问磁盘。内存的查询速度比磁盘的查询速度快一万倍
缺点
如果存一个超级大的字段,那么它可能占用一个节点,或者两个节点,甚至更多,数据越大,表的记录越多,树的高度就越高.因为数据都在叶子节点,数据多,叶子节点也就越多,造成了父节点也要多,树的高度也就偏高.所以mysql5.5之后,推荐我们的数据不要超过一千万.超过一千万就分库分表.
尽量的让大字段,单独存放,例如图片,大文本等一系列的不能扔到数据库,专门文件系统来存放.如fastDFS,MongoDB.
数据库中只放一些比较小的字段,这样可以提高查询效率.
B+树
InnoDB的数据结构是B+树
其中非叶子节点只有索引和指针,没有数据,叶子节点只存储索引和数据,不存储指针.
MySQL数据库默认一次读取一页的大小,一页就是4个磁盘块,一个磁盘块占用4KB,所以一页的大小就是16KB.也就是说一个节点16KB.
一个索引占8个字节,一个指针占六个字节一级节点可以容纳1170个索引.
一级节点向下演化二级节点,一级节点里边有1170个索引1170个指针,一个指针指向一个二级节点,那么二级节点有多少个,1170个二级节点.非叶子节点可以容纳1170个索引,那么二级节点一共可以容纳1170*1170=136W个索引.
以三阶B+tree为例,三级节点作为叶子节点,只存放索引和数据,假如一条记录为1KB,一个三级节点可以存放16条记录.一共有1170 * 1170 * 16=2100W条记录.注意,现在树的高度仅仅为三层,想要查询数据,仅仅只需要进行两次磁盘IO,为什么是两次,因为mysql有一个特点,默认将每一张表的根节点加载到内存.千万记录,两次磁盘IO,所以B+tree的性能可以想象.
B+tree还有一个优点,它的叶子节点是一个有顺序的,是一个链表.就不需要排序,减轻了CPU的消耗.详细一点,它是一个双向链表.单向链表链接方向是单向的,对链表的访问要通过顺序读取从头部开始。而双向链表,在其中的任意一个结点开始,都可以很方便地访问前驱结点和后继结点。对范围查询可以更加高效.
innoDB的MVCC技术
MVCC是一种多版本并发控制机制,是一种提高并发的技术。在MVCC协议下,每个读操作会看到一个一致性的snapshot,并且可以实现非阻塞的读。
为什么使用MVCC
- MySQL的存储引擎是InnoDB,这种大型的事务性存储引擎,仅仅依靠一个行锁机制,并不能满足并发的需求,他们往往都跟其他机制配合使用,比如MVCC.
- 行锁虽然可以控制并发操作,但是系统开销较大,而MVCC可以在大多数情况下代替行锁,使用MVCC可以降低系统开销,提高并发度.
MVCC原理
MVCC的原理与copyonwrite类似,什么是copyonwrite呢,写时复制,读写分离。
举个例子:老王和老张在看一本好看的书,老王想在书上写写画画,这样的话,老张就不爽了,你写的什么玩意,打扰我看书,所以嗖嗖嗖~~,老王变出来了一个复印本,在这个复印本上乱写乱画,老张继续看老张的,等老王弄好后,原本的引用指向复印本,就完成了修改操作。
通过保存数据在某个时间点的快照来实现. MVCC允许数据具有多个版本,这个版本由时间戳或者是全局递增的事务ID控制,在同一个时间点,不同的事务看到的数据是不同的。
InnoDB中的MVCC是怎样进行并发控制的
它在每行记录后边增加了两个字段,分别是该行的创建版本和删除版本,填入的是事务的版本号.这个版本号随着事务的创建不断的增加.
比如,我们现在要对一行记录进行增删改查操作.
执行insert操作,创建版本号为1,这个创建版本号就是insert事务的ID.
执行update操作,分两步实现,先删除,后新增,先将这一行的删除版本号加1等于2,并且将删除版本号作为当前事务ID,再进行新增操作,并且将新增这一行的创建版本号赋值为2.
执行delete操作时,将该行的删除版本号加1等于3,同时当前事务ID就是3.
执行select操作时,需要满足两个条件,满足以下两个条件才会被查询出来.
一.当前事务ID要大于等于当前行的创建版本号,这样表示事务开始前这行数据已经存在.
二.当前事务ID要小于当前行的删除版本号,这样代表,查询事务开始的时候,这行记录是存在的,查询事务开始之后,这行记录才被删除.被删除就被删除,被删除也要被查出来,这就是可重复读.
·························································································
纯文字,是不是看懵了,O(∩_∩)O哈哈~
你学废了吗