[mysql]索引与数据结构

索引是什么:索引类似于字典中查找一个字,一个字典中有根据笔画来查找的方法,也有根据拼音的查找方法.其归根结底是为了更快的来找到我们需要查找的那个字

具体操作:

show index from 表名;具体查看表中的索引

create index 索引名 on 表名(字段名称);
创建一个索引 对于非主键 非唯一约束 非外健约束 都可以创建引索

drop 引索名 on 表名; 删除索引

索引的作用

在进行数据库查询操作时 适当索引 对查询的效率进行了提升 使在查询过程中快速定位,不用全盘遍历数据 并且也加快对 order by 与group by 分组操作 效率的提升

同时 数据库在实际开发中常常 会是在开发过程中瓶颈事发地 所以 索引也具有两面性, 适当的索引会提供 更快的效率,但是创建索引也会占用磁盘空间的, 所以更要注意索引的使用;

索引内部的结构:

索引,一定是引入的一些额外的数据结构 ,来增加查询速度

默认情况下,进行条件查询,就是遍历表,一条一条数据都带入条件

引入索引,是要通过其他的数据结构,加快查询的速度,减小遍历表的可能性

数据结构中与索引

存在一些结构能够加快查询,有些则不能

顺序表:能够快速随机访问,但是插入删除效率低 ;不能快速查找

链表:能够做到插入删除,但是访问需要遍历链表,速度慢;同样不能快速查找

哈希表的结构

数组:这是用来存储数据的主体;

哈希函数:是将元素映射到对于数组位置

链表:当两个元素映射到相同位时,一般在每个数组位置下维护一个链表,将存储映射到相同数组位置的两个元素

哈希表是由数组、链表、哈希函数组成,通过存储的元素所对应的哈希码在哈希函数中计算出结果,所得到的值对于的数组下标进行存储.若两个不同的元素,通过哈希函数计算出相同的值,则这就叫做冲突,一般如果定义一个值叫做冲突因子(已插入的元素/数组长度) 每次在进行插入操作时,会计算冲突因子,若达到设定的哈希冲突会通过重新哈希的方式调整冲突因子;回到发生冲突时,当两个元素得到的数组下标相同是时,会通过链表将前一个先插入相同数组下标元素指向刚刚发生冲突的元素,形成一个链表.再回到我们重新哈希,是通过增加数组长度,再对已插入的元素进行一遍哈希;

哈希表的查询操作时间复杂度是接近O(1),得以我们在哈希表中查询一个准确数据的效率是非常快的,但是在存储过程中我们的存储顺序是随机的,所以我们并不能进行范围查询的操作;

再谈哈希表查询操作的时间复杂度

一般我们近似认为哈希表的查询操作的时间复杂度为O(1),我认为在正常情况下进行插入操作时,数组长度与链表长度,由于有重新哈希这个操作,应会小于 已插入元素的数量.这样的本意就是维护这样一个高效率的查询操作.但考虑最坏情况下 若有N个数据,链表长度为n,那么n<<N 查询时间复杂度也 不可能是O(N),除非故意设置一个有意将所有数据存储在一个链表下,这样无话可说,但在实际情况下,是不会出现的

二叉搜索树,AVL树 红黑树
二叉搜索树

是一个特殊的二叉树,它要求父节点的左孩子要小于父节点,右孩子要大于父节点,再这样的要求下,使二叉搜索树在查询过程中,可对数据对父节点进行判断,往左树找,还是右树找 或者是刚刚好等于父节点; 在树比较平衡情况下这样查询操作的时间复杂度为O(logN),但在出现极端情况,变成一个单分支树,那么时间复杂度就会退化成O(N);

AVL树

是一个特殊的二叉搜索树,为什么会特殊呢?在于AVL树对于结构的要求更为严格,他要求我们在树中每个节点的平衡因子的绝对值不允许>1;

这样使得AVL在插入或者删除节点时需要进行调整,通过调整去维护AVL树的特性,这样就会耗费更多的开销;不过此时的AVL树解决了二叉搜索树中的极端情况,使得AVL树的时间复杂度就为O(logN);

