【问题标题】:Pointers in B TreeB 树中的指针
【发布时间】:2013-10-02 08:09:56
【问题描述】:

我阅读了 B 树并了解了它们的输入、删除方法。我读到这样的介绍:

当我们在磁盘上构建结构时,我们必须处理某些现实 访问和传输时间:

  1. 对磁盘的随机访问通常需要大约 10-20 毫秒 访问时间来定位磁头并等待数据上来 它。
  2. 一旦磁头位置正确,数据可以按以下速率传输 超过 100 万字节/秒。
  3. 然后观察不同大小的总传输时间如何表现 块(假设相当快的 10 毫秒访问时间和 1 兆字节/秒 传输率)

因此,B 树数据结构是为从磁盘提供服务而设计的(这使得它们非常适合数据库)。但是当我尝试实现它时,我遇到了这个问题。

普通 B 树图显示指向子节点的指针,然后下降到叶子。

但是我如何在磁盘上做指针?像文件名吗?

【问题讨论】:

  • 存储在磁盘上的每条记录都是逻辑等价物。的一个节点。许多节点存储在一个文件中。只需跟踪 head 记录的位置,每个记录都指向其子项的偏移量。正如内存是线性资源一样,您也可以将保存记录的文件视为线性资源。每条记录将包含一个有效负载和一对用于定位子级的偏移量。
  • 如果每条记录都是一个节点,那么偏移量是多少?什么是这样的记录,文件?和偏移量,file_names ??或者一切都在一个大文件中,偏移量是该文件中该节点位置的偏移量?
  • 只是提醒你——指针只不过是一个地址,一个内存块的位置。这也适用于文件,因为它们可以被视为一些持久内存的块......

标签: c++ database algorithm data-structures


【解决方案1】:

磁盘上的指针是文件开头的offsets

如果您的key 指向地址n,那么这意味着

  1. 打开数据文件
  2. 读取 n 个字节但丢弃它们(或直接跳过它们。这称为查找。请参阅下文了解如何)
  3. 开始阅读您感兴趣的数据。

现在,作为优化,

  1. 数据文件可能已经打开,比如你的程序启动时;当然可以部分缓存在内存中。
  2. 您可以专门指示框架转到文件中的特定位置,而不是读取和丢弃字节。大多数语言都有这个功能。所有操作系统都可以。这叫做寻求。你调用像file.seek(1024) 这样的方法。要执行跳转,操作系统必须知道您要查找的数据位于磁盘中的哪个点。这涉及更多的查找、一些磁盘移动,但这一切都由操作系统完成。
  3. 您可以开始读取数据,但要知道何时停止,要么拥有固定宽度的记录,要么可以将记录长度放在记录的前 4 个字节中。这使得headers 和元数据会随着复杂性而增长。

有趣的是,与每个key 关联的指针指向leftright nodes 没有数据的位置。所以,在像

这样的教科书例子中
struct node {
    int key;                      //this generally is the primary key of the table
    node left;
    node right;

    long offsetOfDataInDataFile;  // <----------- we need to add this line.
}

首先您在tree 中找到node。然后你找到key。在那里你得到了实际数据的offset。您转到数据文件中的位置并读取内容。

如果您的表有多个索引,那么或表中的每个索引,都需要维护一个这样的树。该树的key 将是被索引的列的内容。

【讨论】:

  • 真实数据库是不是太长文件了?
  • 是的。 大长文件在大多数数据库中很常见。索引(b 树)存储为单独的文件。不同的是文件格式、索引格式、打包、压缩、算法实现、额外功能等。一些数据库,如 ms-access 和 sqlite 将它们的整个世界打包在 一个 单个文件中。像 oracle 这样的大佬可能会使用未格式化的 (raw) 磁盘并在其上实现自己的高度专业化的文件系统。
  • 从头开始读取文件以跳到偏移量是一个荒谬的建议。 B树假定随机访问。你会寻求抵消。这不是“优化”,而是算法的重要组成部分。您的示例是关于二叉树,而不是 b 树。
  • @EJP,寻求不是优化,它是算法的重要组成部分。公认。在输入答案时,我想到对于 OP,读取和丢弃方法会更容易理解。使用seek 方法,涉及到操作系统和硬件,操作系统查询磁盘索引,然后指示硬件将磁头移动到该柱面。 OP 已经在数据库索引下挣扎,所以我想把磁盘索引放在一边。
【解决方案2】:

B 树中的“指针”只是文件中您可以查找的偏移量。或者,如果您要拥有固定的块大小,则它可能是一个块编号,,您在寻找之前乘以块大小。

【讨论】:

    猜你喜欢
    • 2015-06-21
    • 2018-06-01
    • 1970-01-01
    • 2017-05-16
    • 2010-11-30
    • 2015-07-18
    • 2014-09-20
    • 2012-03-06
    • 1970-01-01
    相关资源
    最近更新 更多