外部存储

引入:

      2-3-4树是多叉树的例子,多叉树是值节点的子节点多于两个并且数据项多于一个。另外一种多叉树,B-树,尚在外部存储器上的数据时,它起很大的作用。外部存储,通俗一点就是我们经常使用的电脑中的硬盘。

访问外部数据:

      之前学习的所有数据结都都是假设数据存储在主存中(RAM,随机访问存储器)。但是,在实际情况下有时要处理的数据量太大,不能存储在主存中。这时候我们就需要一种外部存储方式,外部存储的缺点时其比主存慢得多,但是,外部存储还有另外一个优点,那就是数据的持久化。
      举了栗子:假设现在有一个中等规模城市的电话簿的数据–可能有500000条数据。每条数据都包括:姓名、地址、电话号码以及公司内部使用的各种其它数据。每条数据存储为一条记录,长度为512子节。所以文件的大小为 500000*512,256000000子节,即256M.假设计算机的内存不足以存储该数据,我们只能通过外部存储器存储它。
      所以,在外部存储器上存储了大量的数据。怎样组织它们来实现一些有用的特点呢?比如:快速查找、插入和删除呢?
      在这个过程中我们需要遵守两条规则:
            1. 在磁盘驱动器中访问数据比在主存这种访问要慢得多
            2. 一次需要访问很多条数据

首先分析一下外部存储操作较慢的原因:

      计算机的内存按电子的方式工作。几微秒(一秒的百万分之一)就可以访问一个字节。
      而在外部存储中,要访问磁盘驱动器上的某段数据,读写头首先要移动到正确的磁道上。通过步进电机或类似的设备完成,这样的机械运动需要好几毫秒(一秒的几千分支几)。一旦找到正确的磁道,读写头必须要等待数据旋转到正确的位置上。平均来说,这一步要旋转半圈。即使磁盘每分钟转10000圈,那么在读到数据前还需要3毫秒。读写头就位后,就可以进行实际的读写操作了,这可能还需要几毫秒。
      通常磁盘存取的时间大约是10毫秒,大约比访问主存慢了10000倍。

外部存储读取数据的方式:

      当读写头到达正确的位置后开始读或者写的操作时,驱动器可以很快的把大量的数据转移到主存中。因此,为了简化驱动器的控制装置,在磁盘上的数据按块存储(根据不同的系统称为快、页、分配单元、或者其他的名字)。
      磁盘驱动器每次最少读或者写一个数据块的数据。块的大小根据操作系统。磁盘驱动器的容量,以及其他因素而不同,但它总是2的倍数。
      在读写操作时如果按块的容量的倍数来操作时效率最高的。如果读100字节,系统读取一块8192字节,只留下100字节,把其它的都扔了。如果要读8200,那么会读16284字节,把将近一半的数据都扔了。通过一些组织软件可以使他每次操作一块数据,可以优化性能。
       一旦读写头就位,读取一块时相当快的,只需要几毫秒。因此,磁盘存取时都读或者写一块的时间与块的容量关系不大。块越大,读或者写一条记录的效率就越高。

顺序有序排列:

      现在假设我们存储上述电话本数据的方式为数组,而且现在的数组已经按照数据中的相关的关键字进行了相关的排序,我们查找的时候可以直接使用二分法进行查找,这样的操作时很快的。但是,这是在外部存储中进行的数据读取。在读取的过程中肯定会消耗很大的一部分时间用来做外部数据的读操作,其实读进内存中的查找工作是很快的,所以我们必须把重点放在更加耗时的外部存储的数据读取上,我们很显然想用最少的读取次数来获取到我们想要的结果。
      现在我们要操作的是一个有序的数列,加入进行插入和删除操作的时候,我们肯定希望在插入或者删除过后,原来的数据加上新的数据还是有序的,但是这就给我们带了更加庞大的任务量,假设我们要在500000条数据中插入一条数据,而插入的数据刚好是最小的,那么我们就需要把之前的数据全部向后移动一个单位,这种规模的数据操作用脚趾头想都是很费时间的,所以我们和希望使用一种更加方便、快速、有效的方式来作为外部存储的存储方式。
      这时候我们引B-树


