本篇文章来自Youtube上的一个视频,以为讲得相对不错。连接以下:www.youtube.com/watch?v=aZj…数据库
简单来讲:按照时钟方向分,disk由不少个sector组成,编号为0-N。按照从外到内分,disk又由多个track组成,编号为0-N。sector和track交叉的地方,叫作block,每一个block有本身的address,能够用(track_no,sector_no)表示。每一个block的大小是同样的,具体的大小要看实际状况,在这里,咱们假设一个block的大小是512bytes。数组
须要十分明确的一点是:不管是读操做,仍是写操做,都是以block为单位进行的。微信
在block内部,能够看做是一个数组结构,坐标从0到511。每一个byte都有一个address,这个称为offset。因此咱们能够把disk上的每个byte用(track_no,sector_no,offset)的形式表示。数据结构
在计算机中,disk的结构能够这么简要地表示。dom
其中有一个读写头,每一个时刻,读写头对准了disk上的其中一个block(track_no,sector_no)。经过旋转,能够改变sector_no,经过伸缩读写头,能够改变track_no。性能
还有一点,也是须要明确的:**只有disk上的数据被加载到RAM(random access memory),才能被程序使用。**或者说,才是真正对程序有用的。优化
如何优化RAM中数据的效率,这门学问叫作数据结构;如何优化disk中数据的效率,这门学问叫作DBMS,也就是大部分数据库所要研究的内容。3d
如今有一个employee table,其中有这些字段,每一个字段的大小如图所示,一个record的大小总计为128 bytes。指针
总共有100行数据:cdn
每一个block能够存4行数据。存这100条数据,须要25个block。若是如今咱们须要查询其中的一条数据,最多就须要查询25个block。
咱们建一个简单的索引,有两个字段,一个eid,表示employee的id,还有一个字段pointer,指向数据存储在disk上的位置。empolyee中的每一行,在index上都有一条记录。
那么咱们又是怎么存储这个索引的呢?这里咱们假设仍是所有存在disk上(固然你彻底能够选择直接存在内存里)。那么这个索引须要占据多少个block呢?eid大小为10bytes,pointer大小为6bytes,因此一行索引就有16个bytes大小。100条索引就须要占据100 * 16 / 512 -> 4个block。
那么如今要查询employee表中的某一条数据,最多须要查询多少个block呢?答案是4+1=5个。效率比以前要高了不少。
如今假设有1000条数据,这1000条数据将占据250个block,上一小节讲的索引将占据40个block。如今用索引查询一次,最多须要41次block access。如今这个索引已经不能知足咱们对性能的追求了,那么能不能对索引建一个索引呢?也就是二级索引?
对于二级索引,不须要记录每条employee在disk的位置,只须要记录一级索引全部block的位置就好了。 因此,二级索引须要40条记录,也就是须要占据2个block的空间。这种二级索引能够叫作稀疏索引,他不会包含全部数据行所在的位置。
如今借助二级索引,查询效率为:2 + 1 + 1 = 4次block access。
随着数据量不断增长,还能够对二级索引创建三级索引,对三级索引创建四级索引……
同时,咱们还但愿作到一点:多级索引能够随着数据量的大小变化而自动建立和删除。 这就引出了主角:B树和B+树。
二叉搜索树:每一个节点有一个值,有两个子节点。
由二叉搜索树扩展,让每一个节点最多能够存m-1个索引值,每一个节点能够有m个子节点,就是m-way搜索树。
上图所示的就是3-way搜索树。
下面的这个4-way搜索树,每一个节点最多存了3个索引值,有4个指向子节点的pointer,同时还有指向数据项所在的位置的指针Rp。
咱们能够用这个m-way搜索树做为数据库的索引,可是,m-way搜索树存在一些问题:
好比如今有三个数据:10,20,30,要用一个10-way搜索树来构建。颇有可能,最终会构建出一个这样的树:
这是最糟糕的一种状况,最终。咱们须要先把每一个节点填满,而后才能建立下一个子节点。而m-way搜索树自己,并无这种强制,你能够随意插入。
B树,实际上能够看做是m-way搜索树 + 规则(如何构建这棵树的规则)。
规则:
值:10,20,40,50。要构建一个4-way搜索树。4-way搜索树,意味着一个节点最多能够有3个值。
这实际上,也就构建了一个二级索引。上面的是第二层索引,下面的是第一层索引。每一层构成了一级索引。
继续插入60和70:
接着插入80,右下的那个节点已经没有空位置了,因此须要新建一个节点,而后把70那个值提高到上一层。
插入30:
插入35:
等等等等:
每一个值旁边,都有一个指向数据存储位置的指针。
在B+树中,不是每一个值旁边都有一个指向数据存储位置的指针,只有叶子节点才有。非叶子节点的值,在叶子节点上有他的副本。如图所示:
这就成为了一个密集索引。