常见索引模型以及InnoDB使用的索引模型(学习笔记)

索引

索引是什么? 大白话讲:    就是一种提升查询效率的数据存储结构。

常见索引模型:

  • 哈希表
    1.是一种以键值方式存储数据的结构。对key进行hash计算:
    hash(key) = addr;
    addr 就是该(key-value)存储的具体物理地址(索引位置),查询时,只需要根据addr即可快速查出value值。

    2.那这个addr存在哪里呢?
    hash表一般都是将数据存储在底层建立的数组里,效果如下:
    在这里插入图片描述

这就存在一个问题了, 如果我的Hash(A) = 6呢?
可以发现,数组长度不足了! 学过数组应该知道,数组的长度是不可变的!那怎么办呢?

3.对hash结果求余:
hash(A) = 6; 6%4 = 2; 那么A这一组数据 就会放在array[2]下;

问题又来了, 如果Hash(B) = 2呢?
可以发现, A、B最终求得的结果是相同的,都是2! 这就是典型的哈希碰撞。

4.哈希碰撞:
解决办法:拉链法;
就是在数组上加入链表,效果如下:
在这里插入图片描述

链表出现的目的,就是让hash计算结果相同的数据,存储在同一个位置延伸出来的链表上。
5.查询步骤:
对key进行hash换算,得到addr,根据addr去数组中找对应的值,如果是碰撞值,那么对这些值一一对比,直到找出正确值。

6.哈希表这种存储结构最适合于等值查询,不适用于范围查询;
为什么呢?
假如我给id(数字) 用上哈希索引,根据以上分析,这些数字会根据hash(key)被随机存储到数组中。
比如id分别是 1、2、3、9、10。它是根据这些数字的key进行存储的。
那么如果我要查询大于7小于10的id对应的数据呢?
8,9 这两个id可能在数组第一位,也可能在最后一位,也可能在链表上!8和9谁又靠前谁又靠后,这是说不清的。
所以哈希表会一遍一遍的过滤数组,只能查完这个范围的数据为止,这太麻烦了是不是!

  • 有序数组
    1.存储的数据,根据数组的索引值大小不同而相对有序。效果如下:

    在这里插入图片描述
    可以发现,数组的下标是升序,ID的值也是升序。
    2. 可以使用二分查找法,对有序数组快速确定值的大概位置,再确定精确位置。
    3. 与hash索引的不同之处在于,hash索引是通过计算key存储的,而有序数组是直接根据值要存储的。
    4. 等值查询与范围查询都适用。
    5. 但是对数据的插入、删除效率低。 如果学过java中List集合的实现类ArrayList就会明白这个问题。

  • 二叉搜索树:

    1. 以二叉树结构进行数据存储;
    2. 树的深度影响查询效率,当树深度较大时,要似的树尽可能保持平衡;
    3. 数据库文件是存在磁盘上的,所以我们不采用二叉搜索树,而是它延伸出来的多叉搜索树。为什么呢?
      因为多叉树的子代可以有很多个,二叉树子代只会有两个;可以发现,多叉树存储的数据深度会大大降低,那么查询存储等操作就会在一定程度上减少磁盘io次数。

- InnoDB使用的索引模型

  1. InnoDB 根据主键的顺序以索引的方式进行存储;
  2. 默认采用B+树索引模型,数据都存储到B+树上;B+树是多叉树的一种
  • InnoDB索引类型分为主键索引与非主键索引;
    (叶子结点就是没有子节点的节点)

    1.1 主键索引: (也叫聚簇索引)
    含义:把主键当作索引来使用,然后将对应的整行数据维护到B+树上。
    特点:主键索引叶子结点中存储的是整行数据;

    1.2 非主键索引:(也叫二级索引)
    含义: 就是以其它字段(非主键)当作索引来使用,然后将对应数据维护到B+树上;
    特点:二级索引叶子结点中存储的是主键的值;

    1.3 主键索引与非主键索引的区别:
    由于两者的特点不同,导致查询结果也不同;
    主键索引只需查找一次B+树就可以定位到数据;
    非主键索引需要查找两次B+树,首先根据二级索引查询到主键值,再根据主键值查询到整行数据!

    1.4 索引是需要维护的:
    所以,避免在增删改查操作较多的表中添加索引;
    索引自身也是占用磁盘内存的;所以主键的字节尽量小一些。

    1.5 索引的选择:
    尽量选择主键索引;
    主键长度越小越好;
    尽量不要选择业务字段作为主键(例如身份证);
    表数据过多再添加索引;
    尽可能选择高基数列(就是不重复的列);
    1.5 添加索引:

  show index from emp;

效果如下:
在这里插入图片描述

可以发现emp表中有, 主键索引与非主键索引(外键);索引类型为B+树;

添加普通索引:create + index + 索引名(自定义) on table(字段名)

	1. create index index_name on emp(ename);
    2. create table stu(....,index index_name(colunm));
    3. drop index index_name on emp;

添加唯一索引:(索引列必须唯一)

  create unique index index_name on emp(id)

添加主键索引:UID 是索引名,id 是列名

 alter table emp add constraint UID primary key(id);

添加组合索引:

   create index index_name on emp(col1,col2...)

注意: 只有用col1 查询才走索引查询, 用col2只会进行全表扫描;

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值