红黑树:由于AVL树的要求较为严格,触发调整的机会更大,而红黑树在调整的标准中"宽松"许多,使得红黑树结合了二叉搜索树与AVL树的"优点",在查询时间复杂度上与AVL树不相上下,并且在插入删除方面所损耗的开销是低于AVL树,使得红黑树成为一个"六边型战士",让它的性价比更高于ALV树,使得红黑树的应用范围更加广泛;

缺点:

在数据库中为什么不使用红黑树呢:

首先 数据库是存储大量数据,因此不可能存储在内存当中,所以需要对磁盘进行I/O操作,并且在如此大量数据的情况下红黑树的节点更新操作,会多次对磁盘进行操作,造成大量的开销;

其次 在计算机中内存访连续存储空间的数据,是比随机访问快很多的,而红黑树存储的数据是随机分散的,造成计算机访问数据效率降低;

最后 由于数据的增多使得树的高度逐渐变大,但在查询过程中每一层都需要进行比较,所耗费的时间更多,并且存在比红黑树更适合的数据结构应用在数据库当中B树(或者B+树),更择优选则;

B树

B树比红黑树中的节点存储着更多的数据,并且每一个节点能允许拥有更多的子节点,所以同样的数据树的高度大大降低,并且每一个子节点都是处在相同的高度的

在这里插入图片描述
B树的结构图,

根节点当中每一个数据与每一个数据都存在一个范围,衍生出"范围"节点,每两个节点都会衍生出三个范围 (那30与40节点举例,衍生出小于30节点,大于30小于40,大于40这三个范围)

并且数据都是存储在一块连续的范围当中,每一个节点存储的是 一多个健(keys)与数据还有指向下一个节点的指针

并且这一系列查询比较,减少了多次节点的比较,而且在硬盘是进行,只需要硬盘的一次I/O操作就可以读出数据,使得查询速度效率更高,

二叉树搜索树中的存储地址在硬盘上是分散随机的,比较需要硬盘加载,在输出查询,所以需要多次I/O操作使得在查询数据更加效率高,所以B树在查询,删除,添加节点是比较适用的

但在mysql中是使用的是B+树

B+树

同样是一个N叉搜索树,B+树则是B树的升级版

结构图

在这里插入图片描述
在mysql中的B+树每个节点的是子树的最大值,并且父节点并且会出现在子树当中充当该节点的范围,并且每一个节点中只存储着健,方便寻找到下一个节点,而数据是存储在叶子结点当中,并且用一个链表的形式将整个叶子结点串起来 (这里两点与B树相结合比较)

这使得我们在非叶子结点的存储空间非常少,每一个节点能够存储更多的数据,让数据在叶子结点存储使得存储在内存是一块连续的空间,使查找更加迅速;

每一次查询都会查询到叶子结点当中,使得每一次的查询效率更加稳定

这使得B+树更加与引索相匹配适用

如果在表中存在主键的会按照主键创建引索,每一个主键相对于的叶子子节点中存储着一行数据(如 ID 2 name 李四 性别…… );

那么在没有主键的表中创建引索时,会构建一个隐藏主键,根据隐藏主键会创建一个B+树

细说在一个为一个含有主键的表中为:一列是主键,一列为非主键通常非主键这列的引索与主键引索背后的B+树没什么区别,但是却别在与非主键列的B+树当中的叶子结点存储的数据其实是对于主键节点的地址,所以非主键的引索也作为辅助引索

查询过程例子

查询步骤:如果你在一个Student(ID int primary key ,name varchar(20))当中两列都有引索

查询 SELECT * FROM STUDENT WHERE NAME =“李四”;

由于你的name列不是主键引索,会在name的引索的B+树当中找到对应的子节点数据,通过数据中记录的"地址",跳转到主键引索对应存储的数据进行读取

总结

所以总的来说在mysql当中如果一行列中拥有一个引索的查询是非常快速的,而通过没有引索的列查询则是"全盘扫描",效率是非常低效率的;

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值