数据库索引详解

索引

当我们在设计数据库的时候,对表的一些属性有时会加上索引,但索引为什么能提高检索速率呢?是不是用了索引就一定可以提高效率呢?不同索引之间有什么区别呢?搞懂这些问题是灵活运用索引的必备条件。接下来,我们将一 一进行讨论。

一.索引的本质

索引也分为不同的种类,而且也有不同的分类方法,比较常用的是普通索引和聚集索引。

1.普通索引

其实对某字段建立了索引就相当于是对该字段新建立了一个表,这个表里的元素是安照这个字段有序排列。这样有什么好处呢?好处就在于如果我们select的时候要搜索该字段,那就会在这个索引表中先查找,因为索引表是有序的,所以在检索该字段的时候就是二分搜索,速度自然会比在原表上快,然后如果我只需要这一个字段的话,查询就可以结束了,但如果还需要除索引字段的其他字段的话,那么就会根据这个索引表的字段对应到主表中,然后再获取。
看了上面讲的,是不是感觉有点迷茫?下面看一下图就会清晰很多。

(图片来源于百度)
大家可以看到这里我们以Col2建立索引之后右边有一颗二叉树,可能大家会问不是说好了是一张表吗,怎么又是二叉树了,好吧表本身就是一种树形的数据结构存储,虽然实际上很少会选取二叉树,但此处方便讲解。可以看到Col2单独的一棵树,然后每一个节点对过来是一条记录,如果我们执行 select Col2 from tablename where Col2=34;那么直接在右边的树中二叉搜索,找到了就可以返回了。如果我们执行 select * from tablename where Col2=34;那么可以看到需要的不仅仅是Col2这一个字段,那么还是先在二叉树中查找,然后找到了之后对应到主表中,然后返回整条记录。

1.索引的数据结构

通过上面的图我们可以看到,索引的本质其实就是新建了一张表,而表本质上的数据结构就是树形结构,所以索引也是树形结构。但实际运用中并没有谁用红黑树,avl树这种数据结构,一般是b+树,接下来给大家大致介绍一下b+树的构成。

(图片来源于百度)
b+树在构建时和我们之前提到的二三树很像,只是有一些改进,b+树的非叶子节点不包含value的信息,也就是说非叶子结点只起到一个导航的作用,所有的value放在了叶子结点里,这样由于B+树在内部节点上不包含数据信息,因此在内存页中能够存放更多的key。 数据存放的更加紧密,具有更好的空间局部性。因此访问叶子节点上关联的数据也具有更好的缓存命中率。通常会将b+树进行优化,增加顺序访问指针。

(图片来源于百度0)
在B+Tree的每个叶子节点增加一个指向相邻叶子节点的指针,就形成了带有顺序访问指针的B+Tree。做这个优化的目的是为了提高区间访问的性能,例如图中如果要查询key为从18到49的所有数据记录,当找到18后,只需顺着节点和指针顺序遍历就可以一次性访问到所有数据节点,极大提到了区间查询效率。
可以看到b+树对于表的存储是一种很方便的数据结构。那么为什么不用红黑树呢,因为数据量大的时候,会导致这种二叉树深度太深,io次数会很多,层数很少的b+树可以有效降低io次数。

聚集索引

聚集索引和普通索引是不一样的,聚集索引是指数据库表行中数据的物理顺序与键值的逻辑(索引)顺序相同。一个表只能有一个聚集索引,因为一个表的物理顺序只有一种情况。意思就是说上面的普通索引我们可以看到是另建了一个表,然后当查询到了索引没有覆盖到的字段的时候是将这个字段映射到了主表中然后进行查询的。而聚集索引建立后主表本身就会按照这个索引的结构来存储,意思就是说主表直接就按这个来存了。这也是为什么聚集索引一定是唯一的原因,因为一张表中只能有一种存储方式。

聚集索引与普通索引

两种索引谁更快呢?这当然是没有悬念的,聚集索引更快咯,因为普通索引查到没有覆盖的字段的时候需要向主表中映射过去,然后再获取,而聚集索引因为其本身就包含了所有数据,所以一次就好~

主键与聚集索引

在我们新建一个表时,如果没有定义主键,那么表格的数据是顺序线性存储的,在定义的主键之后,因为主键默认有索引,并且在很多平台上默认是聚集索引,所以在主键定义的时候就会把整个表变为一个树形结构(如果主键是聚集索引),但要知道的是主键不一定是聚集索引,也可以是普通索引,只是很多平台默认为聚集,不要盲目划等号。

索引的利弊

那么索引既然这么快是不是越多越好呢?不存在的,因为索引本身是一个数据表,那么在插入或删除的时候就涉及到了索引表的改变,b+树的插入删除涉及到很多节点操作,或许会消耗很多时间。所以我们对于常改变的字段不宜建索引,而对于改动较少的字段就很合适,在设计表的时候我们要灵活选取,才能高效。

