看完上一个章节,相信你已经充分的掌握了数据库事务的一些事情,猿人工厂君也知道,内容对于新手而言,理解起来还是比较很吃力的,文中提到的原理和内容,有兴趣的可以和我一起探讨,猿人工厂君就不一一赘述了。今天我们继续讨论和数据库有关的事情。
索引是数据库快速查找记录的一种数据结构,当数据量较大时,好的索引能够帮助数据库,快速定位记录,提升数据库的访问性能。你可以把数据库索引想象成一本字典的目录,通过目录(索引),快速的找到你需要查找的文字(记录)。
从数据存储的方向上讲,数据库的索引可以分为两个大类——聚集索引和非聚集索引。所谓聚集索引,是指在索引的叶子节点,索引和数据存放在一起,数据库在读取索引的同时,就可以获取相应的记录。非聚集索引,存放的是索引和数据的位置,数据库在读取索引后,需要根据数据位置再次回表读取具体的记录。
MYSQL的存储引擎分为MYISAM和INNODB。MYISAM引擎使用的是非聚集索引,INNODB引擎使用的是聚集索引。并不是讲聚集索引就一定好,聚集索引适用于IO密集型的应用,如果是内存密集型的应用,聚集索引就没啥优势可言了。聚集索引的访问顺序严重依赖于数据的插入顺序,而且更新聚集索引的代价很高,INNODB需要强制移动每个被更新的行到新的位置。
从使用的角度来看,MYSQL的索引可以分为以下几类:
单列索引
对每个字段创建的索引
组合索引
使用表的多个字段组合创建的索引,这类索引要想查询时派上用场,需要查询用的SQL语句遵循最左匹配原则。
单列索引和组合索引又包括:
普通索引
非主键,非唯一列的索引
主键索引
就是一个表的主键,如果一个表不定义主键,会使用该表中是否存在非空、整形、唯一索引作为其主键(可通过select _rowid from 表名查看),若都不满足会隐式生成一个rowid作为主键(无法直接查到),这里还有一个小问题,一个主键是用uuid好还是整型好的问题噢。考虑到INNODB的存储结构,主键属于聚集索引,和插入顺序有关,而且uuid生成得往往较长,和整型比,更浪费存储空间噢。
唯一索引
基于表的唯一列生成的索引,允许为空值
全文索引
将存储于数据库中的整本书或整篇文章中任意内容信息查找出来,如大量级的文字中如like %关键字%,普通索引的效率与全文索引相比是非常低的。
说到MYSQL索引的数据结构,自然不得不提到B 树了。也许你会好奇B 树是一种什么结构?那我问你一个问题B树你知道吗?
B树,一看名字还是很吓唬人的,其实就是平衡二叉树了。为什么要平衡?所谓平衡是指树的深度相对保持平衡,我们知道遍历一个树,需要递归,每多一层,相当于多了一次循环操作噢,不平衡,访问起来的效果要呵呵的。一个B树要满足以下几个特性:
1、根结点至少有两个子女;
2、每个非根节点所包含的关键字个数 j 满足:┌m/2┐ - 1<= j <= m - 1;
3、除根结点以外的所有结点(不包括叶子结点)的度数正好是关键字总数加1,故内部子树个数 k 满足:┌m/2┐ <= k<= m ;
4、所有的叶子结点都位于同一层。
那B 树是什么呢?B 树比较鸡贼了。我们看上图,B 树在叶子节点之间加了一个子针,将叶子节点串联起来,在访问叶子节点的时候就可以从左自右的访问啦,同时非叶子节点只存储了key,而没有存储数据也能节约空间噢。
我们都知道磁盘IO和内存操作相比是很消耗性能的。数据库很鸡贼的在读取数据时不是严格按需读取,而是一次性的读取一页的数据入内存。预读的长度一般为页(page:计算机管理存储器的逻辑块-通常为4k)的整倍数. 主存和磁盘以页为单位做交换数据。当需要读取的数据不在内存时,就会向磁盘发出读取信号,一次读取一页或多页数据放入内存种,这种机制就是数据库的预读机制。
B 树的设计巧妙地运用了操作系统存储结构(一个节点分配到一个存储页中尽量减少IO次数) 并且设置磁盘预读机制(预读马上要用到的数据到内存中).单个节点能放多个子节点,相同IO次数,检索出更多信息。只在叶子节点存储数据并且所有叶子结点包含一个链指针,而且其他内层非叶子节点只存储索引数据。只利用索引快速定位数据索引范围,先定位索引再通过索引高效快速定位数据。
首先,在数据表上每建立一个索引都会增加磁盘的存储空间,索引对于表数据的插入、删除、更新操作也会消耗更多的时间。如果存在单例索引,再建立复合索引往往是没有意义的。
我们在使用索引时有几个原则是可以参考的:
1.较频繁的作为查询条件的字段应该创建索引
2.数据唯一性太差的字段不适合单独创建索引
3.频繁更新的字段不适合创建索引
4.不出现在查询条件中的字段就不要建立索引
5.数据量太小的表是没有必要建立索引的