【问题标题】:How Database stores data internally in B-Tree/B+Tree数据库如何在 B-Tree/B+Tree 内部存储数据
【发布时间】:2010-10-30 17:51:01
【问题描述】:

我的问题是数据库如何存储数据以及它如何在内部执行查询。

假设我们的表中有以下字段:

  1. 身份证
  2. 姓名
  3. 年龄
  4. 重量
  5. 经理

我们查询select * from Table1 where age>50 and weight<100

我只是好奇它如何在内部执行查询。

本例中B-Tre/B+Tree的节点包含什么?

【问题讨论】:

    标签: mysql sql sql-server database sql-server-2008-r2


    【解决方案1】:

    您选择的示例是单个 Tree 无法完成工作的少数情况之一(两个独立的范围)。

    然而,我正在开发的电子书的第一章解释了 B-Tree 索引的内部工作原理:http://use-the-index-luke.com/anatomy/

    编辑了解为什么两个索引可能对上述示例有用。

    上述查询可以通过三种可能的索引配置来支持:

    1. AGEWEIGHT 上的串联索引(按此顺序)。
      以防万一,查询将读取所有记录 WHERE AGE > 50,然后按 WEIGHT 过滤。

    2. WEIGHTAGE 上的串联索引(另一个顺序)。
      方法不同:读取所有记录 WHERE WEIGHT < 100,然后按 AGE 过滤。

    哪个更有效取决于您拥有的数据。如果AGE > 50 的记录比WEIGHT < 100 少,则第一个效率更高,否则第二个。但是,如果您使用不同的值进行查询,则图片可能会发生变化。

    级联索引不能很好地支持查询的原因是每个索引顺序只在一个轴上。每个索引条目都在另一个之前或之后,但从不在它旁边。所有索引条目构建一个链。

    具有两个独立范围查询的查询需要两个轴,不像链,但更像棋盘。 AGE 的一个轴,WEIGHT 的另一个轴。如果可以的话,您的查询将只需要扫描棋盘的一个角。

    但是,b 树只有一个轴,因此您必须先选择要使用的标准。如果选择AGE,则表示从AGE 50开始,会扫描整条链直到结束。只有部分存储在链侧的记录也符合WEIGHT < 100的条件,其他记录必须读取但将被丢弃。

    所以,长篇大论来解释为什么一棵树不能支持具有两个独立范围子句的查询。另一方面,一个连接索引可以很好地完成以下工作:

    WHERE age = 50 AND weight < 100
    WHERE weight = 100 AND age > 50
    WHERE age > 50 AND age < 70;
    

    但是,如果在两个不同的列上使用两个不等式运算符,就会出现问题。

    那么,该怎么办?

    第三种可能的方法是在两列上有两个独立的索引。这允许您拥有任意数量的轴(只需创建更多索引)。但是,这存在一些巨大问题。首先,并非所有数据库产品都支持这一点。只要支持它,它就是一个相当广泛的操作。它通常以扫描每个索引的方式工作,为每个结果构建一个位图索引。然后连接这些位图索引以应用 AND 运算符。这需要大量的数据处理——只有当每个条件对它自己的选择性不是很强时才值得付出努力,但两者加起来都非常有选择性。

    不想听我的建议吗?

    如果您的查询在 OLTP 环境中运行:使用一个连接索引。 两个独立的索引只是最后的选择。但是,如果您在 OLAP 环境中工作,您可能仍然需要位图索引。

    ps: 在我的书中索引AGE 是一个exercise(有解决方案)——特别是因为存储AGE 是一种不好的做法,你应该存储出生日期。

    【讨论】:

    • 嗨,Markus,我已经浏览了您正在进行的工作电子书的链接。你已经把事情解释得很清楚了,干得好。我知道索引是如何在内部存储的,但正如我最初的问题一样,我们需要两个索引来进行这种范围查询吗??
    • 嗨,我想这个框对于我的回答来说太小了,所以我已经编辑了上面的“一点点”。
    • 感谢 Markus 的简洁解释。我现在觉得很开明:)
    • 您忽略了空间索引,由 r-trees 或映射到常规树的空间填充曲线实现。这些类型的索引是多维的,并且支持尽可能多的范围搜索。
    猜你喜欢
    • 1970-01-01
    • 2021-10-25
    • 2017-03-02
    • 1970-01-01
    • 2011-05-17
    • 2017-04-06
    • 1970-01-01
    • 2011-04-24
    • 2011-11-29
    相关资源
    最近更新 更多