索引:是帮助mysql高效获取数据的排好序的数据结构
索引数据结构:
二叉树:将第一个插入的数据作为比较,比他大的放右边,小的放左边,当我们的索引字段是自增的 时候,他就会退化成为链表的结构,效率十分低下,所有后边没有采用
红黑树: 别名:二叉平衡树,他本质上还是二叉树,增加了一个自平衡机制,满3进一,虽然说一定程度的缓解了退化成为链表,但是还是避免不了树的高度过高
hash:
对索引的key进行一次hash计算就可以定位出数据存储的位置
很多时候hsah的索引查询效率要高于b+树的
但是它不支持范围查询
存在hash冲突问题
b树:
叶节点具有相同的深度,叶节点的指针为空,所有索引元素不重复,节点中的数据索引从左到右递增排列
叶子节点之间不存在双向链表的指针,做区间查询的时候效率低下
没有冗余索引,所有节点都带有data
b+树:
数据全部存储在了叶子节点之上,非叶子节点不存储data,只存储索引,可以存放更多的索引,叶子节点包含所有的索引字段,叶子节点之间用指针连接,提高区间访问性能
每一次比较都是和磁盘进行一次i/o交互,效率十分低下,尽量减少查询的次数是提高性能的主要手段
每个节点大小:
默认16kb 能存大概:1170个索引 叶子节点有数据,存储的比较少最 大也就 是1kb一个,1170x1170x16 = 2000多万个,这也就是为什么数据不建议存储超过2000万条数据的由来
查找方式:
从左到右依次递增,根据折半查找法,将查找出来的数据存入内存当中,然后就行查找,折半查找法所浪费的时间远远低于跟磁盘io进行交互所浪费的时间
双向链表:
每一组叶子节点的最左边或者最右边的数据会有一块区域专门存储他相邻叶子节点的磁盘文件存储地址
存储引擎:
是表级别的,每一张表都可以选择自己的存储引擎
数据存储:
mysql数据库里面的数据默认是存储在我们的mysql的data目录下的
一个数据库对应一个文件夹,一张表对应两到三个文件(不同的存储引擎他不一样):
.frm(框架单词的缩写)文件:这是存储我们表结构的数据
.myd(d:是data的缩写,代表数据):这是myisam引擎的文件,这里面存储数据
.myi(i:index的缩写,代表索引):这是myisam引擎的文件,这里面存储索引
.idb:innodb引擎的文件,这里存储数据和索引
mysam引擎:(非聚集)
data:data只在叶子节点下,这里边存储的实际上就是对应索引所在行的磁盘文件地址
查询流程:
首先去myi文件当中通过折半查找,快速的定位到索引的位置,然后获取他data里边的磁盘文件地址,然后通过地址去myd文件里边取出对应的数据
innodb引擎:(聚集)
他的表数据文件本身就是按照b+树组织的一个索引结构的文件
聚集索引(主键索引):代表叶子节点包含了完整的数据记录,存储的是其索引所在行的其他列数据
非主键索引(二级索引):他data里面存储的是数据所在行的主键
为什么innodb表必须建立主键,并且推荐使用自增主键?
因为你不建立,他也会自动帮你建立一个唯一的隐藏索引,会浪费数据库的性能,而且他的文件存储形式就是按照b+树的形式进行存储的,没有这个唯一索引,就没有办法去建立
至于为什么推荐使用整形作为自增主键,因为他在进行查找的时候,回去做数据比对,通过比大小的形式最终定位到索引所在位置,如果是你不是整形的还需要逐位比较并且转换为ASCII码来进行比较,效率方面显而易见,
至于为什么非得是自增,因为b+树他是会分裂的,当我们的一棵树已经存满了,你硬要在中间加入一个数据,他就会分裂,而这个分裂的过程会消耗我们的性能,并且会对我们的数据结构造成影响,如果使用自增,他会一直往右边增加节点,就会大大减小分裂产生的几率
为什么非主键索引结构叶子节点存储的是主键值?
一致性和节省存储空间
联合索引的底层树据结构长什么样子?
其余内容待总结~~~