MySql数据库索引及数据结构

索引是数据库系统⾥⾯最重要的概念之⼀,索引的出现其实就是为了提⾼数据查询的效率,就像书的⽬录⼀样。

索引的常见模型

三种常见、较简单的数据结构,它们分别是哈希表有序数组搜索树

哈希表

哈希表是⼀种以键-值(key-value)存储数据的结构,我们只要输⼊待查找的值即key,就可以找到其对应的值即Value。

哈希的思路很简单,把值放在数组⾥,⽤⼀个哈希函数把key换算成⼀个确定的位置,然后把value放在数组的这个位置。

不可避免地,多个key值经过哈希函数的换算,会出现同⼀个值的情况。处理这种情况的⼀种⽅法是,拉出⼀个链表。

假设,你现在维护着⼀个身份证信息和姓名的表,需要根据身份证号查找对应的名字,这时对应的哈希索引的示意图如下所示:
哈希表示意图
如果你现在要找身份证号在[ID_card_X, ID_card_Y]这个区间的所有⽤户,就必须全部扫描⼀遍了。哈希表这种结构适⽤于只有等值查询的场景,⽐如Memcached及其他⼀些NoSQL引擎。

有序数组

有序数组在等值查询和范围查询场景中的性能就都⾮常优秀,根据身份证号查名字的例⼦:
有序数组示意图
这个数组就是按照身份证号递增的顺序保存的。这时候如果你要查ID_card_n2对应的名字,⽤⼆分法就可以快速得到,这个时间复杂度是O(log(N))。
如果仅仅看查询效率,有序数组就是最好的数据结构了。但是,在需要更新数据的时候就麻烦了,你往中间插⼊⼀个记录就必须得挪动后⾯所有的记录,成本太⾼。

所以,有序数组索引只适用于静态存储引擎,比如你要保存的是2017年某个城市的所有人口信息,这类不会再修改的数据。

二叉搜索树

二叉搜索树
二叉搜索树的特点是:每个节点的左儿子小于⽗节点,⽗节点⼜小于右儿子。这样如果你要查ID_card_n2的话,按照图中的搜索顺序就是按照UserA -> UserC -> UserF -> User2这个路径得到。这个时间复杂度是O(log(N))。

树可以有二叉,也可以有多叉。多叉树就是每个节点有多个儿子,儿子之间的大小保证从左到右递增。

你可以想象⼀下⼀棵100万节点的平衡二叉树,树⾼20。⼀次查询可能需要访问20个数据块。在机械硬盘时代,从磁盘随机读⼀个数据块需要10 ms左右的寻址时间,这个查询可真够慢的。

InnoDB 的索引模型

在InnoDB中,表都是根据主键顺序以索引的形式存放的,这种存储⽅式的表称为索引组织表。⼜因为前⾯我们提到的,InnoDB使⽤了B+树索引模型,所以数据都是存储在B+树中的。

mysql> create table T(
id int primary key,
k int not null,
name varchar(16),
index (k))engine=InnoDB;

表中R1~R5的(ID,k)值分别为(100,1)、(200,2)、(300,3)、(500,5)和(600,6),两棵树的示例示意图如下。

在这里插入图片描述
主键索引的叶⼦节点存的是整⾏数据。在InnoDB⾥,主键索引也被称为聚簇索引(clustered index)

非主键索引的叶⼦节点内容是主键的值。在InnoDB⾥,⾮主键索引也被称为二级索引(secondary index)

根据上⾯的索引结构说明,我们来讨论⼀个问题:基于主键索引和普通索引的查询有什么区别?
如果语句是select * from T where ID=500,即主键查询⽅式,则只需要搜索ID这棵B+树;
如果语句是select * from T where k=5,即普通索引查询⽅式,则需要先搜索k索引树,得到ID的值为500,再到ID索引树搜索一次。这个过程称为回表

也就是说,基于非主键索引的查询需要多扫描⼀棵索引树。因此,我们在应⽤中应该尽量使用主键查询

索引维护

自增主键的插入数据模式,正符合了我们前⾯提到的递增插入的场景。每次插入一条新记录,都是追加操作,都不涉及到挪动其他记录,也不会触发叶⼦节点的分裂。
主键⻓度越小,普通索引的叶⼦节点就越⼩,普通索引占⽤的空间也就越小。

总结:

1.索引的作⽤:提⾼数据查询效率
2.常见索引模型:哈希表、有序数组、搜索树
3.哈希表:键 - 值(key - value)。
4.哈希思路:把值放在数组⾥,⽤⼀个哈希函数把key换算成⼀个确定的位置,然后把value放在数组的这个位置
5.哈希冲突的处理办法:链表
6.哈希表适⽤场景:只有等值查询的场景
7.有序数组:按顺序存储。查询⽤⼆分法就可以快速查询,时间复杂度是:O(log(N))
8.有序数组查询效率⾼,更新效率低
9.有序数组的适⽤场景:静态存储引擎。
10.⼆叉搜索树:每个节点的左⼉⼦⼩于⽗节点,⽗节点⼜⼩于右⼉⼦
11.⼆叉搜索树:查询时间复杂度O(log(N)),更新时间复杂度O(log(N))
12.数据库存储⼤多不适⽤⼆叉树,因为树⾼过⾼,会适⽤N叉树
13.InnoDB中的索引模型:B+Tree
14.索引类型:主键索引、⾮主键索引
主键索引的叶⼦节点存的是整⾏的数据(聚簇索引),⾮主键索引的叶⼦节点内容是主键的值(⼆级索引)
15.主键索引和普通索引的区别:主键索引只要搜索ID这个B+Tree即可拿到数据。普通索引先搜索索引拿到主键值,再到主键
索引树搜索⼀次(回表)
16.⼀个数据⻚满了,按照B+Tree算法,新增加⼀个数据⻚,叫做⻚分裂,会导致性能下降。空间利⽤率降低⼤概50%。当相
邻的两个数据⻚利⽤率很低的时候会做数据⻚合并,合并的过程是分裂过程的逆过程。
17.从性能和存储空间⽅⾯考量,⾃增主键往往是更合理的选择。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值