数据库索引与b+树的更多相关文章

  1. MySQL数据库索引之B+树

    一.B+树是什么 B+ 树是一种树型数据结构,通常用于数据库和操作系统的文件系统中.B+ 树的特点是能够保持数据稳定有序,其插入与修改操作拥有较稳定的对数时间复杂度.B+ 树元素自底向上插入,这与二叉 ...

  2. 数据库索引、B树、B+树

    数据库索引,是数据库管理系统中一个排序的数据结构,以协助快速查询.更新数据库表中数据.索引的实现通常使用B树及其变种B+树. 在数据之外,数据库系统还维护着满足特定查找算法的数据结构,这些数据结构以某 ...

  3. 数据库索引--------B/B+树、聚集、非聚集、符合索引

    摘录自博客:http://www.cnblogs.com/morvenhuang/archive/2009/03/30/1425534.html 一.引言 对数据库索引的关注从未淡出我的们的讨论,那么 ...

  4. 深入理解数据库索引采用B树和B+树的原因

    前面几篇关于数据库底层磁盘文件读取,数据库索引实现细节进行了深入的研究,但是没有串联起来的讲解为什么数据库索引会采用B树和B+树而不是其他的数据结构,例如平衡二叉树.链表等,因此,本文打算从数据库文件 ...

  5. 为什么说B+-tree比B 树更适合实际应用中操作系统的文件索引和数据库索引?

    B树: B+树 1) B+-tree的磁盘读写代价更低 B+-tree的内部结点并没有指向关键字具体信息的指针.因此其内部结点相对B 树更小.如果把所有同一内部结点的关键字存放在同一盘块中,那么盘块所 ...

  6. 为什么MySQL数据库索引选择使用B+树?

    在进一步分析为什么MySQL数据库索引选择使用B+树之前,我相信很多小伙伴对数据结构中的树还是有些许模糊的,因此我们由浅入深一步步探讨树的演进过程,在一步步引出B树以及为什么MySQL数据库索引选择使 ...

  7. B+树比B树更适合实际应用中操作系统的文件索引和数据库索引

    B+树比B树更适合实际应用中操作系统的文件索引和数据库索引 为什么选择B+树作为数据库索引结构?   背景 首先,来谈谈B树.为什么要使用B树?我们需要明白以下两个事实: [事实1]不同容量的存储器, ...

  8. 数据库索引 引用树形结构 B-数 B+数

    MySQL 为什么使用B+数 B-树和B+树最重要的一个区别就是B+树只有叶节点存放数据,其余节点用来索引,而B-树是每个索引节点都会有Data域. 这就决定了B+树更适合用来存储外部数据,也就是所谓 ...

  9. 面试经典---数据库索引B+、B-树

    大型数据库数据都是存在硬盘中的,为了操作的速度,需要设计针对外存的数据结构.而数据库索引技术就是在面试中反复被问到的一个问题:数据库索引是怎么实现的?数据库索引越大越好吗? 需要详细了解下这方面的知识 ...

随机推荐

  1. java代码----求最大值,平均值。。。

    总结:方法的返回值----返回的对象到底是什么? package com.a; import java.util.Scanner; //从键盘输入10个数,并输出最大值,最小值,平均值 public ...

  2. JAVA 1.7并发之LinkedTransferQueue原理理解

    昨天刚看完BlockingQueue觉得好高级啊,今天扫到1.7就发现了升级版.... 如果对内容觉得不够充分,可以去看http://www.cs.rochester.edu/u/scott/pape ...

  3. Kata 架构

    原文:https://github.com/kata-containers/documentation/blob/master/architecture.md (欢迎纠错) Kata-runtime ...

  4. PHP生成唯一固定长度邀请码

    function create_invite_code() { $code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; $rand = $code[rand(0,25)] .str ...

  5. 第一章 为什么使用NoSQL

    1.1 关系型数据库的价值 1.1.1 获取持久化数据 1.1.2 并发 通过”事务“ 来控制,出错有“回滚”机制. 1.1.3 集成                共享数据库集成,多个应用程序将数据 ...

  6. python学习(十三) 数据库支持

    13.1 Python数据库编程接口(API) 13.1.1 全局变量 13.1.2 异常 13.1.3 连接和游标 13.1.4 类型 13.2 SQLite和PySQlite 13.2.1 入门 ...

  7. .Net 框架实现AOP(动态代理实现AOP,本文为翻译)

    在上一节,我们将静态实现AOP,但是对于一个大型项目,要想为每个类,每个方法都去实现AOP ,进行日志记录和权限验证似乎是不可能的. 即使可能对于成百上千个类维护,也是很难维护.所以今天的主题就是如标 ...

  8. python's ninth day for me

    函数 函数的定义与调用: #def  关键字  定义一个函数. # my_len  函数名, 函数名的书写规则与变量的命名一致. # def  与函数名中间一个空格. # 函数名() :  加上冒号. ...

  9. BGP基本配置的方法

    边界网关协议(BGP)是运行于 TCP 上的一种自治系统的路由协议. BGP 是唯一一个用来处理像因特网大小的网络的协议,也是唯一能够妥善处理好不相关路由域间的多路连接的协议. as100 as200 ...

  10. openstack 租户ip 手动配置 openstack静态租户ip

    作者:[吴业亮]云计算开发工程师 博客:http://blog.csdn.net/wylfengyujiancheng 1.综述: 在日常开发和生产环境中经常需要将OpenStack虚拟机配置一个静态 ...