索引是帮助MySql高效获取数据的排好序的数据结构
索引数据结构:1.二叉树 2.红黑树 3.hash表 4.B-Tree
假设查询一条数据:select * from t where t.Col2= 89 查询数据时,会进行多行遍历,并且数据进行比对。如果比对成功,就已找到该条数据。如果表很大,就会查询非常久。表里的数据存储在磁盘上面的,每一行数据存储在磁盘上都是随机分布的,并不是连续的去分布。假设Col2创建索引,利用二叉树。
二叉树的数据特性,右节点数据大于父节点数据。左节点数据小于父节点数据。存储的结构为Key-value结构。Key存储的是Col2下的数据,value存储的是该数据在磁盘上的地址。
MySql的底层索引一般都用B-Tree树,或者B+树这种结构
为什么不是用二叉树呢,因为二叉树在某些场景下是有弊端的。把Col1创建索引变为一颗二叉树,变为了单链表结构,如果去查找元素,有些时候特别慢。
假设为红黑树结构:当右节点比左节点多俩级后,自动平衡数据,中位数当在父节点,比中位数大的数字放在右子节点,比中位数小的数字放在左子节点。实际上也是一颗二叉树。也称为二叉平衡树。
弊端:公司的数据上千万行,如果按红黑树的特征存储数据,则树的高度非常高。如何做,可以降低树的高度。
假设利用B-Tree,把根节点数据都放在内存中,然后查找的元素在内存中比对,如果是49,则会找到15到56间的一个指针,
指针指向的节点放到内存中,再去查找到49。
如果把数据全部放在内存中可行嘛? 如果有几千万条数据,肯能需要几个G来存储。磁盘和内存打交道,一次磁盘IO为4K。
mysql对一个节点设置的大小为16K.
对B-Tree进行改造,得到一种B+Tree的概念,也称为多叉平衡树,单看一个小块也为二叉树,某一个节点元素,从左到右依次为递增的。
为什么要有这么多冗余索引,而且把data元素放在叶子节点?
节点存储大小为16K,把data元素移走之后,数据将会存储的更多。存储的指为8B,指针为6B,16K/8B=1170个索引。
假设树高度为3,叶子节点的元素大概是1K,大概可以放16个。1170*1170*16=20000000个数据。
MySam存储引擎,下图示为mysql安装目录文件夹,第一个存储表结构信息,MYD存储数据行的记录。MYI所有的索引字段。
查找数据会跨俩个文件,例如49先在MYI文件中叶子节点上找到对应数据的存储地址,然后利用此存储地址查找MYD文件中的数据行。
innodb存储引擎:ibd文件中数据文件和索引文件。所有行的数据都放在了索引的叶子节点。
聚集索引-叶节点包含了完整的数据记录