mysql是目前我们在工作 学习中都经常需要接触到的数据库 学校里开展数据库原理这门课 也着重介绍了mysql(没记错的话) 工作中也经常要打交道 比如有些公司会有记录慢速sql查询 然后找过来 说某某字段加个索引 或者这条sql看看怎么优化 但是什么是索引 索引怎么工作 可能很多人都不清楚
下面通过介绍几个索引相关的内容 希望对你有帮助
索引 可以理解为是图书馆中你查找书籍时 每一个书架上的标签 如果书架没有标明这个架子里存放了什么内容的书 这样你查找起来非常费劲 对吗 同样的 数据库中的索引就相当于书架上的标签 是为了让我们可以高效的查找到对应的数据
索引常见模型
哈希表
哈希表 用的是k-v存储的数据结构 输入待查找的key 就获得对应的value 把值放在数组里 通过hash function 把key算成一个确定的位置 然后value放在数组中算出来的位置 这种方法的弊端在于一定会有某个时候 多个key通过hash函数换算 得到一个相同的值 这时候的处理方式是拉出一个链表 还有个弊端就是 在做区间查询时 要全局扫一遍 效率较低
结论 只适合等值查询的场景 如memcached / nosql引擎
有序数组
顾名思义 就是将对应的信息一一排列好按照递增顺序排列成数组 在查询区间和等值这两种情况时性能都非常优秀 举一个例子 有这样一组数据 图书的类型名字name 科幻/神话/金融/悬疑 四种类型分别对应类型枚举 type 1/2/3/4 通过1/2/3/4就可以知道对应的类型名字 然后我们将其按升序排好 如果你要查type = 2 用二分法就可以查到 时间复杂度为O(log(N)) 如果你要查type在x,y范围内的数据 可以先用二分法找到 x(如果不存在x 就找到大于x的第一个类型)然后向右遍历 直到查到第一个大于 y 的类型 退出循环
弊端在于更新数据时麻烦 往中间插一条数据 需要挪动后面所有的数据 成本有点过于高了 所以有序数组通常只适用于静态存储引擎 如上述举的例子 定好之后不会修改的数据
搜索树
二叉搜索树是课本中的常客 也是leetcode题中常见的数据结构 他的特点是每个节点的左儿子小于父节点 而父节点又小于右儿子 如图所示 他的时间复杂度通常为O(log(N))
树可以有二叉 也可以有多叉 多叉树就是每个节点有多个儿子 儿子之间的大小保证从左到右递增 二叉树是搜索效率最高的 但是实际上大多数的数据库存储却并不使用二叉树 其原因是 索引不止存在内存中 还要写到磁盘上 正是因为要写到磁盘上 我们实际上不会用二叉树 而是用N叉树 目的是为了查询尽可能少的读磁盘(也可以理解为尽量少的访问数据块)
InnoDB索引模型
面试题常客 懂得都懂 InnoDB中 表是根据主键顺序以索引的形式存放的 也称为索引组织表 他的索引模型是b+树 每个索引在innodb里对应一颗b+树
根据其叶子结点的内容 又可以分为聚簇索引 二级索引 通常叫主键索引和非主键索引
两者的区别为主键索引的叶子结点存储的是一整行的数据 非主键索引的叶子结点存储的是主键的值 而导致主键索引和非主键索引在查询时出现性能差异的最核心点在于非主键索引查询时要先根据非主键索引查出主键的值 再根据主键的值去查主键索引对应的b+树