B-树:

      首先这是一种多叉树、有点像2-3-4树,但是它每个节点拥有更多的数据项:称它为B-树。

每节点一块:

      为什么要在每个节点有那么多的数据项呢?前面已经说过了,在对外部存储进行数据的读取时,读一块数据的效率是最高的。在树中,包含数据的实体是节点。把一整个数据块作为树的节点是比较有意义的。这样的话,读取一个节点可以在最短的时间里访问最大数据量的数据。
      但是在树中还需要保存节点间的链接,在内存中树里,这些链接是引用,指向内存中其他部分的节点。在外部存储的树中,链接是文件中块的编号。可以使用一个int类型的数据保存块的编号,int是4字节类型可以保存20亿以上的块号码。
      在每个节点中,数据是按照关键字顺序有序排列的,像2-3-4树一样。实际上,B-树的结构很像2-3-4树,只是每个节点有更多的数据项和更多的指向子节点的链接。B-树中的阶数是由节点拥有最多的子节点数决定的。

查找:

      在记录中按照关键字查找和在内存中的2-3-4树查找很类似。首先,含有根的块读入内存中,然后搜索算法开始在节点中查找,当记录的关键字比较大时,需要找这条记录和前一条记录之间的那个子节点。持续这个过程知道找到正确的节点。如果到达叶节点还是没有找到那条记录,则查找不成功。

插入:

      B-树的插入过程和2-3-4树有一定的区别,2-3-4树其实是由很多节点时不满的,实际上有的只有一个数据项。尤其是每次节分裂时总会产生两个每个有一个数据项的节点。在B-树中,这并不是很合适的。尽可能的让B-树节点满时非常重要的,这样每次读取磁盘时,读取整个节点,就可以获得最大数量的数据。为了达到这个目的,B-树的插入过程和2-3-4树的插入过程有下面三点的不同:
      1. 节点分裂时数据项平分:一半到新建的节点中去,一半保留在原来的节点中。
      2. 节点分裂从底向上,而不是自顶向下
      3. 同样,还是像2-3-4树一样,原节点内中间数据项不上移,而是加上数据项后所组成的节点数据项序列的中间数据项上移。

B-树的效率:

      因为每个节点都有很多的记录,每层都有很多的节点,所以在B-树上操作的效率时非常高的,这里假设数据都保存到磁盘上。在电话本的例子中有500000条记录。B-树中,所有的节点都至少半满的,所以每个节点至少有8条记录和9个子节点的链接,树的高度因此比logN小一点,N是500000.结果为5927,这样的树的高度大约是6层。
      所以,使用B-树只需要6次访问磁盘就可以在有500000条记录的文件中找到任何记录了,这比在顺序有序排列的文件中中二分查找要快得多。
      虽然,B-树中的查找比在顺序有序排列的磁盘文件查找快,不过插入和删除操作才显示出B-树最大的优越性。假设在插入的过程中不需要分裂节点,我们只需要6次访问就可以找到插入点秒之后还需要一次访问把保存了新插入记录的块写回到磁盘中,一共也就是7次访问。假设插入的过程中节点需要分裂,要读入分裂的节点,它的一半节点都需要移动,并且要写回磁盘。新创建的节点要写回磁盘,必须要读取父节点,然后插入上移记录,写回磁盘。这里就有5次访问,加上找到插入点需要的6次访问,一共是12次。相比在访问顺序文件中插入数据项所需要的500000次访问这是极大的改进。
      在其他的一些B-树中,只有叶子节点保存数据。非叶子节点只保存关键字和块的号码。这使得操作更快,因为每一块可以保存更多的号码。这使得操作更快,因为每一块可以保存更多块的号码。这样的高阶树层数更少,访问速度也提高了。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值